We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
contains
startsWith
endsWith
1 parent 9df3716 commit 43822adCopy full SHA for 43822ad
5 files changed
README.md
@@ -167,6 +167,9 @@ Operators:
167
- `gt` greater than, `gte` greater than or equal
168
- `eq` equal, `ne` not equal
169
- `in` included in comma-separated list
170
+- `contains` string contains (case-insensitive)
171
+- `startsWith` string starts with (case-insensitive)
172
+- `endsWith` string ends with (case-insensitive)
173
174
Examples:
175
@@ -175,6 +178,9 @@ GET /posts?views:gt=100
178
GET /posts?title:eq=Hello
176
179
GET /posts?id:in=1,2,3
177
180
GET /posts?author.name:eq=typicode
181
+GET /posts?title:contains=hello
182
+GET /posts?title:startsWith=Hello
183
+GET /posts?title:endsWith=world
184
```
185
186
### Sort
src/matches-where.test.ts
@@ -35,6 +35,24 @@ await test('matchesWhere', async (t) => {
35
[{ a: { foo: 10 } }, true],
36
[{ a: { foo: 10, eq: 10 } }, true],
37
[{ missing: { foo: 1 } }, true],
38
+ // contains
39
+ [{ c: { contains: 'x' } }, true],
40
+ [{ c: { contains: 'X' } }, true],
41
+ [{ c: { contains: 'z' } }, false],
42
+ [{ a: { contains: '1' } }, false],
43
+ [{ c: { contains: 1 } }, false],
44
+ // startsWith
45
+ [{ c: { startsWith: 'x' } }, true],
46
+ [{ c: { startsWith: 'X' } }, true],
47
+ [{ c: { startsWith: 'z' } }, false],
48
+ [{ a: { startsWith: '1' } }, false],
49
+ [{ c: { startsWith: 1 } }, false],
50
+ // endsWith
51
+ [{ c: { endsWith: 'x' } }, true],
52
+ [{ c: { endsWith: 'X' } }, true],
53
+ [{ c: { endsWith: 'z' } }, false],
54
+ [{ a: { endsWith: '1' } }, false],
55
+ [{ c: { endsWith: 1 } }, false],
56
]
57
58
for (const [query, expected] of cases) {
src/matches-where.ts
@@ -57,6 +57,18 @@ export function matchesWhere(obj: JsonObject, where: JsonObject): boolean {
const inValues = Array.isArray(op.in) ? op.in : [op.in]
if (!inValues.some((v) => (field as any) === (v as any))) return false
59
}
60
+ if (knownOps.includes('contains')) {
61
+ if (typeof field !== 'string') return false
62
+ if (!field.toLowerCase().includes(String(op.contains).toLowerCase())) return false
63
+ }
64
+ if (knownOps.includes('startsWith')) {
65
66
+ if (!field.toLowerCase().startsWith(String(op.startsWith).toLowerCase())) return false
67
68
+ if (knownOps.includes('endsWith')) {
69
70
+ if (!field.toLowerCase().endsWith(String(op.endsWith).toLowerCase())) return false
71
72
continue
73
74
src/parse-where.test.ts
@@ -95,6 +95,24 @@ await test('parseWhere', async (t) => {
95
title: { in: ['hello', 'world'] },
96
},
97
],
98
+ [
99
+ 'title:contains=ello',
100
+ {
101
+ title: { contains: 'ello' },
102
+ },
103
+ ],
104
105
+ 'title:startsWith=hel',
106
107
+ title: { startsWith: 'hel' },
108
109
110
111
+ 'title:endsWith=rld',
112
113
+ title: { endsWith: 'rld' },
114
115
116
117
118
src/where-operators.ts
@@ -1,4 +1,15 @@
1
-export const WHERE_OPERATORS = ['lt', 'lte', 'gt', 'gte', 'eq', 'ne', 'in'] as const
+export const WHERE_OPERATORS = [
2
+ 'lt',
3
+ 'lte',
4
+ 'gt',
5
+ 'gte',
6
+ 'eq',
7
+ 'ne',
8
+ 'in',
9
+ 'contains',
10
+ 'startsWith',
11
+ 'endsWith',
12
+] as const
13
14
export type WhereOperator = (typeof WHERE_OPERATORS)[number]
15
0 commit comments