@malloydata/malloy-filter 0.0.237-dev250221201621
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 +81 -0
- package/SAMPLES.md +381 -0
- package/SERIALIZE_SAMPLES.md +300 -0
- package/dist/a_simple_parser.d.ts +1 -0
- package/dist/a_simple_parser.js +20 -0
- package/dist/a_simple_parser.js.map +1 -0
- package/dist/a_simple_serializer.d.ts +1 -0
- package/dist/a_simple_serializer.js +31 -0
- package/dist/a_simple_serializer.js.map +1 -0
- package/dist/base_parser.d.ts +13 -0
- package/dist/base_parser.js +33 -0
- package/dist/base_parser.js.map +1 -0
- package/dist/base_serializer.d.ts +6 -0
- package/dist/base_serializer.js +11 -0
- package/dist/base_serializer.js.map +1 -0
- package/dist/boolean_parser.d.ts +7 -0
- package/dist/boolean_parser.js +59 -0
- package/dist/boolean_parser.js.map +1 -0
- package/dist/boolean_serializer.d.ts +8 -0
- package/dist/boolean_serializer.js +31 -0
- package/dist/boolean_serializer.js.map +1 -0
- package/dist/clause_types.d.ts +70 -0
- package/dist/clause_types.js +3 -0
- package/dist/clause_types.js.map +1 -0
- package/dist/date_parser.d.ts +22 -0
- package/dist/date_parser.js +315 -0
- package/dist/date_parser.js.map +1 -0
- package/dist/date_serializer.d.ts +10 -0
- package/dist/date_serializer.js +100 -0
- package/dist/date_serializer.js.map +1 -0
- package/dist/filter_parser.d.ts +12 -0
- package/dist/filter_parser.js +66 -0
- package/dist/filter_parser.js.map +1 -0
- package/dist/filter_serializer.d.ts +13 -0
- package/dist/filter_serializer.js +43 -0
- package/dist/filter_serializer.js.map +1 -0
- package/dist/filter_types.d.ts +10 -0
- package/dist/filter_types.js +3 -0
- package/dist/filter_types.js.map +1 -0
- package/dist/generate_samples.d.ts +1 -0
- package/dist/generate_samples.js +344 -0
- package/dist/generate_samples.js.map +1 -0
- package/dist/number_parser.d.ts +20 -0
- package/dist/number_parser.js +275 -0
- package/dist/number_parser.js.map +1 -0
- package/dist/number_serializer.d.ts +11 -0
- package/dist/number_serializer.js +76 -0
- package/dist/number_serializer.js.map +1 -0
- package/dist/string_parser.d.ts +18 -0
- package/dist/string_parser.js +198 -0
- package/dist/string_parser.js.map +1 -0
- package/dist/string_serializer.d.ts +11 -0
- package/dist/string_serializer.js +77 -0
- package/dist/string_serializer.js.map +1 -0
- package/dist/token_types.d.ts +7 -0
- package/dist/token_types.js +3 -0
- package/dist/token_types.js.map +1 -0
- package/dist/tokenizer.d.ts +52 -0
- package/dist/tokenizer.js +263 -0
- package/dist/tokenizer.js.map +1 -0
- package/dist/tokenizer.spec.d.ts +1 -0
- package/dist/tokenizer.spec.js +255 -0
- package/dist/tokenizer.spec.js.map +1 -0
- package/jest.config.js +3 -0
- package/package.json +21 -0
- package/src/DEVELOPING.md +26 -0
- package/src/a_simple_parser.ts +22 -0
- package/src/a_simple_serializer.ts +40 -0
- package/src/base_parser.ts +45 -0
- package/src/base_serializer.ts +9 -0
- package/src/boolean_parser.ts +60 -0
- package/src/boolean_serializer.ts +32 -0
- package/src/clause_types.ts +160 -0
- package/src/date_parser.ts +413 -0
- package/src/date_serializer.ts +114 -0
- package/src/filter_parser.ts +68 -0
- package/src/filter_serializer.ts +49 -0
- package/src/filter_types.ts +12 -0
- package/src/generate_samples.ts +387 -0
- package/src/number_parser.ts +308 -0
- package/src/number_serializer.ts +96 -0
- package/src/string_parser.ts +193 -0
- package/src/string_serializer.ts +87 -0
- package/src/token_types.ts +7 -0
- package/src/tokenizer.spec.ts +273 -0
- package/src/tokenizer.ts +320 -0
- package/tsconfig.json +14 -0
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Malloy Filter Expressions
|
|
2
|
+
|
|
3
|
+
This repository contains the parser and serializer for Malloy filter expressions. Filter expressions give Malloy users a powerful, yet simple and intuitive, way to specify complex filtering conditions.
|
|
4
|
+
|
|
5
|
+
The library contains no external dependencies, and is designed to produce a lightweight data structure that can be embedded with minimal overhead into products interfacing with Malloy. Instructions for building and using the library are below.
|
|
6
|
+
|
|
7
|
+
The WN for filter expressions is [TBD].
|
|
8
|
+
|
|
9
|
+
## Building
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm run build
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Using
|
|
16
|
+
|
|
17
|
+
To use the parser, simply import `FilterParser` and go.
|
|
18
|
+
|
|
19
|
+
Example:
|
|
20
|
+
|
|
21
|
+
```code
|
|
22
|
+
import { FilterParser } from './filter_parser'
|
|
23
|
+
|
|
24
|
+
let str = 'CAT,DOG';
|
|
25
|
+
let response = new FilterParser(str, 'string').parse();
|
|
26
|
+
console.log(str, '\n', ...response.clauses, '\n');
|
|
27
|
+
|
|
28
|
+
str = '-5.5, 10, 2.3e7';
|
|
29
|
+
response = new FilterParser(str, 'number').parse();
|
|
30
|
+
console.log(str, '\n', ...response.clauses, '\n');
|
|
31
|
+
|
|
32
|
+
str = 'null, false';
|
|
33
|
+
response = new FilterParser(str, 'boolean').parse();
|
|
34
|
+
console.log(str, '\n', ...response.clauses, '\n');
|
|
35
|
+
|
|
36
|
+
str = 'after 2025-10-05';
|
|
37
|
+
response = new FilterParser(str, 'date').parse();
|
|
38
|
+
console.log(str, '\n', ...response.clauses, '\n');
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Output:
|
|
42
|
+
|
|
43
|
+
```code
|
|
44
|
+
CAT,DOG
|
|
45
|
+
{ operator: '=', values: [ 'CAT', 'DOG' ] }
|
|
46
|
+
|
|
47
|
+
-5.5, 10, 2.3e7
|
|
48
|
+
{ operator: '=', values: [ -5.5, 10, 23000000 ] }
|
|
49
|
+
|
|
50
|
+
null, false
|
|
51
|
+
{ operator: 'NULL' } { operator: 'FALSE' }
|
|
52
|
+
|
|
53
|
+
after 2025-10-05
|
|
54
|
+
{ operator: 'DATE', date: '2025-10-05', prefix: 'AFTER' }
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Likewise, to use the serializer, simply import `FilterSerializer`.
|
|
58
|
+
|
|
59
|
+
## Parsers
|
|
60
|
+
|
|
61
|
+
Each filter type is handled by a different parser (strings, numbers, dates and times, etc).
|
|
62
|
+
|
|
63
|
+
### Number Parser
|
|
64
|
+
|
|
65
|
+
The number parser `number_parser.ts` supports the operations highlighted on the [Samples](SAMPLES.md#numbers) page.
|
|
66
|
+
|
|
67
|
+
### String Parser
|
|
68
|
+
|
|
69
|
+
The string parser `string_parser.ts` supports the operations highlighted on the [Samples](SAMPLES.md#strings) page.
|
|
70
|
+
|
|
71
|
+
### Boolean Parser
|
|
72
|
+
|
|
73
|
+
The boolean parser `boolean_parser.ts` supports the operations highlighted on the [Samples](SAMPLES.md#booleans) page.
|
|
74
|
+
|
|
75
|
+
### Date and Time Parser
|
|
76
|
+
|
|
77
|
+
The date and time parser `date_parser.ts` supports the operations highlighted on the [Samples](SAMPLES.md#dates-and-times) page.
|
|
78
|
+
|
|
79
|
+
## Serializers
|
|
80
|
+
|
|
81
|
+
Each parser has a complementary serializer that converts the parser output (`Clause[]`) 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
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
# Parsers
|
|
2
|
+
|
|
3
|
+
Each filter type is handled by a different parser (strings, numbers, dates and times, etc). Sample outputs from each parser follow...
|
|
4
|
+
|
|
5
|
+
## Numbers
|
|
6
|
+
|
|
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
|
+
```code
|
|
10
|
+
Input: 5
|
|
11
|
+
Output: { operator: '=', values: [ 5 ] }
|
|
12
|
+
|
|
13
|
+
Input: !=5
|
|
14
|
+
Output: { operator: '!=', values: [ 5 ] }
|
|
15
|
+
|
|
16
|
+
Input: 1, 3, null , 7
|
|
17
|
+
Output: { operator: '=', values: [ 1, 3, null, 7 ] }
|
|
18
|
+
|
|
19
|
+
Input: <1, >=100
|
|
20
|
+
Output: { operator: '<', values: [ 1 ] } { operator: '>=', values: [ 100 ] }
|
|
21
|
+
|
|
22
|
+
Input: >=1
|
|
23
|
+
Output: { operator: '>=', values: [ 1 ] }
|
|
24
|
+
|
|
25
|
+
Input: <= 10
|
|
26
|
+
Output: { operator: '<=', values: [ 10 ] }
|
|
27
|
+
|
|
28
|
+
Input: NULL
|
|
29
|
+
Output: { operator: '=', values: [ null ] }
|
|
30
|
+
|
|
31
|
+
Input: -NULL
|
|
32
|
+
Output: { operator: '!=', values: [ null ] }
|
|
33
|
+
|
|
34
|
+
Input: (1, 7)
|
|
35
|
+
Output: {
|
|
36
|
+
operator: 'range',
|
|
37
|
+
startOperator: '>',
|
|
38
|
+
startValue: 1,
|
|
39
|
+
endOperator: '<',
|
|
40
|
+
endValue: 7
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
Input: [-5, 90]
|
|
44
|
+
Output: {
|
|
45
|
+
operator: 'range',
|
|
46
|
+
startOperator: '>=',
|
|
47
|
+
startValue: -5,
|
|
48
|
+
endOperator: '<=',
|
|
49
|
+
endValue: 90
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
Input: != ( 12, 20 ]
|
|
53
|
+
Output: {
|
|
54
|
+
operator: 'range',
|
|
55
|
+
startOperator: '<=',
|
|
56
|
+
startValue: 12,
|
|
57
|
+
endOperator: '>',
|
|
58
|
+
endValue: 20
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
Input: [.12e-20, 20.0e3)
|
|
62
|
+
Output: {
|
|
63
|
+
operator: 'range',
|
|
64
|
+
startOperator: '>=',
|
|
65
|
+
startValue: 1.2e-21,
|
|
66
|
+
endOperator: '<',
|
|
67
|
+
endValue: 20000
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
Input: [0,9],[20,29]
|
|
71
|
+
Output: {
|
|
72
|
+
operator: 'range',
|
|
73
|
+
startOperator: '>=',
|
|
74
|
+
startValue: 0,
|
|
75
|
+
endOperator: '<=',
|
|
76
|
+
endValue: 9
|
|
77
|
+
} {
|
|
78
|
+
operator: 'range',
|
|
79
|
+
startOperator: '>=',
|
|
80
|
+
startValue: 20,
|
|
81
|
+
endOperator: '<=',
|
|
82
|
+
endValue: 29
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
Input: [0,10], 20, NULL, ( 72, 82 ]
|
|
86
|
+
Output: {
|
|
87
|
+
operator: 'range',
|
|
88
|
+
startOperator: '>=',
|
|
89
|
+
startValue: 0,
|
|
90
|
+
endOperator: '<=',
|
|
91
|
+
endValue: 10
|
|
92
|
+
} { operator: '=', values: [ 20, null ] } {
|
|
93
|
+
operator: 'range',
|
|
94
|
+
startOperator: '>',
|
|
95
|
+
startValue: 72,
|
|
96
|
+
endOperator: '<=',
|
|
97
|
+
endValue: 82
|
|
98
|
+
}
|
|
99
|
+
|
|
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 }
|
|
103
|
+
|
|
104
|
+
Input: [cat, 100], <cat
|
|
105
|
+
Errors: { message: 'Invalid number', startIndex: 1, endIndex: 4 } { message: 'Invalid expression', startIndex: 12, endIndex: 13 } { message: 'Invalid expression', startIndex: 13, endIndex: 16 }
|
|
106
|
+
|
|
107
|
+
Input: -5.5 to 10
|
|
108
|
+
Output: { operator: '=', values: [ -5.5, 10 ] }
|
|
109
|
+
Errors: { message: 'Invalid expression', startIndex: 5, endIndex: 7 }
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Strings
|
|
113
|
+
|
|
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
|
+
```code
|
|
117
|
+
Input: CAT, DOG,mouse
|
|
118
|
+
Output: { operator: '=', values: [ 'CAT', 'DOG', 'mouse' ] }
|
|
119
|
+
|
|
120
|
+
Input: -CAT,-DOG , -mouse
|
|
121
|
+
Output: { operator: '!=', values: [ 'CAT', 'DOG', 'mouse' ] }
|
|
122
|
+
|
|
123
|
+
Input: CAT,-"DOG",m o u s e
|
|
124
|
+
Output: { operator: '=', values: [ 'CAT' ] } { operator: '!=', values: [ '"DOG"' ] } { operator: '=', values: [ 'm o u s e' ] }
|
|
125
|
+
|
|
126
|
+
Input: -CAT,-DOG,mouse, bird, zebra, -horse, -goat
|
|
127
|
+
Output: { operator: '!=', values: [ 'CAT', 'DOG' ] } { operator: '=', values: [ 'mouse', 'bird', 'zebra' ] } { operator: '!=', values: [ 'horse', 'goat' ] }
|
|
128
|
+
|
|
129
|
+
Input: Missing ,NULL
|
|
130
|
+
Output: { operator: '=', values: [ 'Missing', null ] }
|
|
131
|
+
|
|
132
|
+
Input: CAT%, D%OG, %ous%, %ira_f%, %_oat,
|
|
133
|
+
Output: { operator: 'starts', values: [ 'CAT' ] } { operator: '~', values: [ 'D%OG' ] } { operator: 'contains', values: [ 'ous' ] } { operator: '~', values: [ '%ira_f%', '%_oat' ] }
|
|
134
|
+
Errors: { message: 'Invalid expression', startIndex: 34, endIndex: 35 }
|
|
135
|
+
|
|
136
|
+
Input: -CAT%,-D%OG,-%mouse,-%zebra%
|
|
137
|
+
Output: { operator: 'notStarts', values: [ 'CAT' ] } { operator: '!~', values: [ 'D%OG' ] } { operator: 'notEnds', values: [ 'mouse' ] } { operator: 'notContains', values: [ 'zebra' ] }
|
|
138
|
+
|
|
139
|
+
Input: CAT%,-CATALOG
|
|
140
|
+
Output: { operator: 'starts', values: [ 'CAT' ] } { operator: '!=', values: [ 'CATALOG' ] }
|
|
141
|
+
|
|
142
|
+
Input: %,_,%%,%a%
|
|
143
|
+
Output: { operator: '~', values: [ '%', '_', '%%' ] } { operator: 'contains', values: [ 'a' ] }
|
|
144
|
+
|
|
145
|
+
Input: %\_X
|
|
146
|
+
Output: { operator: 'ends', values: [ '_X' ] }
|
|
147
|
+
|
|
148
|
+
Input: _\_X
|
|
149
|
+
Output: { operator: '~', values: [ '_\\_X' ] }
|
|
150
|
+
|
|
151
|
+
Input: _CAT,D_G,mouse_
|
|
152
|
+
Output: { operator: '~', values: [ '_CAT', 'D_G', 'mouse_' ] }
|
|
153
|
+
|
|
154
|
+
Input: \_CAT,D\%G,\mouse
|
|
155
|
+
Output: { operator: '=', values: [ '_CAT', 'D%G', 'mouse' ] }
|
|
156
|
+
|
|
157
|
+
Input: CAT,-NULL
|
|
158
|
+
Output: { operator: '=', values: [ 'CAT' ] } { operator: '!=', values: [ null ] }
|
|
159
|
+
|
|
160
|
+
Input: CAT,-"NULL"
|
|
161
|
+
Output: { operator: '=', values: [ 'CAT' ] } { operator: '!=', values: [ '"NULL"' ] }
|
|
162
|
+
|
|
163
|
+
Input: CAT,NULL
|
|
164
|
+
Output: { operator: '=', values: [ 'CAT', null ] }
|
|
165
|
+
|
|
166
|
+
Input: EMPTY
|
|
167
|
+
Output: { operator: 'EMPTY', values: [ null ] }
|
|
168
|
+
|
|
169
|
+
Input: -EMPTY
|
|
170
|
+
Output: { operator: 'NOTEMPTY', values: [ null ] }
|
|
171
|
+
|
|
172
|
+
Input: CAT,-EMPTY
|
|
173
|
+
Output: { operator: '=', values: [ 'CAT' ] } { operator: 'NOTEMPTY', values: [ null ] }
|
|
174
|
+
|
|
175
|
+
Input: "CAT,DOG',mo`use,zeb'''ra,g"""t,g\"ir\`af\'e
|
|
176
|
+
Output: {
|
|
177
|
+
operator: '=',
|
|
178
|
+
values: [ '"CAT', "DOG'", 'mo`use', "zeb'''ra", 'g"""t', 'g"ir`af\'e' ]
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
Input: CAT\,DOG
|
|
182
|
+
Output: { operator: '=', values: [ 'CAT,DOG' ] }
|
|
183
|
+
|
|
184
|
+
Input: CAT,DOG,-, -
|
|
185
|
+
Output: { operator: '=', values: [ 'CAT', 'DOG', '-', '-' ] }
|
|
186
|
+
|
|
187
|
+
Input: --CAT,DOG,\
|
|
188
|
+
Output: { operator: '!=', values: [ '-CAT' ] } { operator: '=', values: [ 'DOG' ] }
|
|
189
|
+
Errors: { message: 'Invalid expression', startIndex: 10, endIndex: 11 }
|
|
190
|
+
|
|
191
|
+
Input: CAT\ DOG
|
|
192
|
+
Output: { operator: '=', values: [ 'CAT DOG' ] }
|
|
193
|
+
|
|
194
|
+
Input: _\_CAT
|
|
195
|
+
Output: { operator: '~', values: [ '_\\_CAT' ] }
|
|
196
|
+
|
|
197
|
+
Input: \NULL
|
|
198
|
+
Output: { operator: '=', values: [ 'NULL' ] }
|
|
199
|
+
|
|
200
|
+
Input: \-NULL
|
|
201
|
+
Output: { operator: '=', values: [ '-NULL' ] }
|
|
202
|
+
|
|
203
|
+
Input: -N\ULL
|
|
204
|
+
Output: { operator: '!=', values: [ 'NULL' ] }
|
|
205
|
+
|
|
206
|
+
Input: CA--,D-G
|
|
207
|
+
Output: { operator: '=', values: [ 'CA--', 'D-G' ] }
|
|
208
|
+
|
|
209
|
+
Input: hello world, foo="bar baz" , qux=quux
|
|
210
|
+
Output: {
|
|
211
|
+
operator: '=',
|
|
212
|
+
values: [ 'hello world', 'foo="bar baz"', 'qux=quux' ]
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
Input: one ,Null , Empty,E M P T Y Y,EEmpty, emptIEs
|
|
216
|
+
Output: { operator: '=', values: [ 'one', null ] } { operator: 'EMPTY', values: [ null ] } { operator: '=', values: [ 'E M P T Y Y', 'EEmpty', 'emptIEs' ] }
|
|
217
|
+
|
|
218
|
+
Input:
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Booleans
|
|
222
|
+
|
|
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
|
+
```code
|
|
226
|
+
Input: true
|
|
227
|
+
Output: { operator: 'TRUE' }
|
|
228
|
+
|
|
229
|
+
Input: FALSE
|
|
230
|
+
Output: { operator: 'FALSE' }
|
|
231
|
+
|
|
232
|
+
Input: null
|
|
233
|
+
Output: { operator: 'NULL' }
|
|
234
|
+
|
|
235
|
+
Input: -NULL
|
|
236
|
+
Output: { operator: 'NOTNULL' }
|
|
237
|
+
|
|
238
|
+
Input: True , faLSE,NULl,-null
|
|
239
|
+
Output: { operator: 'TRUE' } { operator: 'FALSE' } { operator: 'NULL' } { operator: 'NOTNULL' }
|
|
240
|
+
|
|
241
|
+
Input: -'null'
|
|
242
|
+
Errors: { message: "Invalid token -'null'", startIndex: 0, endIndex: 7 }
|
|
243
|
+
|
|
244
|
+
Input: 10
|
|
245
|
+
Errors: { message: 'Invalid token 10', startIndex: 0, endIndex: 2 }
|
|
246
|
+
|
|
247
|
+
Input: nnull
|
|
248
|
+
Errors: { message: 'Invalid token nnull', startIndex: 0, endIndex: 5 }
|
|
249
|
+
|
|
250
|
+
Input: truee
|
|
251
|
+
Errors: { message: 'Invalid token truee', startIndex: 1, endIndex: 6 }
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Dates and Times
|
|
255
|
+
|
|
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
|
+
```code
|
|
259
|
+
Input: this month
|
|
260
|
+
Output: { operator: 'THIS', unit: 'MONTH' }
|
|
261
|
+
|
|
262
|
+
Input: 3 days
|
|
263
|
+
Output: { operator: 'TIMEBLOCK', value: '3', unit: 'DAYS' }
|
|
264
|
+
|
|
265
|
+
Input: 3 days ago
|
|
266
|
+
Output: { operator: 'AGO', value: '3', unit: 'DAYS' }
|
|
267
|
+
|
|
268
|
+
Input: 3 months ago for 2 days
|
|
269
|
+
Output: {
|
|
270
|
+
start: { operator: 'AGO', value: '3', unit: 'MONTHS' },
|
|
271
|
+
operator: 'FOR',
|
|
272
|
+
end: { operator: 'TIMEBLOCK', value: '2', unit: 'DAYS' }
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
Input: after 2025 seconds
|
|
276
|
+
Output: {
|
|
277
|
+
operator: 'TIMEBLOCK',
|
|
278
|
+
value: '2025',
|
|
279
|
+
unit: 'SECONDS',
|
|
280
|
+
prefix: 'AFTER'
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
Input: 2025 weeks ago
|
|
284
|
+
Output: { operator: 'AGO', value: '2025', unit: 'WEEKS' }
|
|
285
|
+
|
|
286
|
+
Input: before 3 days ago
|
|
287
|
+
Output: { operator: 'AGO', value: '3', unit: 'DAYS', prefix: 'BEFORE' }
|
|
288
|
+
|
|
289
|
+
Input: before 2025-08-30 08:30:20
|
|
290
|
+
Output: {
|
|
291
|
+
operator: 'DATETIME',
|
|
292
|
+
date: '2025-08-30',
|
|
293
|
+
time: '08:30:20',
|
|
294
|
+
prefix: 'BEFORE'
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
Input: after 2025-10-05
|
|
298
|
+
Output: { operator: 'DATE', date: '2025-10-05', prefix: 'AFTER' }
|
|
299
|
+
|
|
300
|
+
Input: 2025-08-30 12:00:00 to 2025-09-18 14:00:00
|
|
301
|
+
Output: {
|
|
302
|
+
start: { operator: 'DATETIME', date: '2025-08-30', time: '12:00:00' },
|
|
303
|
+
operator: 'TO',
|
|
304
|
+
end: { operator: 'DATETIME', date: '2025-09-18', time: '14:00:00' }
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
Input: this year
|
|
308
|
+
Output: { operator: 'THIS', unit: 'YEAR' }
|
|
309
|
+
|
|
310
|
+
Input: next tuesday
|
|
311
|
+
Output: { operator: 'NEXT', unit: 'TUESDAY' }
|
|
312
|
+
|
|
313
|
+
Input: 7 years from now
|
|
314
|
+
Output: { operator: 'FROMNOW', value: '7', unit: 'YEARS' }
|
|
315
|
+
|
|
316
|
+
Input: 2025-01-01 12:00:00 for 3 days
|
|
317
|
+
Output: {
|
|
318
|
+
start: { operator: 'DATETIME', date: '2025-01-01', time: '12:00:00' },
|
|
319
|
+
operator: 'FOR',
|
|
320
|
+
end: { operator: 'TIMEBLOCK', value: '3', unit: 'DAYS' }
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
Input: 2020-08-12
|
|
324
|
+
Output: { operator: 'DATE', date: '2020-08-12' }
|
|
325
|
+
|
|
326
|
+
Input: 2020-08
|
|
327
|
+
Output: { operator: 'DATE', date: '2020-08' }
|
|
328
|
+
|
|
329
|
+
Input: today
|
|
330
|
+
Output: { operator: 'TODAY' }
|
|
331
|
+
|
|
332
|
+
Input: yesterday
|
|
333
|
+
Output: { operator: 'YESTERDAY' }
|
|
334
|
+
|
|
335
|
+
Input: tomorrow
|
|
336
|
+
Output: { operator: 'TOMORROW' }
|
|
337
|
+
|
|
338
|
+
Input: TODay,Yesterday, TOMORROW , ,TODay ,,
|
|
339
|
+
Output: { operator: 'TODAY' } { operator: 'YESTERDAY' } { operator: 'TOMORROW' } { operator: 'TODAY' }
|
|
340
|
+
|
|
341
|
+
Input: 2010 to 2011, 2015 to 2016 , 2018, 2020
|
|
342
|
+
Output: {
|
|
343
|
+
start: { operator: 'DATE', date: '2010' },
|
|
344
|
+
operator: 'TO',
|
|
345
|
+
end: { operator: 'DATE', date: '2011' }
|
|
346
|
+
} {
|
|
347
|
+
start: { operator: 'DATE', date: '2015' },
|
|
348
|
+
operator: 'TO',
|
|
349
|
+
end: { operator: 'DATE', date: '2016' }
|
|
350
|
+
} { operator: 'DATE', date: '2018' } { operator: 'DATE', date: '2020' }
|
|
351
|
+
|
|
352
|
+
Input: next week
|
|
353
|
+
Output: { operator: 'NEXT', unit: 'WEEK' }
|
|
354
|
+
|
|
355
|
+
Input: now
|
|
356
|
+
Output: { operator: 'NOW' }
|
|
357
|
+
|
|
358
|
+
Input: now to next month
|
|
359
|
+
Output: {
|
|
360
|
+
start: { operator: 'NOW' },
|
|
361
|
+
operator: 'TO',
|
|
362
|
+
end: { operator: 'NEXT', unit: 'MONTH' }
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
Input: yyesterday
|
|
366
|
+
Errors: { message: 'Invalid token yyesterday', startIndex: 1, endIndex: 11 }
|
|
367
|
+
|
|
368
|
+
Input: before
|
|
369
|
+
|
|
370
|
+
Input: for
|
|
371
|
+
Errors: { message: 'Invalid token FOR', startIndex: 0, endIndex: 3 }
|
|
372
|
+
|
|
373
|
+
Input: 7
|
|
374
|
+
Errors: { message: 'Invalid token 7', startIndex: 0, endIndex: 1 }
|
|
375
|
+
|
|
376
|
+
Input: from now
|
|
377
|
+
Output: { operator: 'NOW' }
|
|
378
|
+
Errors: { message: 'Invalid token FROM', startIndex: 0, endIndex: 4 }
|
|
379
|
+
|
|
380
|
+
Input:
|
|
381
|
+
```
|