pbf
1.3.2
用于序列化和反序列化 PocketBase 过滤器语法的库。
您可以使用npm或yarn轻松安装PBF:
npm install pbf
或者
yarn add pbf
PBF 使得使用 PocketBase 过滤器语法变得简单。以下是如何开始的快速示例:
import * as pbf from "@nedpals/pbf" ;
import PocketBase from "pocketbase" ;
const pb = new PocketBase ( "<pocketbase url>" ) ;
const result = await pb . collection ( 'example' ) . getList ( 1 , 20 , {
filter : pbf . stringify ( pbf . and (
pbf . eq ( 'status' , true ) ,
pbf . gt ( 'created' , new Date ( "2022-08-01" ) )
) ) // status = true && created > "2022-08-01 10:00:00.000Z"
} ) ;
要否定过滤器(例如,等于、不等于、或),您可以使用not
函数。这不会否定该值,而只会否定所使用的运算符。
import * as pbf from "@nedpals/pbf" ;
pbf . stringify ( pbf . not ( pbf . eq ( "is_repost" , false ) ) ) // is_repost = false
在某些情况下,您希望创建一个搜索过滤器,其中一些过滤器通过短路有条件地启用。您可以通过在调用运算符之前添加.maybe
修饰符来实现此目的。这将过滤掉任何错误值并输出适当的过滤器。
import * as pbf from "@nedpals/pbf" ;
pbf . stringify ( pbf . and . maybe (
false && pbf . eq ( 'f' , 4 ) ,
null ,
pbf . eq ( 'd' , 1 ) ,
0 ,
pbf . not ( pbf . eq ( 'e' , 1 ) ) ,
) ) ; // d = 1 && e != 1
PBF 无需重复编写同一字段的多个比较过滤器,而是通过either
修饰符提供了一种简单的快捷方式。
import * as pbf from "@nedpals/pbf" ;
// shortcut for pbf.or(pbf.eq("size", "L"), pbf.eq("size", "XL"), pbf.eq("size", "XXL"))
pbf . stringify ( pbf . eq . either ( "size" , [ "L" , "XL" , "XXL" ] ) ) ; // (size = "L" || size = "XL") || size = "XXL"
PBF 还支持将原始过滤器字符串解析为正确的 PBF 格式。当您想要从 URL 搜索查询进行解析或者只是想要构建类似 PocketBase 的搜索体验时,这非常有用:
import * as pbf from "@nedpals/pbf" ;
const result = pbf . parse ( "title = 'example'" ) ; // equivalent to eq("title", "example");
// You can also inject/bind values to placeholders
const resultB = pbf . parse ( "title = {:title}" , { title : "Foo bar" } ) // equivalent of eq("title", "Foo bar")
为了使序列化/反序列化成为可能,PBF 将其存储为遵循语法树格式的对象,以区分逻辑、比较和容器化/括号过滤器。
// Taken and modified from the source code for brevity
type FilterValue = number | boolean | string | Date | null ;
type Filter = ComparisonFilter | LogicalFilter | ContainerFilter ;
type Metadata = Record < string , any >
// eg. a = 1
interface ComparisonFilter {
field : string
op : Operator
value : FilterValue
meta ?: Metadata
}
// eg. a > 1 && b = 2
interface LogicalFilter {
lhs : Filter
op : Operator
rhs : Filter
meta ?: Metadata
}
// eg. (c = 3)
interface ContainerFilter {
op : Operator
filter : Filter
meta ?: Metadata
}
这也使得手工制作过滤器变得更容易,特别是在构建动态的多面过滤器时:
const filter : Filter = {
op : "and" ,
lhs : {
op : "gte" ,
field : "shoe_size" ,
value : 20
} ,
rhs : {
op : "eq" ,
field : "color" ,
value : "burgundy"
}
}
pbf . stringify ( filter ) // shoe_size >= 20 && color = "burgundy"
从 PocketBase JS SDK 0.19.0 开始,添加了一项新功能,允许以类似于 PBF 的方式构建过滤器。然而,这两种方法之间存在一些关键差异。
PocketBase 仅确保值被正确转义并绑定到过滤器。用户仍然负责构造过滤器语法,这很容易出错。另一方面,PBF 提供了更全面的解决方案,还提供了一种简单而广泛的方法来创建复杂的搜索过滤器,而无需担心语法。
在将此功能添加到 PocketBase 之前,PBF 也是作为一次性实用功能创建的。
pbf 根据 MIT 许可证获得许可。
欢迎贡献!请随时提出问题或拉取请求。