@malloydata/malloy-filter 0.0.237-dev250222034547 → 0.0.237-dev250223010918
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -22
- package/SAMPLES.md +154 -75
- package/SERIALIZE_SAMPLES.md +37 -24
- package/dist/boolean_parser.js +3 -1
- package/dist/boolean_parser.js.map +1 -1
- package/dist/boolean_serializer.js +9 -1
- package/dist/boolean_serializer.js.map +1 -1
- package/dist/clause_types.d.ts +28 -9
- package/dist/date_parser.js +5 -1
- package/dist/date_parser.js.map +1 -1
- package/dist/date_serializer.js +6 -0
- package/dist/date_serializer.js.map +1 -1
- package/dist/date_types.d.ts +7 -1
- package/dist/generate_samples.js +177 -271
- package/dist/generate_samples.js.map +1 -1
- package/dist/number_parser.d.ts +0 -3
- package/dist/number_parser.js +10 -51
- package/dist/number_parser.js.map +1 -1
- package/dist/number_serializer.js +14 -11
- package/dist/number_serializer.js.map +1 -1
- package/dist/string_parser.js +21 -21
- package/dist/string_parser.js.map +1 -1
- package/dist/string_serializer.d.ts +1 -0
- package/dist/string_serializer.js +35 -21
- package/dist/string_serializer.js.map +1 -1
- package/package.json +1 -1
- package/src/DEVELOPING.md +3 -10
- package/src/boolean_parser.ts +4 -3
- package/src/boolean_serializer.ts +9 -1
- package/src/clause_types.ts +59 -20
- package/src/date_parser.ts +5 -1
- package/src/date_serializer.ts +4 -0
- package/src/date_types.ts +10 -0
- package/src/generate_samples.ts +201 -298
- package/src/number_parser.ts +9 -58
- package/src/number_serializer.ts +14 -14
- package/src/string_parser.ts +29 -21
- package/src/string_serializer.ts +54 -27
package/README.md
CHANGED
|
@@ -19,42 +19,52 @@ To use the parser, simply import `FilterParser` and go.
|
|
|
19
19
|
Example:
|
|
20
20
|
|
|
21
21
|
```code
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
22
|
+
import {BooleanParser} from './boolean_parser';
|
|
23
|
+
import {StringParser} from './string_parser';
|
|
24
|
+
import {NumberParser} from './number_parser';
|
|
25
|
+
import {DateParser} from './date_parser';
|
|
26
|
+
|
|
27
|
+
function aSimpleParser() {
|
|
28
|
+
let str = 'CAT,DOG';
|
|
29
|
+
const stringResponse = new StringParser(str).parse();
|
|
30
|
+
console.log(str, '\n', ...stringResponse.clauses, '\n');
|
|
31
|
+
|
|
32
|
+
str = '-5.5, 10, 2.3e7';
|
|
33
|
+
const numberResponse = new NumberParser(str).parse();
|
|
34
|
+
console.log(str, '\n', ...numberResponse.clauses, '\n');
|
|
35
|
+
|
|
36
|
+
str = 'null, false';
|
|
37
|
+
const booleanResponse = new BooleanParser(str).parse();
|
|
38
|
+
console.log(str, '\n', ...booleanResponse.clauses, '\n');
|
|
39
|
+
|
|
40
|
+
str = 'after 2025-10-05';
|
|
41
|
+
const dateResponse = new DateParser(str).parse();
|
|
42
|
+
console.log(str, '\n', ...dateResponse.clauses, '\n');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
aSimpleParser();
|
|
39
46
|
```
|
|
40
47
|
|
|
41
48
|
Output:
|
|
42
49
|
|
|
43
50
|
```code
|
|
44
|
-
CAT,DOG
|
|
51
|
+
CAT,DOG
|
|
45
52
|
{ operator: '=', values: [ 'CAT', 'DOG' ] }
|
|
46
53
|
|
|
47
54
|
-5.5, 10, 2.3e7
|
|
48
55
|
{ operator: '=', values: [ -5.5, 10, 23000000 ] }
|
|
49
56
|
|
|
50
57
|
null, false
|
|
51
|
-
{ operator: 'NULL' } { operator: '
|
|
58
|
+
{ operator: 'NULL' } { operator: 'FALSEORNULL' }
|
|
52
59
|
|
|
53
60
|
after 2025-10-05
|
|
54
|
-
{
|
|
61
|
+
{
|
|
62
|
+
operator: 'AFTER',
|
|
63
|
+
moment: { type: 'ABSOLUTE', date: '2025-10-05', unit: 'DAY' }
|
|
64
|
+
}
|
|
55
65
|
```
|
|
56
66
|
|
|
57
|
-
Likewise, to use the
|
|
67
|
+
Likewise, to use the serializers, simply import the `*Serializer` classes.
|
|
58
68
|
|
|
59
69
|
## Parsers
|
|
60
70
|
|
|
@@ -78,4 +88,4 @@ The date and time parser `date_parser.ts` supports the operations highlighted on
|
|
|
78
88
|
|
|
79
89
|
## Serializers
|
|
80
90
|
|
|
81
|
-
Each parser has a complementary serializer that converts the parser output (`
|
|
91
|
+
Each parser has a complementary serializer that converts the parser output (`xxxClause[]`) back to a string. See examples of the round trip from string to Clause to string on the [Serialization Samples](SERIALIZE_SAMPLES.md) page.
|
package/SAMPLES.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Parsers
|
|
2
2
|
|
|
3
|
-
Each filter type is handled by a different parser (strings, numbers, dates and times, etc).
|
|
3
|
+
Each filter type is handled by a different parser (strings, numbers, dates and times, etc).
|
|
4
|
+
Sample outputs from each parser follow...
|
|
4
5
|
|
|
6
|
+
-------------------------------------------------------------------------
|
|
5
7
|
## Numbers
|
|
6
8
|
|
|
7
|
-
The number parser `number_parser.ts` supports the "numeric" expressions shown below. `Input` is the input string and `Output` shows the output of `number_parser`:
|
|
8
|
-
|
|
9
9
|
```code
|
|
10
10
|
Input: 5
|
|
11
11
|
Output: { operator: '=', values: [ 5 ] }
|
|
@@ -13,8 +13,8 @@ Output: { operator: '=', values: [ 5 ] }
|
|
|
13
13
|
Input: !=5
|
|
14
14
|
Output: { operator: '!=', values: [ 5 ] }
|
|
15
15
|
|
|
16
|
-
Input: 1, 3,
|
|
17
|
-
Output: { operator: '=', values: [ 1, 3,
|
|
16
|
+
Input: 1, 3, 5, null
|
|
17
|
+
Output: { operator: '=', values: [ 1, 3, 5 ] } { operator: 'NULL' }
|
|
18
18
|
|
|
19
19
|
Input: <1, >=100
|
|
20
20
|
Output: { operator: '<', values: [ 1 ] } { operator: '>=', values: [ 100 ] }
|
|
@@ -26,10 +26,10 @@ Input: <= 10
|
|
|
26
26
|
Output: { operator: '<=', values: [ 10 ] }
|
|
27
27
|
|
|
28
28
|
Input: NULL
|
|
29
|
-
Output: { operator: '
|
|
29
|
+
Output: { operator: 'NULL' }
|
|
30
30
|
|
|
31
31
|
Input: -NULL
|
|
32
|
-
Output: { operator: '
|
|
32
|
+
Output: { operator: 'NOTNULL' }
|
|
33
33
|
|
|
34
34
|
Input: (1, 7)
|
|
35
35
|
Output: {
|
|
@@ -89,7 +89,7 @@ Output: {
|
|
|
89
89
|
startValue: 0,
|
|
90
90
|
endOperator: '<=',
|
|
91
91
|
endValue: 10
|
|
92
|
-
} { operator: '=', values: [ 20
|
|
92
|
+
} { operator: '=', values: [ 20 ] } { operator: 'NULL' } {
|
|
93
93
|
operator: 'range',
|
|
94
94
|
startOperator: '>',
|
|
95
95
|
startValue: 72,
|
|
@@ -98,8 +98,7 @@ Output: {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
Input: , notanumber,, "null", apple pear orange, nulle, nnull, >=,
|
|
101
|
-
Errors: { message: 'Invalid expression', startIndex: 2, endIndex: 12 } { message: 'Invalid expression', startIndex: 15, endIndex: 21 } { message: 'Invalid expression', startIndex: 23, endIndex: 28 } { message: 'Invalid expression', startIndex: 29, endIndex: 33 } { message: 'Invalid expression', startIndex: 34, endIndex: 40 } { message: 'Invalid expression', startIndex: 42, endIndex: 47 } { message:
|
|
102
|
-
'Invalid expression', startIndex: 49, endIndex: 54 } { message: 'Invalid expression', startIndex: 56, endIndex: 58 }
|
|
101
|
+
Errors: { message: 'Invalid expression', startIndex: 2, endIndex: 12 } { message: 'Invalid expression', startIndex: 15, endIndex: 21 } { message: 'Invalid expression', startIndex: 23, endIndex: 28 } { message: 'Invalid expression', startIndex: 29, endIndex: 33 } { message: 'Invalid expression', startIndex: 34, endIndex: 40 } { message: 'Invalid expression', startIndex: 42, endIndex: 47 } { message: 'Invalid expression', startIndex: 49, endIndex: 54 } { message: 'Invalid expression', startIndex: 56, endIndex: 58 }
|
|
103
102
|
|
|
104
103
|
Input: [cat, 100], <cat
|
|
105
104
|
Errors: { message: 'Invalid number', startIndex: 1, endIndex: 4 } { message: 'Invalid expression', startIndex: 12, endIndex: 13 } { message: 'Invalid expression', startIndex: 13, endIndex: 16 }
|
|
@@ -107,12 +106,12 @@ Errors: { message: 'Invalid number', startIndex: 1, endIndex: 4 } { message: 'I
|
|
|
107
106
|
Input: -5.5 to 10
|
|
108
107
|
Output: { operator: '=', values: [ -5.5, 10 ] }
|
|
109
108
|
Errors: { message: 'Invalid expression', startIndex: 5, endIndex: 7 }
|
|
109
|
+
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
+
-------------------------------------------------------------------------
|
|
112
113
|
## Strings
|
|
113
114
|
|
|
114
|
-
The string parser `string_parser.ts` supports the "string expressions" shown below. `Input` is the input string and `Output` shows the output of `string_parser`. Note that **several examples below are illogical**, and are intended to stress-test the parser.
|
|
115
|
-
|
|
116
115
|
```code
|
|
117
116
|
Input: CAT, DOG,mouse
|
|
118
117
|
Output: { operator: '=', values: [ 'CAT', 'DOG', 'mouse' ] }
|
|
@@ -121,13 +120,14 @@ Input: -CAT,-DOG , -mouse
|
|
|
121
120
|
Output: { operator: '!=', values: [ 'CAT', 'DOG', 'mouse' ] }
|
|
122
121
|
|
|
123
122
|
Input: CAT,-"DOG",m o u s e
|
|
124
|
-
Output: { operator: '=', values: [ 'CAT' ] } { operator: '!=', values: [ '"DOG"' ] } { operator: '=', values: [ 'm o u s e' ] }
|
|
123
|
+
Output: { operator: '=', values: [ 'CAT' ] } { operator: '!=', values: [ '"DOG"' ] } { operator: '=', values: [ 'm o u s e' ] }
|
|
124
|
+
Quotes: DOUBLE
|
|
125
125
|
|
|
126
126
|
Input: -CAT,-DOG,mouse, bird, zebra, -horse, -goat
|
|
127
127
|
Output: { operator: '!=', values: [ 'CAT', 'DOG' ] } { operator: '=', values: [ 'mouse', 'bird', 'zebra' ] } { operator: '!=', values: [ 'horse', 'goat' ] }
|
|
128
128
|
|
|
129
129
|
Input: Missing ,NULL
|
|
130
|
-
Output: { operator: '=', values: [ 'Missing'
|
|
130
|
+
Output: { operator: '=', values: [ 'Missing' ] } { operator: 'NULL' }
|
|
131
131
|
|
|
132
132
|
Input: CAT%, D%OG, %ous%, %ira_f%, %_oat,
|
|
133
133
|
Output: { operator: 'starts', values: [ 'CAT' ] } { operator: '~', values: [ 'D%OG' ] } { operator: 'contains', values: [ 'ous' ] } { operator: '~', values: [ '%ira_f%', '%_oat' ] }
|
|
@@ -155,28 +155,30 @@ Input: \_CAT,D\%G,\mouse
|
|
|
155
155
|
Output: { operator: '=', values: [ '_CAT', 'D%G', 'mouse' ] }
|
|
156
156
|
|
|
157
157
|
Input: CAT,-NULL
|
|
158
|
-
Output: { operator: '=', values: [ 'CAT' ] } { operator: '
|
|
158
|
+
Output: { operator: '=', values: [ 'CAT' ] } { operator: 'NOTNULL' }
|
|
159
159
|
|
|
160
160
|
Input: CAT,-"NULL"
|
|
161
161
|
Output: { operator: '=', values: [ 'CAT' ] } { operator: '!=', values: [ '"NULL"' ] }
|
|
162
|
+
Quotes: DOUBLE
|
|
162
163
|
|
|
163
164
|
Input: CAT,NULL
|
|
164
|
-
Output: { operator: '=', values: [ 'CAT'
|
|
165
|
+
Output: { operator: '=', values: [ 'CAT' ] } { operator: 'NULL' }
|
|
165
166
|
|
|
166
167
|
Input: EMPTY
|
|
167
|
-
Output: { operator: 'EMPTY'
|
|
168
|
+
Output: { operator: 'EMPTY' }
|
|
168
169
|
|
|
169
170
|
Input: -EMPTY
|
|
170
|
-
Output: { operator: 'NOTEMPTY'
|
|
171
|
+
Output: { operator: 'NOTEMPTY' }
|
|
171
172
|
|
|
172
173
|
Input: CAT,-EMPTY
|
|
173
|
-
Output: { operator: '=', values: [ 'CAT' ] } { operator: 'NOTEMPTY'
|
|
174
|
+
Output: { operator: '=', values: [ 'CAT' ] } { operator: 'NOTEMPTY' }
|
|
174
175
|
|
|
175
176
|
Input: "CAT,DOG',mo`use,zeb'''ra,g"""t,g\"ir\`af\'e
|
|
176
177
|
Output: {
|
|
177
178
|
operator: '=',
|
|
178
179
|
values: [ '"CAT', "DOG'", 'mo`use', "zeb'''ra", 'g"""t', 'g"ir`af\'e' ]
|
|
179
180
|
}
|
|
181
|
+
Quotes: DOUBLE SINGLE BACKTICK TRIPLESINGLE TRIPLEDOUBLE ESCAPEDDOUBLE ESCAPEDBACKTICK ESCAPEDSINGLE
|
|
180
182
|
|
|
181
183
|
Input: CAT\,DOG
|
|
182
184
|
Output: { operator: '=', values: [ 'CAT,DOG' ] }
|
|
@@ -211,22 +213,26 @@ Output: {
|
|
|
211
213
|
operator: '=',
|
|
212
214
|
values: [ 'hello world', 'foo="bar baz"', 'qux=quux' ]
|
|
213
215
|
}
|
|
216
|
+
Quotes: DOUBLE
|
|
214
217
|
|
|
215
218
|
Input: one ,Null , Empty,E M P T Y Y,EEmpty, emptIEs
|
|
216
|
-
Output: { operator: '=', values: [ 'one'
|
|
219
|
+
Output: { operator: '=', values: [ 'one' ] } { operator: 'NULL' } { operator: 'EMPTY' } { operator: '=', values: [ 'E M P T Y Y', 'EEmpty', 'emptIEs' ] }
|
|
217
220
|
|
|
218
221
|
Input:
|
|
222
|
+
|
|
219
223
|
```
|
|
220
224
|
|
|
225
|
+
-------------------------------------------------------------------------
|
|
221
226
|
## Booleans
|
|
222
227
|
|
|
223
|
-
The boolean parser `boolean_parser.ts` supports the "truthy" expressions shown below. `Input` is the input string and `Output` shows the output of `boolean_parser`:
|
|
224
|
-
|
|
225
228
|
```code
|
|
226
229
|
Input: true
|
|
227
230
|
Output: { operator: 'TRUE' }
|
|
228
231
|
|
|
229
232
|
Input: FALSE
|
|
233
|
+
Output: { operator: 'FALSEORNULL' }
|
|
234
|
+
|
|
235
|
+
Input: =false
|
|
230
236
|
Output: { operator: 'FALSE' }
|
|
231
237
|
|
|
232
238
|
Input: null
|
|
@@ -235,8 +241,8 @@ Output: { operator: 'NULL' }
|
|
|
235
241
|
Input: -NULL
|
|
236
242
|
Output: { operator: 'NOTNULL' }
|
|
237
243
|
|
|
238
|
-
Input: True , faLSE,NULl,-null
|
|
239
|
-
Output: { operator: 'TRUE' } { operator: 'FALSE' } { operator: 'NULL' } { operator: 'NOTNULL' }
|
|
244
|
+
Input: True , faLSE,=false,NULl,-null
|
|
245
|
+
Output: { operator: 'TRUE' } { operator: 'FALSEORNULL' } { operator: 'FALSE' } { operator: 'NULL' } { operator: 'NOTNULL' }
|
|
240
246
|
|
|
241
247
|
Input: -'null'
|
|
242
248
|
Errors: { message: "Invalid token -'null'", startIndex: 0, endIndex: 7 }
|
|
@@ -249,119 +255,181 @@ Errors: { message: 'Invalid token nnull', startIndex: 0, endIndex: 5 }
|
|
|
249
255
|
|
|
250
256
|
Input: truee
|
|
251
257
|
Errors: { message: 'Invalid token truee', startIndex: 1, endIndex: 6 }
|
|
258
|
+
|
|
252
259
|
```
|
|
253
260
|
|
|
261
|
+
-------------------------------------------------------------------------
|
|
254
262
|
## Dates and Times
|
|
255
263
|
|
|
256
|
-
The date and time parser `date_parser.ts` supports the date and time expressions shown below. `Input` is the input string and `Output` shows the output of `date_parser`. Note that, like with strings above, we include several invalid examples to highlight error responses:
|
|
257
|
-
|
|
258
264
|
```code
|
|
259
265
|
Input: this month
|
|
260
|
-
Output: {
|
|
266
|
+
Output: {
|
|
267
|
+
operator: 'ON',
|
|
268
|
+
moment: { type: 'INTERVAL', kind: 'THIS', unit: 'MONTH' }
|
|
269
|
+
}
|
|
261
270
|
|
|
262
271
|
Input: 3 days
|
|
263
|
-
Output: { operator: '
|
|
272
|
+
Output: { operator: 'DURATION', duration: { amount: 3, unit: 'DAYS' } }
|
|
264
273
|
|
|
265
274
|
Input: 3 days ago
|
|
266
|
-
Output: { operator: 'AGO', value: '3', unit: 'DAYS' }
|
|
267
|
-
|
|
268
|
-
Input: 3 months ago for 2 days
|
|
269
275
|
Output: {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
276
|
+
operator: 'ON',
|
|
277
|
+
moment: {
|
|
278
|
+
type: 'OFFSET_FROM_NOW',
|
|
279
|
+
direction: 'AGO',
|
|
280
|
+
amount: 3,
|
|
281
|
+
unit: 'DAYS'
|
|
282
|
+
}
|
|
273
283
|
}
|
|
274
284
|
|
|
275
|
-
Input:
|
|
285
|
+
Input: 3 months ago for 2 days
|
|
276
286
|
Output: {
|
|
277
|
-
operator: '
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
287
|
+
operator: 'FOR_RANGE',
|
|
288
|
+
from: {
|
|
289
|
+
type: 'OFFSET_FROM_NOW',
|
|
290
|
+
direction: 'AGO',
|
|
291
|
+
amount: 3,
|
|
292
|
+
unit: 'MONTHS'
|
|
293
|
+
},
|
|
294
|
+
duration: { amount: 2, unit: 'DAYS' }
|
|
281
295
|
}
|
|
282
296
|
|
|
283
297
|
Input: 2025 weeks ago
|
|
284
|
-
Output: {
|
|
298
|
+
Output: {
|
|
299
|
+
operator: 'ON',
|
|
300
|
+
moment: {
|
|
301
|
+
type: 'OFFSET_FROM_NOW',
|
|
302
|
+
direction: 'AGO',
|
|
303
|
+
amount: 2025,
|
|
304
|
+
unit: 'WEEKS'
|
|
305
|
+
}
|
|
306
|
+
}
|
|
285
307
|
|
|
286
308
|
Input: before 3 days ago
|
|
287
|
-
Output: {
|
|
309
|
+
Output: {
|
|
310
|
+
operator: 'BEFORE',
|
|
311
|
+
moment: {
|
|
312
|
+
type: 'OFFSET_FROM_NOW',
|
|
313
|
+
direction: 'AGO',
|
|
314
|
+
amount: 3,
|
|
315
|
+
unit: 'DAYS'
|
|
316
|
+
}
|
|
317
|
+
}
|
|
288
318
|
|
|
289
319
|
Input: before 2025-08-30 08:30:20
|
|
290
320
|
Output: {
|
|
291
|
-
operator: '
|
|
292
|
-
date: '2025-08-30',
|
|
293
|
-
time: '08:30:20',
|
|
294
|
-
prefix: 'BEFORE'
|
|
321
|
+
operator: 'BEFORE',
|
|
322
|
+
moment: { type: 'ABSOLUTE', date: '2025-08-30 08:30:20', unit: 'SECOND' }
|
|
295
323
|
}
|
|
296
324
|
|
|
297
325
|
Input: after 2025-10-05
|
|
298
|
-
Output: {
|
|
326
|
+
Output: {
|
|
327
|
+
operator: 'AFTER',
|
|
328
|
+
moment: { type: 'ABSOLUTE', date: '2025-10-05', unit: 'DAY' }
|
|
329
|
+
}
|
|
299
330
|
|
|
300
|
-
Input: 2025-08-30 12:00
|
|
331
|
+
Input: 2025-08-30 12:00 to 2025-09-18 14:30
|
|
301
332
|
Output: {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
333
|
+
operator: 'TO_RANGE',
|
|
334
|
+
from: { type: 'ABSOLUTE', date: '2025-08-30 12:00', unit: 'MINUTE' },
|
|
335
|
+
to: { type: 'ABSOLUTE', date: '2025-09-18 14:30', unit: 'MINUTE' }
|
|
305
336
|
}
|
|
306
337
|
|
|
307
338
|
Input: this year
|
|
308
|
-
Output: {
|
|
339
|
+
Output: {
|
|
340
|
+
operator: 'ON',
|
|
341
|
+
moment: { type: 'INTERVAL', kind: 'THIS', unit: 'YEAR' }
|
|
342
|
+
}
|
|
309
343
|
|
|
310
344
|
Input: next tuesday
|
|
311
|
-
Output: {
|
|
345
|
+
Output: {
|
|
346
|
+
operator: 'ON',
|
|
347
|
+
moment: { type: 'INTERVAL', kind: 'NEXT', unit: 'TUESDAY' }
|
|
348
|
+
}
|
|
312
349
|
|
|
313
350
|
Input: 7 years from now
|
|
314
|
-
Output: {
|
|
351
|
+
Output: {
|
|
352
|
+
operator: 'ON',
|
|
353
|
+
moment: {
|
|
354
|
+
type: 'OFFSET_FROM_NOW',
|
|
355
|
+
direction: 'FROMNOW',
|
|
356
|
+
amount: 7,
|
|
357
|
+
unit: 'YEARS'
|
|
358
|
+
}
|
|
359
|
+
}
|
|
315
360
|
|
|
316
361
|
Input: 2025-01-01 12:00:00 for 3 days
|
|
317
362
|
Output: {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
363
|
+
operator: 'FOR_RANGE',
|
|
364
|
+
from: { type: 'ABSOLUTE', date: '2025-01-01 12:00:00', unit: 'SECOND' },
|
|
365
|
+
duration: { amount: 3, unit: 'DAYS' }
|
|
321
366
|
}
|
|
322
367
|
|
|
323
368
|
Input: 2020-08-12
|
|
324
|
-
Output: {
|
|
369
|
+
Output: {
|
|
370
|
+
operator: 'ON',
|
|
371
|
+
moment: { type: 'ABSOLUTE', date: '2020-08-12', unit: 'DAY' }
|
|
372
|
+
}
|
|
325
373
|
|
|
326
374
|
Input: 2020-08
|
|
327
|
-
Output: {
|
|
375
|
+
Output: {
|
|
376
|
+
operator: 'ON',
|
|
377
|
+
moment: { type: 'ABSOLUTE', date: '2020-08', unit: 'MONTH' }
|
|
378
|
+
}
|
|
328
379
|
|
|
329
380
|
Input: today
|
|
330
|
-
Output: { operator: 'TODAY' }
|
|
381
|
+
Output: { operator: 'ON', moment: { type: 'NAMED', name: 'TODAY' } }
|
|
331
382
|
|
|
332
383
|
Input: yesterday
|
|
333
|
-
Output: { operator: 'YESTERDAY' }
|
|
384
|
+
Output: { operator: 'ON', moment: { type: 'NAMED', name: 'YESTERDAY' } }
|
|
334
385
|
|
|
335
386
|
Input: tomorrow
|
|
336
|
-
Output: { operator: 'TOMORROW' }
|
|
387
|
+
Output: { operator: 'ON', moment: { type: 'NAMED', name: 'TOMORROW' } }
|
|
337
388
|
|
|
338
389
|
Input: TODay,Yesterday, TOMORROW , ,TODay ,,
|
|
339
|
-
Output: { operator: 'TODAY' } { operator: 'YESTERDAY' } { operator: 'TOMORROW' } { operator: 'TODAY' }
|
|
390
|
+
Output: { operator: 'ON', moment: { type: 'NAMED', name: 'TODAY' } } { operator: 'ON', moment: { type: 'NAMED', name: 'YESTERDAY' } } { operator: 'ON', moment: { type: 'NAMED', name: 'TOMORROW' } } { operator: 'ON', moment: { type: 'NAMED', name: 'TODAY' } }
|
|
340
391
|
|
|
341
392
|
Input: 2010 to 2011, 2015 to 2016 , 2018, 2020
|
|
342
393
|
Output: {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
394
|
+
operator: 'TO_RANGE',
|
|
395
|
+
from: { type: 'ABSOLUTE', date: '2010', unit: 'YEAR' },
|
|
396
|
+
to: { type: 'ABSOLUTE', date: '2011', unit: 'YEAR' }
|
|
397
|
+
} {
|
|
398
|
+
operator: 'TO_RANGE',
|
|
399
|
+
from: { type: 'ABSOLUTE', date: '2015', unit: 'YEAR' },
|
|
400
|
+
to: { type: 'ABSOLUTE', date: '2016', unit: 'YEAR' }
|
|
346
401
|
} {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
402
|
+
operator: 'ON',
|
|
403
|
+
moment: { type: 'ABSOLUTE', date: '2018', unit: 'YEAR' }
|
|
404
|
+
} {
|
|
405
|
+
operator: 'ON',
|
|
406
|
+
moment: { type: 'ABSOLUTE', date: '2020', unit: 'YEAR' }
|
|
407
|
+
}
|
|
351
408
|
|
|
352
409
|
Input: next week
|
|
353
|
-
Output: {
|
|
410
|
+
Output: {
|
|
411
|
+
operator: 'ON',
|
|
412
|
+
moment: { type: 'INTERVAL', kind: 'NEXT', unit: 'WEEK' }
|
|
413
|
+
}
|
|
354
414
|
|
|
355
415
|
Input: now
|
|
356
|
-
Output: { operator: 'NOW' }
|
|
416
|
+
Output: { operator: 'ON', moment: { type: 'NAMED', name: 'NOW' } }
|
|
357
417
|
|
|
358
418
|
Input: now to next month
|
|
359
419
|
Output: {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
420
|
+
operator: 'TO_RANGE',
|
|
421
|
+
from: { type: 'NAMED', name: 'NOW' },
|
|
422
|
+
to: { type: 'INTERVAL', kind: 'NEXT', unit: 'MONTH' }
|
|
363
423
|
}
|
|
364
424
|
|
|
425
|
+
Input: null
|
|
426
|
+
Output: { operator: 'NULL' }
|
|
427
|
+
Errors: { message: 'Invalid token NULL', startIndex: 0, endIndex: 4 }
|
|
428
|
+
|
|
429
|
+
Input: -null,
|
|
430
|
+
Output: { operator: 'NOTNULL' }
|
|
431
|
+
Errors: { message: 'Invalid token -NULL', startIndex: 0, endIndex: 5 }
|
|
432
|
+
|
|
365
433
|
Input: yyesterday
|
|
366
434
|
Errors: { message: 'Invalid token yyesterday', startIndex: 1, endIndex: 11 }
|
|
367
435
|
|
|
@@ -374,8 +442,19 @@ Input: 7
|
|
|
374
442
|
Errors: { message: 'Invalid token 7', startIndex: 0, endIndex: 1 }
|
|
375
443
|
|
|
376
444
|
Input: from now
|
|
377
|
-
Output: { operator: 'NOW' }
|
|
445
|
+
Output: { operator: 'ON', moment: { type: 'NAMED', name: 'NOW' } }
|
|
378
446
|
Errors: { message: 'Invalid token FROM', startIndex: 0, endIndex: 4 }
|
|
379
447
|
|
|
448
|
+
Input: 2025-12-25 12:32:
|
|
449
|
+
Output: {
|
|
450
|
+
operator: 'ON',
|
|
451
|
+
moment: { type: 'ABSOLUTE', date: '2025-12-25', unit: 'DAY' }
|
|
452
|
+
}
|
|
453
|
+
Errors: { message: 'Invalid token 12:32:', startIndex: 11, endIndex: 17 }
|
|
454
|
+
|
|
455
|
+
Input: after 2025 seconds
|
|
456
|
+
Errors: { message: 'Invalid token ', startIndex: 6, endIndex: 18 }
|
|
457
|
+
|
|
380
458
|
Input:
|
|
459
|
+
|
|
381
460
|
```
|
package/SERIALIZE_SAMPLES.md
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
# Serializers
|
|
2
2
|
|
|
3
|
-
Each parser has a complementary serializer that converts the structured clause list back
|
|
4
|
-
|
|
5
|
-
Round-trip Examples:
|
|
3
|
+
Each parser has a complementary serializer that converts the structured clause list back
|
|
4
|
+
to string format. Below are round-trip samples: `string` to `Clause[]` back to `string`.
|
|
5
|
+
Round-trip Examples:
|
|
6
6
|
|
|
7
7
|
```code
|
|
8
8
|
Input > parse > Clause[] > serialize > Output
|
|
9
9
|
string string
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
-------------------------------------------------------------------------
|
|
14
13
|
## Number Serializer
|
|
15
14
|
|
|
16
15
|
```code
|
|
@@ -20,8 +19,8 @@ Output: 5
|
|
|
20
19
|
Input: !=5
|
|
21
20
|
Output: !=5
|
|
22
21
|
|
|
23
|
-
Input: 1, 3,
|
|
24
|
-
Output: 1, 3,
|
|
22
|
+
Input: 1, 3, 5, null
|
|
23
|
+
Output: 1, 3, 5, NULL
|
|
25
24
|
|
|
26
25
|
Input: <1, >=100
|
|
27
26
|
Output: <1, >=100
|
|
@@ -57,8 +56,7 @@ Input: [0,10], 20, NULL, ( 72, 82 ]
|
|
|
57
56
|
Output: [0, 10], 20, NULL, (72, 82]
|
|
58
57
|
|
|
59
58
|
Input: , notanumber,, "null", apple pear orange, nulle, nnull, >=,
|
|
60
|
-
Errors: { message: 'Invalid expression', startIndex: 2, endIndex: 12 } { message: 'Invalid expression', startIndex: 15, endIndex: 21 } { message: 'Invalid expression', startIndex: 23, endIndex: 28 } { message: 'Invalid expression', startIndex: 29, endIndex: 33 } { message: 'Invalid expression', startIndex: 34, endIndex: 40 } { message: 'Invalid expression', startIndex: 42, endIndex: 47 } { message:
|
|
61
|
-
'Invalid expression', startIndex: 49, endIndex: 54 } { message: 'Invalid expression', startIndex: 56, endIndex: 58 }
|
|
59
|
+
Errors: { message: 'Invalid expression', startIndex: 2, endIndex: 12 } { message: 'Invalid expression', startIndex: 15, endIndex: 21 } { message: 'Invalid expression', startIndex: 23, endIndex: 28 } { message: 'Invalid expression', startIndex: 29, endIndex: 33 } { message: 'Invalid expression', startIndex: 34, endIndex: 40 } { message: 'Invalid expression', startIndex: 42, endIndex: 47 } { message: 'Invalid expression', startIndex: 49, endIndex: 54 } { message: 'Invalid expression', startIndex: 56, endIndex: 58 }
|
|
62
60
|
|
|
63
61
|
Input: [cat, 100], <cat
|
|
64
62
|
Errors: { message: 'Invalid number', startIndex: 1, endIndex: 4 } { message: 'Invalid expression', startIndex: 12, endIndex: 13 } { message: 'Invalid expression', startIndex: 13, endIndex: 16 }
|
|
@@ -68,8 +66,7 @@ Output: -5.5, 10
|
|
|
68
66
|
Errors: { message: 'Invalid expression', startIndex: 5, endIndex: 7 }
|
|
69
67
|
```
|
|
70
68
|
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
-------------------------------------------------------------------------
|
|
73
70
|
## String Serializer
|
|
74
71
|
|
|
75
72
|
```code
|
|
@@ -169,10 +166,10 @@ Input: one ,Null , Empty,E M P T Y Y,EEmpty, emptIEs
|
|
|
169
166
|
Output: one, NULL, EMPTY, E M P T Y Y, EEmpty, emptIEs
|
|
170
167
|
|
|
171
168
|
Input:
|
|
172
|
-
```
|
|
173
169
|
|
|
174
|
-
|
|
170
|
+
```
|
|
175
171
|
|
|
172
|
+
-------------------------------------------------------------------------
|
|
176
173
|
## Boolean Serializer
|
|
177
174
|
|
|
178
175
|
```code
|
|
@@ -182,14 +179,17 @@ Output: TRUE
|
|
|
182
179
|
Input: FALSE
|
|
183
180
|
Output: FALSE
|
|
184
181
|
|
|
182
|
+
Input: =false
|
|
183
|
+
Output: =FALSE
|
|
184
|
+
|
|
185
185
|
Input: null
|
|
186
186
|
Output: NULL
|
|
187
187
|
|
|
188
188
|
Input: -NULL
|
|
189
189
|
Output: -NULL
|
|
190
190
|
|
|
191
|
-
Input: True , faLSE,NULl,-null
|
|
192
|
-
Output: TRUE, FALSE, NULL, -NULL
|
|
191
|
+
Input: True , faLSE,=false,NULl,-null
|
|
192
|
+
Output: TRUE, FALSE, =FALSE, NULL, -NULL
|
|
193
193
|
|
|
194
194
|
Input: -'null'
|
|
195
195
|
Errors: { message: "Invalid token -'null'", startIndex: 0, endIndex: 7 }
|
|
@@ -202,11 +202,11 @@ Errors: { message: 'Invalid token nnull', startIndex: 0, endIndex: 5 }
|
|
|
202
202
|
|
|
203
203
|
Input: truee
|
|
204
204
|
Errors: { message: 'Invalid token truee', startIndex: 1, endIndex: 6 }
|
|
205
|
-
```
|
|
206
205
|
|
|
207
|
-
|
|
206
|
+
```
|
|
208
207
|
|
|
209
|
-
|
|
208
|
+
-------------------------------------------------------------------------
|
|
209
|
+
## Date Serializer
|
|
210
210
|
|
|
211
211
|
```code
|
|
212
212
|
Input: this month
|
|
@@ -221,9 +221,6 @@ Output: 3 DAYS AGO
|
|
|
221
221
|
Input: 3 months ago for 2 days
|
|
222
222
|
Output: 3 MONTHS AGO FOR 2 DAYS
|
|
223
223
|
|
|
224
|
-
Input: after 2025 seconds
|
|
225
|
-
Output: AFTER 2025 SECONDS
|
|
226
|
-
|
|
227
224
|
Input: 2025 weeks ago
|
|
228
225
|
Output: 2025 WEEKS AGO
|
|
229
226
|
|
|
@@ -236,8 +233,8 @@ Output: BEFORE 2025-08-30 08:30:20
|
|
|
236
233
|
Input: after 2025-10-05
|
|
237
234
|
Output: AFTER 2025-10-05
|
|
238
235
|
|
|
239
|
-
Input: 2025-08-30 12:00
|
|
240
|
-
Output: 2025-08-30 12:00
|
|
236
|
+
Input: 2025-08-30 12:00 to 2025-09-18 14:30
|
|
237
|
+
Output: 2025-08-30 12:00 TO 2025-09-18 14:30
|
|
241
238
|
|
|
242
239
|
Input: this year
|
|
243
240
|
Output: THIS YEAR
|
|
@@ -281,6 +278,14 @@ Output: NOW
|
|
|
281
278
|
Input: now to next month
|
|
282
279
|
Output: NOW TO NEXT MONTH
|
|
283
280
|
|
|
281
|
+
Input: null
|
|
282
|
+
Output: NULL
|
|
283
|
+
Errors: { message: 'Invalid token NULL', startIndex: 0, endIndex: 4 }
|
|
284
|
+
|
|
285
|
+
Input: -null,
|
|
286
|
+
Output: -NULL
|
|
287
|
+
Errors: { message: 'Invalid token -NULL', startIndex: 0, endIndex: 5 }
|
|
288
|
+
|
|
284
289
|
Input: yyesterday
|
|
285
290
|
Errors: { message: 'Invalid token yyesterday', startIndex: 1, endIndex: 11 }
|
|
286
291
|
|
|
@@ -296,5 +301,13 @@ Input: from now
|
|
|
296
301
|
Output: NOW
|
|
297
302
|
Errors: { message: 'Invalid token FROM', startIndex: 0, endIndex: 4 }
|
|
298
303
|
|
|
304
|
+
Input: 2025-12-25 12:32:
|
|
305
|
+
Output: 2025-12-25
|
|
306
|
+
Errors: { message: 'Invalid token 12:32:', startIndex: 11, endIndex: 17 }
|
|
307
|
+
|
|
308
|
+
Input: after 2025 seconds
|
|
309
|
+
Errors: { message: 'Invalid token ', startIndex: 6, endIndex: 18 }
|
|
310
|
+
|
|
299
311
|
Input:
|
|
300
|
-
|
|
312
|
+
|
|
313
|
+
```
|
package/dist/boolean_parser.js
CHANGED
|
@@ -13,7 +13,8 @@ class BooleanParser extends base_parser_1.BaseParser {
|
|
|
13
13
|
{ type: 'NULL', value: 'null', ignoreCase: true },
|
|
14
14
|
{ type: 'NOTNULL', value: '-null', ignoreCase: true },
|
|
15
15
|
{ type: 'TRUE', value: 'true', ignoreCase: true },
|
|
16
|
-
{ type: 'FALSE', value: 'false', ignoreCase: true },
|
|
16
|
+
{ type: 'FALSE', value: '=false', ignoreCase: true },
|
|
17
|
+
{ type: 'FALSEORNULL', value: 'false', ignoreCase: true },
|
|
17
18
|
];
|
|
18
19
|
const params = {
|
|
19
20
|
trimWordWhitespace: true,
|
|
@@ -38,6 +39,7 @@ class BooleanParser extends base_parser_1.BaseParser {
|
|
|
38
39
|
else if (token.type === 'NULL' ||
|
|
39
40
|
token.type === 'TRUE' ||
|
|
40
41
|
token.type === 'FALSE' ||
|
|
42
|
+
token.type === 'FALSEORNULL' ||
|
|
41
43
|
token.type === 'NOTNULL') {
|
|
42
44
|
const clause = { operator: token.type };
|
|
43
45
|
clauses.push(clause);
|