@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.
Files changed (87) hide show
  1. package/README.md +81 -0
  2. package/SAMPLES.md +381 -0
  3. package/SERIALIZE_SAMPLES.md +300 -0
  4. package/dist/a_simple_parser.d.ts +1 -0
  5. package/dist/a_simple_parser.js +20 -0
  6. package/dist/a_simple_parser.js.map +1 -0
  7. package/dist/a_simple_serializer.d.ts +1 -0
  8. package/dist/a_simple_serializer.js +31 -0
  9. package/dist/a_simple_serializer.js.map +1 -0
  10. package/dist/base_parser.d.ts +13 -0
  11. package/dist/base_parser.js +33 -0
  12. package/dist/base_parser.js.map +1 -0
  13. package/dist/base_serializer.d.ts +6 -0
  14. package/dist/base_serializer.js +11 -0
  15. package/dist/base_serializer.js.map +1 -0
  16. package/dist/boolean_parser.d.ts +7 -0
  17. package/dist/boolean_parser.js +59 -0
  18. package/dist/boolean_parser.js.map +1 -0
  19. package/dist/boolean_serializer.d.ts +8 -0
  20. package/dist/boolean_serializer.js +31 -0
  21. package/dist/boolean_serializer.js.map +1 -0
  22. package/dist/clause_types.d.ts +70 -0
  23. package/dist/clause_types.js +3 -0
  24. package/dist/clause_types.js.map +1 -0
  25. package/dist/date_parser.d.ts +22 -0
  26. package/dist/date_parser.js +315 -0
  27. package/dist/date_parser.js.map +1 -0
  28. package/dist/date_serializer.d.ts +10 -0
  29. package/dist/date_serializer.js +100 -0
  30. package/dist/date_serializer.js.map +1 -0
  31. package/dist/filter_parser.d.ts +12 -0
  32. package/dist/filter_parser.js +66 -0
  33. package/dist/filter_parser.js.map +1 -0
  34. package/dist/filter_serializer.d.ts +13 -0
  35. package/dist/filter_serializer.js +43 -0
  36. package/dist/filter_serializer.js.map +1 -0
  37. package/dist/filter_types.d.ts +10 -0
  38. package/dist/filter_types.js +3 -0
  39. package/dist/filter_types.js.map +1 -0
  40. package/dist/generate_samples.d.ts +1 -0
  41. package/dist/generate_samples.js +344 -0
  42. package/dist/generate_samples.js.map +1 -0
  43. package/dist/number_parser.d.ts +20 -0
  44. package/dist/number_parser.js +275 -0
  45. package/dist/number_parser.js.map +1 -0
  46. package/dist/number_serializer.d.ts +11 -0
  47. package/dist/number_serializer.js +76 -0
  48. package/dist/number_serializer.js.map +1 -0
  49. package/dist/string_parser.d.ts +18 -0
  50. package/dist/string_parser.js +198 -0
  51. package/dist/string_parser.js.map +1 -0
  52. package/dist/string_serializer.d.ts +11 -0
  53. package/dist/string_serializer.js +77 -0
  54. package/dist/string_serializer.js.map +1 -0
  55. package/dist/token_types.d.ts +7 -0
  56. package/dist/token_types.js +3 -0
  57. package/dist/token_types.js.map +1 -0
  58. package/dist/tokenizer.d.ts +52 -0
  59. package/dist/tokenizer.js +263 -0
  60. package/dist/tokenizer.js.map +1 -0
  61. package/dist/tokenizer.spec.d.ts +1 -0
  62. package/dist/tokenizer.spec.js +255 -0
  63. package/dist/tokenizer.spec.js.map +1 -0
  64. package/jest.config.js +3 -0
  65. package/package.json +21 -0
  66. package/src/DEVELOPING.md +26 -0
  67. package/src/a_simple_parser.ts +22 -0
  68. package/src/a_simple_serializer.ts +40 -0
  69. package/src/base_parser.ts +45 -0
  70. package/src/base_serializer.ts +9 -0
  71. package/src/boolean_parser.ts +60 -0
  72. package/src/boolean_serializer.ts +32 -0
  73. package/src/clause_types.ts +160 -0
  74. package/src/date_parser.ts +413 -0
  75. package/src/date_serializer.ts +114 -0
  76. package/src/filter_parser.ts +68 -0
  77. package/src/filter_serializer.ts +49 -0
  78. package/src/filter_types.ts +12 -0
  79. package/src/generate_samples.ts +387 -0
  80. package/src/number_parser.ts +308 -0
  81. package/src/number_serializer.ts +96 -0
  82. package/src/string_parser.ts +193 -0
  83. package/src/string_serializer.ts +87 -0
  84. package/src/token_types.ts +7 -0
  85. package/src/tokenizer.spec.ts +273 -0
  86. package/src/tokenizer.ts +320 -0
  87. package/tsconfig.json +14 -0
@@ -0,0 +1,300 @@
1
+ # Serializers
2
+
3
+ Each parser has a complementary serializer that converts the structured clause list back to string format. Below are round-trip samples: `string` to `Clause[]` back to `string`.
4
+
5
+ Round-trip Examples:
6
+
7
+ ```code
8
+ Input > parse > Clause[] > serialize > Output
9
+ string string
10
+ ```
11
+
12
+ ---
13
+
14
+ ## Number Serializer
15
+
16
+ ```code
17
+ Input: 5
18
+ Output: 5
19
+
20
+ Input: !=5
21
+ Output: !=5
22
+
23
+ Input: 1, 3, null , 7
24
+ Output: 1, 3, NULL, 7
25
+
26
+ Input: <1, >=100
27
+ Output: <1, >=100
28
+
29
+ Input: >=1
30
+ Output: >=1
31
+
32
+ Input: <= 10
33
+ Output: <=10
34
+
35
+ Input: NULL
36
+ Output: NULL
37
+
38
+ Input: -NULL
39
+ Output: -NULL
40
+
41
+ Input: (1, 7)
42
+ Output: (1, 7)
43
+
44
+ Input: [-5, 90]
45
+ Output: [-5, 90]
46
+
47
+ Input: != ( 12, 20 ]
48
+ Output: !=(12, 20]
49
+
50
+ Input: [.12e-20, 20.0e3)
51
+ Output: [1.2e-21, 20000)
52
+
53
+ Input: [0,9],[20,29]
54
+ Output: [0, 9], [20, 29]
55
+
56
+ Input: [0,10], 20, NULL, ( 72, 82 ]
57
+ Output: [0, 10], 20, NULL, (72, 82]
58
+
59
+ 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 }
62
+
63
+ Input: [cat, 100], <cat
64
+ Errors: { message: 'Invalid number', startIndex: 1, endIndex: 4 } { message: 'Invalid expression', startIndex: 12, endIndex: 13 } { message: 'Invalid expression', startIndex: 13, endIndex: 16 }
65
+
66
+ Input: -5.5 to 10
67
+ Output: -5.5, 10
68
+ Errors: { message: 'Invalid expression', startIndex: 5, endIndex: 7 }
69
+ ```
70
+
71
+ ---
72
+
73
+ ## String Serializer
74
+
75
+ ```code
76
+ Input: CAT, DOG,mouse
77
+ Output: CAT, DOG, mouse
78
+
79
+ Input: -CAT,-DOG , -mouse
80
+ Output: -CAT, -DOG, -mouse
81
+
82
+ Input: CAT,-"DOG",m o u s e
83
+ Output: CAT, -"DOG", m o u s e
84
+
85
+ Input: -CAT,-DOG,mouse, bird, zebra, -horse, -goat
86
+ Output: -CAT, -DOG, mouse, bird, zebra, -horse, -goat
87
+
88
+ Input: Missing ,NULL
89
+ Output: Missing, NULL
90
+
91
+ Input: CAT%, D%OG, %ous%, %ira_f%, %_oat,
92
+ Output: CAT%, D%OG, %ous%, %ira_f%, %_oat
93
+ Errors: { message: 'Invalid expression', startIndex: 34, endIndex: 35 }
94
+
95
+ Input: -CAT%,-D%OG,-%mouse,-%zebra%
96
+ Output: -CAT%, -D%OG, -%mouse, -%zebra%
97
+
98
+ Input: CAT%,-CATALOG
99
+ Output: CAT%, -CATALOG
100
+
101
+ Input: %,_,%%,%a%
102
+ Output: %, _, %%, %a%
103
+
104
+ Input: %\_X
105
+ Output: %\_X
106
+
107
+ Input: _\_X
108
+ Output: _\\_X
109
+
110
+ Input: _CAT,D_G,mouse_
111
+ Output: _CAT, D_G, mouse_
112
+
113
+ Input: \_CAT,D\%G,\mouse
114
+ Output: \_CAT, D\%G, mouse
115
+
116
+ Input: CAT,-NULL
117
+ Output: CAT, -NULL
118
+
119
+ Input: CAT,-"NULL"
120
+ Output: CAT, -"NULL"
121
+
122
+ Input: CAT,NULL
123
+ Output: CAT, NULL
124
+
125
+ Input: EMPTY
126
+ Output: EMPTY
127
+
128
+ Input: -EMPTY
129
+ Output: -EMPTY
130
+
131
+ Input: CAT,-EMPTY
132
+ Output: CAT, -EMPTY
133
+
134
+ Input: "CAT,DOG',mo`use,zeb'''ra,g"""t,g\"ir\`af\'e
135
+ Output: "CAT, DOG', mo`use, zeb'''ra, g"""t, g"ir`af'e
136
+
137
+ Input: CAT\,DOG
138
+ Output: CAT\,DOG
139
+
140
+ Input: CAT,DOG,-, -
141
+ Output: CAT, DOG, -, -
142
+
143
+ Input: --CAT,DOG,\
144
+ Output: --CAT, DOG
145
+ Errors: { message: 'Invalid expression', startIndex: 10, endIndex: 11 }
146
+
147
+ Input: CAT\ DOG
148
+ Output: CAT DOG
149
+
150
+ Input: _\_CAT
151
+ Output: _\\_CAT
152
+
153
+ Input: \NULL
154
+ Output: \NULL
155
+
156
+ Input: \-NULL
157
+ Output: \-NULL
158
+
159
+ Input: -N\ULL
160
+ Output: -\NULL
161
+
162
+ Input: CA--,D-G
163
+ Output: CA--, D-G
164
+
165
+ Input: hello world, foo="bar baz" , qux=quux
166
+ Output: hello world, foo="bar baz", qux=quux
167
+
168
+ Input: one ,Null , Empty,E M P T Y Y,EEmpty, emptIEs
169
+ Output: one, NULL, EMPTY, E M P T Y Y, EEmpty, emptIEs
170
+
171
+ Input:
172
+ ```
173
+
174
+ ---
175
+
176
+ ## Boolean Serializer
177
+
178
+ ```code
179
+ Input: true
180
+ Output: TRUE
181
+
182
+ Input: FALSE
183
+ Output: FALSE
184
+
185
+ Input: null
186
+ Output: NULL
187
+
188
+ Input: -NULL
189
+ Output: -NULL
190
+
191
+ Input: True , faLSE,NULl,-null
192
+ Output: TRUE, FALSE, NULL, -NULL
193
+
194
+ Input: -'null'
195
+ Errors: { message: "Invalid token -'null'", startIndex: 0, endIndex: 7 }
196
+
197
+ Input: 10
198
+ Errors: { message: 'Invalid token 10', startIndex: 0, endIndex: 2 }
199
+
200
+ Input: nnull
201
+ Errors: { message: 'Invalid token nnull', startIndex: 0, endIndex: 5 }
202
+
203
+ Input: truee
204
+ Errors: { message: 'Invalid token truee', startIndex: 1, endIndex: 6 }
205
+ ```
206
+
207
+ ---
208
+
209
+ ## Date and Time Serializer
210
+
211
+ ```code
212
+ Input: this month
213
+ Output: THIS MONTH
214
+
215
+ Input: 3 days
216
+ Output: 3 DAYS
217
+
218
+ Input: 3 days ago
219
+ Output: 3 DAYS AGO
220
+
221
+ Input: 3 months ago for 2 days
222
+ Output: 3 MONTHS AGO FOR 2 DAYS
223
+
224
+ Input: after 2025 seconds
225
+ Output: AFTER 2025 SECONDS
226
+
227
+ Input: 2025 weeks ago
228
+ Output: 2025 WEEKS AGO
229
+
230
+ Input: before 3 days ago
231
+ Output: BEFORE 3 DAYS AGO
232
+
233
+ Input: before 2025-08-30 08:30:20
234
+ Output: BEFORE 2025-08-30 08:30:20
235
+
236
+ Input: after 2025-10-05
237
+ Output: AFTER 2025-10-05
238
+
239
+ Input: 2025-08-30 12:00:00 to 2025-09-18 14:00:00
240
+ Output: 2025-08-30 12:00:00 TO 2025-09-18 14:00:00
241
+
242
+ Input: this year
243
+ Output: THIS YEAR
244
+
245
+ Input: next tuesday
246
+ Output: NEXT TUESDAY
247
+
248
+ Input: 7 years from now
249
+ Output: 7 YEARS FROM NOW
250
+
251
+ Input: 2025-01-01 12:00:00 for 3 days
252
+ Output: 2025-01-01 12:00:00 FOR 3 DAYS
253
+
254
+ Input: 2020-08-12
255
+ Output: 2020-08-12
256
+
257
+ Input: 2020-08
258
+ Output: 2020-08
259
+
260
+ Input: today
261
+ Output: TODAY
262
+
263
+ Input: yesterday
264
+ Output: YESTERDAY
265
+
266
+ Input: tomorrow
267
+ Output: TOMORROW
268
+
269
+ Input: TODay,Yesterday, TOMORROW , ,TODay ,,
270
+ Output: TODAY, YESTERDAY, TOMORROW, TODAY
271
+
272
+ Input: 2010 to 2011, 2015 to 2016 , 2018, 2020
273
+ Output: 2010 TO 2011, 2015 TO 2016, 2018, 2020
274
+
275
+ Input: next week
276
+ Output: NEXT WEEK
277
+
278
+ Input: now
279
+ Output: NOW
280
+
281
+ Input: now to next month
282
+ Output: NOW TO NEXT MONTH
283
+
284
+ Input: yyesterday
285
+ Errors: { message: 'Invalid token yyesterday', startIndex: 1, endIndex: 11 }
286
+
287
+ Input: before
288
+
289
+ Input: for
290
+ Errors: { message: 'Invalid token FOR', startIndex: 0, endIndex: 3 }
291
+
292
+ Input: 7
293
+ Errors: { message: 'Invalid token 7', startIndex: 0, endIndex: 1 }
294
+
295
+ Input: from now
296
+ Output: NOW
297
+ Errors: { message: 'Invalid token FROM', startIndex: 0, endIndex: 4 }
298
+
299
+ Input:
300
+ ```
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const filter_parser_1 = require("./filter_parser");
4
+ /* eslint-disable no-console */
5
+ function aSimpleParser() {
6
+ let str = 'CAT,DOG';
7
+ let response = new filter_parser_1.FilterParser(str, 'string').parse();
8
+ console.log(str, '\n', ...response.clauses, '\n');
9
+ str = '-5.5, 10, 2.3e7';
10
+ response = new filter_parser_1.FilterParser(str, 'number').parse();
11
+ console.log(str, '\n', ...response.clauses, '\n');
12
+ str = 'null, false';
13
+ response = new filter_parser_1.FilterParser(str, 'boolean').parse();
14
+ console.log(str, '\n', ...response.clauses, '\n');
15
+ str = 'after 2025-10-05';
16
+ response = new filter_parser_1.FilterParser(str, 'date').parse();
17
+ console.log(str, '\n', ...response.clauses, '\n');
18
+ }
19
+ aSimpleParser();
20
+ //# sourceMappingURL=a_simple_parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a_simple_parser.js","sourceRoot":"","sources":["../src/a_simple_parser.ts"],"names":[],"mappings":";;AAAA,mDAA6C;AAE7C,+BAA+B;AAC/B,SAAS,aAAa;IACpB,IAAI,GAAG,GAAG,SAAS,CAAC;IACpB,IAAI,QAAQ,GAAG,IAAI,4BAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAElD,GAAG,GAAG,iBAAiB,CAAC;IACxB,QAAQ,GAAG,IAAI,4BAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAElD,GAAG,GAAG,aAAa,CAAC;IACpB,QAAQ,GAAG,IAAI,4BAAY,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,KAAK,EAAE,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAElD,GAAG,GAAG,kBAAkB,CAAC;IACzB,QAAQ,GAAG,IAAI,4BAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACpD,CAAC;AAED,aAAa,EAAE,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const filter_serializer_1 = require("./filter_serializer");
4
+ /* eslint-disable no-console */
5
+ function aSimpleSerializer() {
6
+ const strings = [{ operator: '=', values: ['CAT', 'DOG'] }];
7
+ let response = new filter_serializer_1.FilterSerializer(strings, 'string').serialize();
8
+ console.log(...strings, '\n', response.result, '\n');
9
+ const numbers = [
10
+ {
11
+ operator: 'range',
12
+ startOperator: '>=',
13
+ startValue: -5.5,
14
+ endOperator: '<',
15
+ endValue: 10,
16
+ },
17
+ ];
18
+ response = new filter_serializer_1.FilterSerializer(numbers, 'number').serialize();
19
+ console.log(...numbers, '\n', response.result, '\n');
20
+ const booleans = [{ operator: 'NULL' }, { operator: 'TRUE' }];
21
+ response = new filter_serializer_1.FilterSerializer(booleans, 'boolean').serialize();
22
+ console.log(...booleans, '\n', response.result, '\n');
23
+ const dates = [
24
+ { operator: 'YESTERDAY' },
25
+ { operator: 'NEXT', unit: 'TUESDAY' },
26
+ ];
27
+ response = new filter_serializer_1.FilterSerializer(dates, 'date').serialize();
28
+ console.log(...dates, '\n', response.result, '\n');
29
+ }
30
+ aSimpleSerializer();
31
+ //# sourceMappingURL=a_simple_serializer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a_simple_serializer.js","sourceRoot":"","sources":["../src/a_simple_serializer.ts"],"names":[],"mappings":";;AAAA,2DAAqD;AAQrD,+BAA+B;AAC/B,SAAS,iBAAiB;IACxB,MAAM,OAAO,GAAsB,CAAC,EAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,EAAC,CAAC,CAAC;IAC7E,IAAI,QAAQ,GAAG,IAAI,oCAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,SAAS,EAAE,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAErD,MAAM,OAAO,GAAmB;QAC9B;YACE,QAAQ,EAAE,OAAO;YACjB,aAAa,EAAE,IAAI;YACnB,UAAU,EAAE,CAAC,GAAG;YAChB,WAAW,EAAE,GAAG;YAChB,QAAQ,EAAE,EAAE;SACb;KACF,CAAC;IACF,QAAQ,GAAG,IAAI,oCAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,SAAS,EAAE,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAErD,MAAM,QAAQ,GAAoB,CAAC,EAAC,QAAQ,EAAE,MAAM,EAAC,EAAE,EAAC,QAAQ,EAAE,MAAM,EAAC,CAAC,CAAC;IAE3E,QAAQ,GAAG,IAAI,oCAAgB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,SAAS,EAAE,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAEtD,MAAM,KAAK,GAAiB;QAC1B,EAAC,QAAQ,EAAE,WAAW,EAAC;QACvB,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAC;KACpC,CAAC;IACF,QAAQ,GAAG,IAAI,oCAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACrD,CAAC;AAED,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { Token } from './token_types';
2
+ import { FilterParserResponse } from './filter_types';
3
+ export declare abstract class BaseParser {
4
+ protected inputString: string;
5
+ protected index: number;
6
+ protected tokens: Token[];
7
+ constructor(inputString: string);
8
+ getTokens(): Token[];
9
+ abstract parse(): FilterParserResponse;
10
+ protected getAt(index: number): Token;
11
+ protected getNext(): Token;
12
+ protected static matchTokenTypes(candidates: string[], index: number, tokens: Token[]): boolean;
13
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseParser = void 0;
4
+ class BaseParser {
5
+ constructor(inputString) {
6
+ this.index = 0;
7
+ this.tokens = [];
8
+ this.inputString = inputString;
9
+ }
10
+ getTokens() {
11
+ return this.tokens;
12
+ }
13
+ getAt(index) {
14
+ return this.tokens[index];
15
+ }
16
+ getNext() {
17
+ return this.getAt(this.index);
18
+ }
19
+ static matchTokenTypes(candidates, index, tokens) {
20
+ const maxIndex = index + candidates.length;
21
+ if (index < 0 || maxIndex > tokens.length) {
22
+ return false;
23
+ }
24
+ for (let i = 0; i < candidates.length; i++) {
25
+ if (candidates[i] !== tokens[i + index].type) {
26
+ return false;
27
+ }
28
+ }
29
+ return true;
30
+ }
31
+ }
32
+ exports.BaseParser = BaseParser;
33
+ //# sourceMappingURL=base_parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base_parser.js","sourceRoot":"","sources":["../src/base_parser.ts"],"names":[],"mappings":";;;AAGA,MAAsB,UAAU;IAK9B,YAAY,WAAmB;QAC7B,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAEM,SAAS;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAIS,KAAK,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAES,OAAO;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAES,MAAM,CAAC,eAAe,CAC9B,UAAoB,EACpB,KAAa,EACb,MAAe;QAEf,MAAM,QAAQ,GAAG,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC;QAC3C,IAAI,KAAK,GAAG,CAAC,IAAI,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE;YACzC,OAAO,KAAK,CAAC;SACd;QACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YAC1C,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE;gBAC5C,OAAO,KAAK,CAAC;aACd;SACF;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAzCD,gCAyCC"}
@@ -0,0 +1,6 @@
1
+ import { Clause } from './clause_types';
2
+ export declare abstract class BaseSerializer {
3
+ protected clauses: Clause[];
4
+ constructor(clauses: Clause[]);
5
+ abstract serialize(): string;
6
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseSerializer = void 0;
4
+ class BaseSerializer {
5
+ constructor(clauses) {
6
+ this.clauses = clauses;
7
+ this.clauses = clauses;
8
+ }
9
+ }
10
+ exports.BaseSerializer = BaseSerializer;
11
+ //# sourceMappingURL=base_serializer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base_serializer.js","sourceRoot":"","sources":["../src/base_serializer.ts"],"names":[],"mappings":";;;AAEA,MAAsB,cAAc;IAClC,YAAsB,OAAiB;QAAjB,YAAO,GAAP,OAAO,CAAU;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CAGF;AAND,wCAMC"}
@@ -0,0 +1,7 @@
1
+ import { BaseParser } from './base_parser';
2
+ import { FilterParserResponse } from './filter_types';
3
+ export declare class BooleanParser extends BaseParser {
4
+ constructor(input: string);
5
+ private tokenize;
6
+ parse(): FilterParserResponse;
7
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BooleanParser = void 0;
4
+ const tokenizer_1 = require("./tokenizer");
5
+ const base_parser_1 = require("./base_parser");
6
+ class BooleanParser extends base_parser_1.BaseParser {
7
+ constructor(input) {
8
+ super(input);
9
+ }
10
+ tokenize() {
11
+ const specialSubstrings = [{ type: ',', value: ',' }];
12
+ const specialWords = [
13
+ { type: 'NULL', value: 'null', ignoreCase: true },
14
+ { type: 'NOTNULL', value: '-null', ignoreCase: true },
15
+ { type: 'TRUE', value: 'true', ignoreCase: true },
16
+ { type: 'FALSE', value: 'false', ignoreCase: true },
17
+ ];
18
+ const params = {
19
+ trimWordWhitespace: true,
20
+ splitOnWhitespace: true,
21
+ specialSubstrings,
22
+ specialWords: specialWords,
23
+ };
24
+ const tokenizer = new tokenizer_1.Tokenizer(this.inputString, params);
25
+ this.tokens = tokenizer.parse();
26
+ this.tokens = tokenizer_1.Tokenizer.convertSpecialWords(this.tokens, specialWords);
27
+ }
28
+ parse() {
29
+ this.index = 0;
30
+ this.tokenize();
31
+ const clauses = [];
32
+ const errors = [];
33
+ while (this.index < this.tokens.length) {
34
+ const token = this.getNext();
35
+ if (token.type === ',') {
36
+ this.index++;
37
+ }
38
+ else if (token.type === 'NULL' ||
39
+ token.type === 'TRUE' ||
40
+ token.type === 'FALSE' ||
41
+ token.type === 'NOTNULL') {
42
+ const clause = { operator: token.type };
43
+ clauses.push(clause);
44
+ this.index++;
45
+ }
46
+ else {
47
+ errors.push({
48
+ message: 'Invalid token ' + token.value,
49
+ startIndex: token.startIndex,
50
+ endIndex: token.endIndex,
51
+ });
52
+ this.index++;
53
+ }
54
+ }
55
+ return { clauses, errors };
56
+ }
57
+ }
58
+ exports.BooleanParser = BooleanParser;
59
+ //# sourceMappingURL=boolean_parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boolean_parser.js","sourceRoot":"","sources":["../src/boolean_parser.ts"],"names":[],"mappings":";;;AAAA,2CAAqE;AAErE,+CAAyC;AAGzC,MAAa,aAAc,SAAQ,wBAAU;IAC3C,YAAY,KAAa;QACvB,KAAK,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;IAEO,QAAQ;QACd,MAAM,iBAAiB,GAAmB,CAAC,EAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAC,CAAC,CAAC;QACpE,MAAM,YAAY,GAAmB;YACnC,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAC;YAC/C,EAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAC;YACnD,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAC;YAC/C,EAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAC;SAClD,CAAC;QACF,MAAM,MAAM,GAAoB;YAC9B,kBAAkB,EAAE,IAAI;YACxB,iBAAiB,EAAE,IAAI;YACvB,iBAAiB;YACjB,YAAY,EAAE,YAAY;SAC3B,CAAC;QAEF,MAAM,SAAS,GAAG,IAAI,qBAAS,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,qBAAS,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACzE,CAAC;IAEM,KAAK;QACV,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,MAAM,OAAO,GAAoB,EAAE,CAAC;QACpC,MAAM,MAAM,GAAkB,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YACtC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,EAAE;gBACtB,IAAI,CAAC,KAAK,EAAE,CAAC;aACd;iBAAM,IACL,KAAK,CAAC,IAAI,KAAK,MAAM;gBACrB,KAAK,CAAC,IAAI,KAAK,MAAM;gBACrB,KAAK,CAAC,IAAI,KAAK,OAAO;gBACtB,KAAK,CAAC,IAAI,KAAK,SAAS,EACxB;gBACA,MAAM,MAAM,GAAkB,EAAC,QAAQ,EAAE,KAAK,CAAC,IAAuB,EAAC,CAAC;gBACxE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACrB,IAAI,CAAC,KAAK,EAAE,CAAC;aACd;iBAAM;gBACL,MAAM,CAAC,IAAI,CAAC;oBACV,OAAO,EAAE,gBAAgB,GAAG,KAAK,CAAC,KAAK;oBACvC,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;iBACzB,CAAC,CAAC;gBACH,IAAI,CAAC,KAAK,EAAE,CAAC;aACd;SACF;QACD,OAAO,EAAC,OAAO,EAAE,MAAM,EAAC,CAAC;IAC3B,CAAC;CACF;AAtDD,sCAsDC"}
@@ -0,0 +1,8 @@
1
+ import { Clause } from './clause_types';
2
+ import { BaseSerializer } from './base_serializer';
3
+ export declare class BooleanSerializer extends BaseSerializer {
4
+ constructor(clauses: Clause[]);
5
+ serialize(): string;
6
+ private static booleanClauseToString;
7
+ private static clauseToString;
8
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BooleanSerializer = void 0;
4
+ const base_serializer_1 = require("./base_serializer");
5
+ class BooleanSerializer extends base_serializer_1.BaseSerializer {
6
+ constructor(clauses) {
7
+ super(clauses);
8
+ }
9
+ serialize() {
10
+ const result = BooleanSerializer.clauseToString(this.clauses);
11
+ return result.trim().replace(/,$/, '');
12
+ }
13
+ static booleanClauseToString(clause) {
14
+ return clause.operator === 'NOTNULL' ? '-NULL' : clause.operator;
15
+ }
16
+ static clauseToString(clauses) {
17
+ let result = '';
18
+ for (const clause of clauses) {
19
+ if ('operator' in clause) {
20
+ result += BooleanSerializer.booleanClauseToString(clause);
21
+ }
22
+ else {
23
+ throw new Error('Invalid boolean clause ' + JSON.stringify(clause));
24
+ }
25
+ result += ', ';
26
+ }
27
+ return result;
28
+ }
29
+ }
30
+ exports.BooleanSerializer = BooleanSerializer;
31
+ //# sourceMappingURL=boolean_serializer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boolean_serializer.js","sourceRoot":"","sources":["../src/boolean_serializer.ts"],"names":[],"mappings":";;;AACA,uDAAiD;AAEjD,MAAa,iBAAkB,SAAQ,gCAAc;IACnD,YAAY,OAAiB;QAC3B,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;IAEM,SAAS;QACd,MAAM,MAAM,GAAG,iBAAiB,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC9D,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAAC,MAAqB;QACxD,OAAO,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IACnE,CAAC;IAEO,MAAM,CAAC,cAAc,CAAC,OAAiB;QAC7C,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;YAC5B,IAAI,UAAU,IAAI,MAAM,EAAE;gBACxB,MAAM,IAAI,iBAAiB,CAAC,qBAAqB,CAC/C,MAAuB,CACxB,CAAC;aACH;iBAAM;gBACL,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;aACrE;YACD,MAAM,IAAI,IAAI,CAAC;SAChB;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AA5BD,8CA4BC"}
@@ -0,0 +1,70 @@
1
+ export type NumberOperator = '<=' | '>=' | '!=' | '=' | '>' | '<';
2
+ export type NumberValue = number | null;
3
+ export interface NumberCondition {
4
+ operator: NumberOperator;
5
+ values: NumberValue[];
6
+ }
7
+ export type NumberRangeOperator = '<=' | '>=' | '>' | '<';
8
+ export interface NumberRange {
9
+ operator: 'range';
10
+ startOperator: NumberRangeOperator;
11
+ startValue: NumberValue;
12
+ endOperator: NumberRangeOperator;
13
+ endValue: NumberValue;
14
+ }
15
+ export type QuoteType = 'SINGLE' | 'DOUBLE' | 'BACKTICK' | 'TRIPLESINGLE' | 'TRIPLEDOUBLE' | 'ESCAPEDSINGLE' | 'ESCAPEDDOUBLE' | 'ESCAPEDBACKTICK';
16
+ export type StringOperator = 'EMPTY' | 'NOTEMPTY' | 'starts' | 'ends' | 'contains' | 'notStarts' | 'notEnds' | 'notContains' | '~' | '=' | '!~' | '!=';
17
+ export type StringValue = string | null;
18
+ export interface StringCondition {
19
+ operator: StringOperator;
20
+ values: StringValue[];
21
+ quotes?: QuoteType[];
22
+ }
23
+ export type BooleanOperator = 'TRUE' | 'FALSE' | 'NULL' | 'NOTNULL';
24
+ export interface BooleanClause {
25
+ operator: BooleanOperator;
26
+ }
27
+ export type DatePrefix = 'BEFORE' | 'AFTER';
28
+ export type DateTimeUnit = 'YEAR' | 'QUARTER' | 'MONTH' | 'WEEK' | 'DAY' | 'HOUR' | 'MINUTE' | 'SECOND';
29
+ export type DateWeekday = 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY' | 'SUNDAY';
30
+ export type DateMomentNowOperator = 'NOW' | 'TODAY' | 'YESTERDAY' | 'TOMORROW';
31
+ export interface DateMomentNow {
32
+ prefix?: DatePrefix;
33
+ operator: DateMomentNowOperator;
34
+ }
35
+ export type DateMomentIntervalOperator = 'LAST' | 'THIS' | 'NEXT';
36
+ export interface DateMomentInterval {
37
+ prefix?: DatePrefix;
38
+ operator: DateMomentIntervalOperator;
39
+ unit: DateTimeUnit | DateWeekday;
40
+ }
41
+ export type DateMomentNumberIntervalOperator = 'LASTN' | 'NEXTN' | 'AGO' | 'FROMNOW';
42
+ export interface DateMomentNumberInterval {
43
+ prefix?: DatePrefix;
44
+ operator: DateMomentNumberIntervalOperator;
45
+ unit: DateTimeUnit;
46
+ value: string;
47
+ }
48
+ export type DateMomentNumberUnitOperator = 'TIMEBLOCK';
49
+ export interface DateMomentNumberUnit {
50
+ prefix?: DatePrefix;
51
+ operator: DateMomentNumberUnitOperator;
52
+ unit: DateTimeUnit;
53
+ value: string;
54
+ }
55
+ export type DateMomentNumberOperator = 'DATE' | 'DATETIME';
56
+ export interface DateMomentNumber {
57
+ prefix?: DatePrefix;
58
+ operator: DateMomentNumberOperator;
59
+ date: string;
60
+ time?: string;
61
+ }
62
+ export type DateMoment = DateMomentNow | DateMomentInterval | DateMomentNumberInterval | DateMomentNumberUnit | DateMomentNumber;
63
+ export interface DateRange {
64
+ start: DateMoment;
65
+ operator: 'TO' | 'FOR';
66
+ end: DateMoment;
67
+ }
68
+ export type NumberClause = NumberCondition | NumberRange;
69
+ export type DateClause = DateMoment | DateRange;
70
+ export type Clause = NumberClause | StringCondition | BooleanClause | DateClause;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=clause_types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clause_types.js","sourceRoot":"","sources":["../src/clause_types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ import { BaseParser } from './base_parser';
2
+ import { FilterParserResponse } from './filter_types';
3
+ export declare class DateParser extends BaseParser {
4
+ private static readonly yearRegex;
5
+ private static readonly negatedStartRegex;
6
+ constructor(input: string);
7
+ private tokenize;
8
+ private mergeMomentTokens;
9
+ private matchAndMerge;
10
+ parse(): FilterParserResponse;
11
+ private static createMomentInterval;
12
+ private static createMomentNumberInterval;
13
+ private static createMomentNumberIntervalAgo;
14
+ private static createMomentNumberIntervalFromNow;
15
+ private static createMomentNumberUnit;
16
+ private static createMomentNumber;
17
+ private static createMomentNow;
18
+ private static createMomentFromToken;
19
+ private isMatchingToken;
20
+ private handleRange;
21
+ private handleMoment;
22
+ }