@nymphjs/query-parser 1.0.0-beta.10 → 1.0.0-beta.101
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/CHANGELOG.md +379 -0
- package/README.md +14 -6
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/queryParser.d.ts +15 -0
- package/dist/queryParser.js +788 -0
- package/dist/queryParser.js.map +1 -0
- package/dist/queryParser.test.d.ts +1 -0
- package/dist/queryParser.test.js +1183 -0
- package/dist/queryParser.test.js.map +1 -0
- package/jest.config.js +11 -2
- package/lib/queryParser.js +47 -14
- package/lib/queryParser.js.map +1 -1
- package/lib/queryParser.test.js +47 -1
- package/lib/queryParser.test.js.map +1 -1
- package/package.json +22 -29
- package/src/index.ts +2 -2
- package/src/queryParser.test.ts +371 -2
- package/src/queryParser.ts +153 -48
- package/tsconfig.json +6 -4
- package/typedoc.json +4 -0
- package/webpack.config.js +0 -28
package/src/queryParser.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { EntityConstructor, Options, Selector } from '@nymphjs/client';
|
|
2
|
-
import splitn from '@sciactive/splitn';
|
|
2
|
+
import { splitn } from '@sciactive/splitn';
|
|
3
3
|
|
|
4
4
|
export type BareQueryHandler = (
|
|
5
5
|
input: string,
|
|
6
6
|
entityClass?: EntityConstructor,
|
|
7
|
-
defaultFields?: string[]
|
|
7
|
+
defaultFields?: string[],
|
|
8
8
|
) => Partial<Selector>;
|
|
9
9
|
|
|
10
10
|
export type QRefMap = {
|
|
@@ -12,7 +12,7 @@ export type QRefMap = {
|
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
export default function queryParser<
|
|
15
|
-
T extends EntityConstructor = EntityConstructor
|
|
15
|
+
T extends EntityConstructor = EntityConstructor,
|
|
16
16
|
>({
|
|
17
17
|
query,
|
|
18
18
|
entityClass,
|
|
@@ -27,7 +27,7 @@ export default function queryParser<
|
|
|
27
27
|
type: '|',
|
|
28
28
|
ilike: defaultFields.map((field) => [field, input]) as [
|
|
29
29
|
string,
|
|
30
|
-
string
|
|
30
|
+
string,
|
|
31
31
|
][],
|
|
32
32
|
};
|
|
33
33
|
}
|
|
@@ -90,7 +90,8 @@ function selectorsParser({
|
|
|
90
90
|
} else if (inQuote) {
|
|
91
91
|
continue;
|
|
92
92
|
} else if (curQuery[i] === '(') {
|
|
93
|
-
|
|
93
|
+
const searchClause = i !== 0 && !curQuery[i - 1].match(/\s/);
|
|
94
|
+
if (currentStart == null && !searchClause) {
|
|
94
95
|
currentStart = i;
|
|
95
96
|
} else {
|
|
96
97
|
nesting++;
|
|
@@ -144,7 +145,7 @@ function selectorsParser({
|
|
|
144
145
|
defaultFields,
|
|
145
146
|
qrefMap,
|
|
146
147
|
bareHandler,
|
|
147
|
-
})
|
|
148
|
+
}),
|
|
148
149
|
);
|
|
149
150
|
}
|
|
150
151
|
}
|
|
@@ -171,6 +172,16 @@ function selectorsParser({
|
|
|
171
172
|
}
|
|
172
173
|
curQuery = curQuery.replace(offsetRegex, '');
|
|
173
174
|
|
|
175
|
+
// JavaScript variable names are ridiculously infeasable to check
|
|
176
|
+
// thoroughly, so this is a "best attempt".
|
|
177
|
+
const sortRegex =
|
|
178
|
+
/(?: |^)sort:([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)(?= |$)/;
|
|
179
|
+
const sortMatch = curQuery.match(sortRegex);
|
|
180
|
+
if (sortMatch) {
|
|
181
|
+
options.sort = sortMatch[1];
|
|
182
|
+
}
|
|
183
|
+
curQuery = curQuery.replace(sortRegex, '');
|
|
184
|
+
|
|
174
185
|
const reverseRegex = /(?: |^)reverse:(true|false|1|0)(?= |$)/;
|
|
175
186
|
const reverseMatch = curQuery.match(reverseRegex);
|
|
176
187
|
if (reverseMatch) {
|
|
@@ -222,8 +233,35 @@ function selectorParser({
|
|
|
222
233
|
}): string {
|
|
223
234
|
let curQuery = query;
|
|
224
235
|
|
|
236
|
+
// eg. prop(some search string) or prop!(some search string)
|
|
237
|
+
const searchRegex = /(?: |^)([^\s=\[\]<>{}]+?)!?\([^\)]+\)(?= |$)/g;
|
|
238
|
+
const searchMatch = curQuery.match(searchRegex);
|
|
239
|
+
if (searchMatch) {
|
|
240
|
+
selector.search = [];
|
|
241
|
+
selector['!search'] = [];
|
|
242
|
+
for (let match of searchMatch) {
|
|
243
|
+
try {
|
|
244
|
+
let [name, value] = splitn(match.trim().slice(0, -1), '(', 2);
|
|
245
|
+
if (name.endsWith('!')) {
|
|
246
|
+
selector['!search'].push([name.slice(0, -1), value]);
|
|
247
|
+
} else {
|
|
248
|
+
selector.search.push([name, value]);
|
|
249
|
+
}
|
|
250
|
+
} catch (e: any) {
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (!selector.search.length) {
|
|
255
|
+
delete selector.search;
|
|
256
|
+
}
|
|
257
|
+
if (!selector['!search'].length) {
|
|
258
|
+
delete selector['!search'];
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
curQuery = curQuery.replace(searchRegex, '');
|
|
262
|
+
|
|
225
263
|
// eg. user<{User name="Hunter"}> or user!<{User name="Hunter"}>
|
|
226
|
-
const qrefRegex = /(?: |^)(\
|
|
264
|
+
const qrefRegex = /(?: |^)([^\s=\[\]<>{}]+?)!?<\{(\w+) (.*?[^\\])\}>(?= |$)/g;
|
|
227
265
|
const qrefMatch = curQuery.match(qrefRegex);
|
|
228
266
|
if (qrefMatch) {
|
|
229
267
|
selector.qref = [];
|
|
@@ -232,7 +270,7 @@ function selectorParser({
|
|
|
232
270
|
try {
|
|
233
271
|
let [name, value] = splitn(match.trim().slice(0, -1), '<', 2);
|
|
234
272
|
value = unQuoteCurlies(value.slice(1, -1));
|
|
235
|
-
let [className, qrefQuery] = value
|
|
273
|
+
let [className, qrefQuery] = splitn(value, ' ', 2);
|
|
236
274
|
const EntityClass = qrefMap[className].class;
|
|
237
275
|
if (EntityClass == null) {
|
|
238
276
|
continue;
|
|
@@ -262,50 +300,114 @@ function selectorParser({
|
|
|
262
300
|
}
|
|
263
301
|
curQuery = curQuery.replace(qrefRegex, '');
|
|
264
302
|
|
|
265
|
-
// eg.
|
|
266
|
-
const
|
|
303
|
+
// eg. someArray=[1,2] or someObject={"prop":"some value"}
|
|
304
|
+
const equalJsonRegex = /(?: |^)([^\s=\[\]<>{}]+?)!?=(\{|\[)/g;
|
|
305
|
+
const equalJsonMatch = [...curQuery.matchAll(equalJsonRegex)];
|
|
306
|
+
if (equalJsonMatch) {
|
|
307
|
+
if (!('equal' in selector)) {
|
|
308
|
+
selector.equal = [];
|
|
309
|
+
}
|
|
310
|
+
if (!('!equal' in selector)) {
|
|
311
|
+
selector['!equal'] = [];
|
|
312
|
+
}
|
|
313
|
+
// Work backward to find all long JSON values.
|
|
314
|
+
for (let i = equalJsonMatch.length - 1; i >= 0; i--) {
|
|
315
|
+
const match = equalJsonMatch[i];
|
|
316
|
+
let [name, opener] = splitn(match[0].trim(), '=', 2);
|
|
317
|
+
let start = match.index + match[0].length - 1;
|
|
318
|
+
let nextEndToken = curQuery.indexOf(opener === '{' ? '}' : ']', start);
|
|
319
|
+
while (nextEndToken !== -1) {
|
|
320
|
+
try {
|
|
321
|
+
if (name.endsWith('!')) {
|
|
322
|
+
(selector['!equal'] as [string, any][]).unshift([
|
|
323
|
+
name.slice(0, -1),
|
|
324
|
+
JSON.parse(curQuery.substring(start, nextEndToken + 1)),
|
|
325
|
+
]);
|
|
326
|
+
} else {
|
|
327
|
+
(selector.equal as [string, any][]).unshift([
|
|
328
|
+
name,
|
|
329
|
+
JSON.parse(curQuery.substring(start, nextEndToken + 1)),
|
|
330
|
+
]);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
curQuery =
|
|
334
|
+
curQuery.substring(0, match.index) +
|
|
335
|
+
curQuery.substring(nextEndToken + 1);
|
|
336
|
+
break;
|
|
337
|
+
} catch (e: any) {
|
|
338
|
+
nextEndToken = curQuery.indexOf(
|
|
339
|
+
opener === '{' ? '}' : ']',
|
|
340
|
+
nextEndToken + 1,
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
if (selector.equal == null || !selector.equal.length) {
|
|
346
|
+
delete selector.equal;
|
|
347
|
+
}
|
|
348
|
+
if (selector['!equal'] == null || !selector['!equal'].length) {
|
|
349
|
+
delete selector['!equal'];
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// eg. name=Marty or name="Marty McFly" or enabled=true
|
|
354
|
+
const equalRegex =
|
|
355
|
+
/(?: |^)([^\s=\[\]<>{}]+?)!?=(""|".*?[^\\]"|[^ ]+)(?= |$)/g;
|
|
267
356
|
const equalMatch = curQuery.match(equalRegex);
|
|
268
357
|
if (equalMatch) {
|
|
269
|
-
|
|
270
|
-
|
|
358
|
+
if (!('equal' in selector)) {
|
|
359
|
+
selector.equal = [];
|
|
360
|
+
}
|
|
361
|
+
if (!('!equal' in selector)) {
|
|
362
|
+
selector['!equal'] = [];
|
|
363
|
+
}
|
|
271
364
|
for (let match of equalMatch) {
|
|
272
365
|
try {
|
|
273
|
-
let [name, value] = match.trim()
|
|
366
|
+
let [name, value] = splitn(match.trim(), '=', 2);
|
|
274
367
|
try {
|
|
275
368
|
if (name.endsWith('!')) {
|
|
276
|
-
selector['!equal']
|
|
369
|
+
(selector['!equal'] as [string, any][]).push([
|
|
370
|
+
name.slice(0, -1),
|
|
371
|
+
JSON.parse(value),
|
|
372
|
+
]);
|
|
277
373
|
} else {
|
|
278
|
-
selector.equal.push([name, JSON.parse(value)]);
|
|
374
|
+
(selector.equal as [string, any][]).push([name, JSON.parse(value)]);
|
|
279
375
|
}
|
|
280
376
|
} catch (e: any) {
|
|
281
377
|
if (name.endsWith('!')) {
|
|
282
|
-
selector['!equal']
|
|
378
|
+
(selector['!equal'] as [string, any][]).push([
|
|
379
|
+
name.slice(0, -1),
|
|
380
|
+
unQuoteString(value),
|
|
381
|
+
]);
|
|
283
382
|
} else {
|
|
284
|
-
selector.equal
|
|
383
|
+
(selector.equal as [string, any][]).push([
|
|
384
|
+
name,
|
|
385
|
+
unQuoteString(value),
|
|
386
|
+
]);
|
|
285
387
|
}
|
|
286
388
|
}
|
|
287
389
|
} catch (e: any) {
|
|
288
390
|
continue;
|
|
289
391
|
}
|
|
290
392
|
}
|
|
291
|
-
if (!selector.equal.length) {
|
|
393
|
+
if (selector.equal == null || !selector.equal.length) {
|
|
292
394
|
delete selector.equal;
|
|
293
395
|
}
|
|
294
|
-
if (!selector['!equal'].length) {
|
|
396
|
+
if (selector['!equal'] == null || !selector['!equal'].length) {
|
|
295
397
|
delete selector['!equal'];
|
|
296
398
|
}
|
|
297
399
|
}
|
|
298
400
|
curQuery = curQuery.replace(equalRegex, '');
|
|
299
401
|
|
|
300
402
|
// eg. user<{790274347f9b3a018c2cedee}> or user!<{790274347f9b3a018c2cedee}>
|
|
301
|
-
const refRegex = /(?: |^)(\
|
|
403
|
+
const refRegex = /(?: |^)([^\s=\[\]<>{}]+?)!?<\{([0-9a-f]{24})\}>(?= |$)/g;
|
|
302
404
|
const refMatch = curQuery.match(refRegex);
|
|
303
405
|
if (refMatch) {
|
|
304
406
|
selector.ref = [];
|
|
305
407
|
selector['!ref'] = [];
|
|
306
408
|
for (let match of refMatch) {
|
|
307
409
|
try {
|
|
308
|
-
let [name, value] = match.trim().slice(0, -1)
|
|
410
|
+
let [name, value] = splitn(match.trim().slice(0, -1), '<', 2);
|
|
309
411
|
if (name.endsWith('!')) {
|
|
310
412
|
selector['!ref'].push([name.slice(0, -1), value.slice(1, -1)]);
|
|
311
413
|
} else {
|
|
@@ -325,31 +427,32 @@ function selectorParser({
|
|
|
325
427
|
curQuery = curQuery.replace(refRegex, '');
|
|
326
428
|
|
|
327
429
|
// eg. someArrayOfNumbers<10> or someObject!<"some string">
|
|
328
|
-
const containRegex =
|
|
430
|
+
const containRegex =
|
|
431
|
+
/(?: |^)([^\s=\[\]<>{}]+?)!?(<(?:[^"][^>]*?|".*?[^\\]"))>(?= |$)/g;
|
|
329
432
|
const containMatch = curQuery.match(containRegex);
|
|
330
433
|
if (containMatch) {
|
|
331
434
|
selector.contain = [];
|
|
332
435
|
selector['!contain'] = [];
|
|
333
436
|
for (let match of containMatch) {
|
|
334
437
|
try {
|
|
335
|
-
let [name, value] = match.trim().slice(0, -1)
|
|
438
|
+
let [name, value] = splitn(match.trim().slice(0, -1), '<', 2);
|
|
336
439
|
try {
|
|
337
440
|
if (name.endsWith('!')) {
|
|
338
441
|
selector['!contain'].push([
|
|
339
442
|
name.slice(0, -1),
|
|
340
|
-
JSON.parse(
|
|
443
|
+
JSON.parse(unQuoteString(value)),
|
|
341
444
|
]);
|
|
342
445
|
} else {
|
|
343
|
-
selector.contain.push([name, JSON.parse(
|
|
446
|
+
selector.contain.push([name, JSON.parse(unQuoteString(value))]);
|
|
344
447
|
}
|
|
345
448
|
} catch (e: any) {
|
|
346
449
|
if (name.endsWith('!')) {
|
|
347
450
|
selector['!contain'].push([
|
|
348
451
|
name.slice(0, -1),
|
|
349
|
-
|
|
452
|
+
unQuoteString(value),
|
|
350
453
|
]);
|
|
351
454
|
} else {
|
|
352
|
-
selector.contain.push([name,
|
|
455
|
+
selector.contain.push([name, unQuoteString(value)]);
|
|
353
456
|
}
|
|
354
457
|
}
|
|
355
458
|
} catch (e: any) {
|
|
@@ -366,7 +469,8 @@ function selectorParser({
|
|
|
366
469
|
curQuery = curQuery.replace(containRegex, '');
|
|
367
470
|
|
|
368
471
|
// eg. name~/Hunter/ or name!~/hunter/i
|
|
369
|
-
const posixRegex =
|
|
472
|
+
const posixRegex =
|
|
473
|
+
/(?: |^)([^\s=\[\]<>{}]+?)!?~(\/\/|\/.*?[^\\]\/)i?(?= |$)/g;
|
|
370
474
|
const posixMatch = curQuery.match(posixRegex);
|
|
371
475
|
if (posixMatch) {
|
|
372
476
|
selector.match = [];
|
|
@@ -375,7 +479,7 @@ function selectorParser({
|
|
|
375
479
|
selector['!imatch'] = [];
|
|
376
480
|
for (let match of posixMatch) {
|
|
377
481
|
try {
|
|
378
|
-
let [name, value] = match.trim()
|
|
482
|
+
let [name, value] = splitn(match.trim(), '~', 2);
|
|
379
483
|
if (name.endsWith('!')) {
|
|
380
484
|
if (value.endsWith('i')) {
|
|
381
485
|
selector['!imatch'].push([
|
|
@@ -415,7 +519,8 @@ function selectorParser({
|
|
|
415
519
|
curQuery = curQuery.replace(posixRegex, '');
|
|
416
520
|
|
|
417
521
|
// eg. name~Hunter or name!~"hunter"i
|
|
418
|
-
const likeRegex =
|
|
522
|
+
const likeRegex =
|
|
523
|
+
/(?: |^)([^\s=\[\]<>{}]+?)!?~(""i?|".*?[^\\]"i?|[^ ]+)(?= |$)/g;
|
|
419
524
|
const likeMatch = curQuery.match(likeRegex);
|
|
420
525
|
if (likeMatch) {
|
|
421
526
|
selector.like = [];
|
|
@@ -424,7 +529,7 @@ function selectorParser({
|
|
|
424
529
|
selector['!ilike'] = [];
|
|
425
530
|
for (let match of likeMatch) {
|
|
426
531
|
try {
|
|
427
|
-
let [name, value] = match.trim()
|
|
532
|
+
let [name, value] = splitn(match.trim(), '~', 2);
|
|
428
533
|
if (name.endsWith('!')) {
|
|
429
534
|
if (value.endsWith('"i')) {
|
|
430
535
|
selector['!ilike'].push([
|
|
@@ -488,7 +593,7 @@ function selectorParser({
|
|
|
488
593
|
curQuery = curQuery.replace(guidRegex, '');
|
|
489
594
|
|
|
490
595
|
// eg. [enabled] or [!defaultPrimaryGroup]
|
|
491
|
-
const truthyRegex = /(?: |^)\[(
|
|
596
|
+
const truthyRegex = /(?: |^)\[(!?[^\s=\[\]<>{}]+?)\](?= |$)/g;
|
|
492
597
|
const truthyMatch = curQuery.match(truthyRegex);
|
|
493
598
|
if (truthyMatch) {
|
|
494
599
|
selector.truthy = [];
|
|
@@ -542,13 +647,13 @@ function selectorParser({
|
|
|
542
647
|
curQuery = curQuery.replace(tagRegex, '');
|
|
543
648
|
|
|
544
649
|
// eg. cdate>15
|
|
545
|
-
const gtRegex = /(?: |^)(\
|
|
650
|
+
const gtRegex = /(?: |^)([^\s=\[\]<>{}]+?)>(-?\d+(?:\.\d+)?)(?= |$)/g;
|
|
546
651
|
const gtMatch = curQuery.match(gtRegex);
|
|
547
652
|
if (gtMatch) {
|
|
548
653
|
selector.gt = [];
|
|
549
654
|
for (let match of gtMatch) {
|
|
550
655
|
try {
|
|
551
|
-
let [name, value] = match.trim()
|
|
656
|
+
let [name, value] = splitn(match.trim(), '>', 2);
|
|
552
657
|
selector.gt.push([name, Number(value)]);
|
|
553
658
|
} catch (e: any) {
|
|
554
659
|
continue;
|
|
@@ -561,7 +666,7 @@ function selectorParser({
|
|
|
561
666
|
curQuery = curQuery.replace(gtRegex, '');
|
|
562
667
|
|
|
563
668
|
// eg. cdate>yesterday or cdate>"2 days ago"
|
|
564
|
-
const gtRelativeRegex = /(?: |^)(\
|
|
669
|
+
const gtRelativeRegex = /(?: |^)([^\s=\[\]<>{}]+?)>(\w+|"[^"]+")(?= |$)/g;
|
|
565
670
|
const gtRelativeMatch = curQuery.match(gtRelativeRegex);
|
|
566
671
|
if (gtRelativeMatch) {
|
|
567
672
|
if (selector.gt == null) {
|
|
@@ -569,7 +674,7 @@ function selectorParser({
|
|
|
569
674
|
}
|
|
570
675
|
for (let match of gtRelativeMatch) {
|
|
571
676
|
try {
|
|
572
|
-
let [name, value] = match.trim()
|
|
677
|
+
let [name, value] = splitn(match.trim(), '>', 2);
|
|
573
678
|
(selector.gt as [string, null, string][]).push([
|
|
574
679
|
name,
|
|
575
680
|
null,
|
|
@@ -586,13 +691,13 @@ function selectorParser({
|
|
|
586
691
|
curQuery = curQuery.replace(gtRelativeRegex, '');
|
|
587
692
|
|
|
588
693
|
// eg. cdate>=15
|
|
589
|
-
const gteRegex = /(?: |^)(\
|
|
694
|
+
const gteRegex = /(?: |^)([^\s=\[\]<>{}]+?)>=(-?\d+(?:\.\d+)?)(?= |$)/g;
|
|
590
695
|
const gteMatch = curQuery.match(gteRegex);
|
|
591
696
|
if (gteMatch) {
|
|
592
697
|
selector.gte = [];
|
|
593
698
|
for (let match of gteMatch) {
|
|
594
699
|
try {
|
|
595
|
-
let [name, value] = match.trim()
|
|
700
|
+
let [name, value] = splitn(match.trim(), '>=', 2);
|
|
596
701
|
selector.gte.push([name, Number(value)]);
|
|
597
702
|
} catch (e: any) {
|
|
598
703
|
continue;
|
|
@@ -605,7 +710,7 @@ function selectorParser({
|
|
|
605
710
|
curQuery = curQuery.replace(gteRegex, '');
|
|
606
711
|
|
|
607
712
|
// eg. cdate>=yesterday or cdate>="2 days ago"
|
|
608
|
-
const gteRelativeRegex = /(?: |^)(\
|
|
713
|
+
const gteRelativeRegex = /(?: |^)([^\s=\[\]<>{}]+?)>=(\w+|"[^"]+")(?= |$)/g;
|
|
609
714
|
const gteRelativeMatch = curQuery.match(gteRelativeRegex);
|
|
610
715
|
if (gteRelativeMatch) {
|
|
611
716
|
if (selector.gte == null) {
|
|
@@ -613,7 +718,7 @@ function selectorParser({
|
|
|
613
718
|
}
|
|
614
719
|
for (let match of gteRelativeMatch) {
|
|
615
720
|
try {
|
|
616
|
-
let [name, value] = match.trim()
|
|
721
|
+
let [name, value] = splitn(match.trim(), '>=', 2);
|
|
617
722
|
(selector.gte as [string, null, string][]).push([
|
|
618
723
|
name,
|
|
619
724
|
null,
|
|
@@ -630,13 +735,13 @@ function selectorParser({
|
|
|
630
735
|
curQuery = curQuery.replace(gteRelativeRegex, '');
|
|
631
736
|
|
|
632
737
|
// eg. cdate<15
|
|
633
|
-
const ltRegex = /(?: |^)(\
|
|
738
|
+
const ltRegex = /(?: |^)([^\s=\[\]<>{}]+?)<(-?\d+(?:\.\d+)?)(?= |$)/g;
|
|
634
739
|
const ltMatch = curQuery.match(ltRegex);
|
|
635
740
|
if (ltMatch) {
|
|
636
741
|
selector.lt = [];
|
|
637
742
|
for (let match of ltMatch) {
|
|
638
743
|
try {
|
|
639
|
-
let [name, value] = match.trim()
|
|
744
|
+
let [name, value] = splitn(match.trim(), '<', 2);
|
|
640
745
|
selector.lt.push([name, Number(value)]);
|
|
641
746
|
} catch (e: any) {
|
|
642
747
|
continue;
|
|
@@ -649,7 +754,7 @@ function selectorParser({
|
|
|
649
754
|
curQuery = curQuery.replace(ltRegex, '');
|
|
650
755
|
|
|
651
756
|
// eg. cdate<yesterday or cdate<"2 days ago"
|
|
652
|
-
const ltRelativeRegex = /(?: |^)(\
|
|
757
|
+
const ltRelativeRegex = /(?: |^)([^\s=\[\]<>{}]+?)<(\w+|"[^"]+")(?= |$)/g;
|
|
653
758
|
const ltRelativeMatch = curQuery.match(ltRelativeRegex);
|
|
654
759
|
if (ltRelativeMatch) {
|
|
655
760
|
if (selector.lt == null) {
|
|
@@ -657,7 +762,7 @@ function selectorParser({
|
|
|
657
762
|
}
|
|
658
763
|
for (let match of ltRelativeMatch) {
|
|
659
764
|
try {
|
|
660
|
-
let [name, value] = match.trim()
|
|
765
|
+
let [name, value] = splitn(match.trim(), '<', 2);
|
|
661
766
|
(selector.lt as [string, null, string][]).push([
|
|
662
767
|
name,
|
|
663
768
|
null,
|
|
@@ -674,13 +779,13 @@ function selectorParser({
|
|
|
674
779
|
curQuery = curQuery.replace(ltRelativeRegex, '');
|
|
675
780
|
|
|
676
781
|
// eg. cdate<=15
|
|
677
|
-
const lteRegex = /(?: |^)(\
|
|
782
|
+
const lteRegex = /(?: |^)([^\s=\[\]<>{}]+?)<=(-?\d+(?:\.\d+)?)(?= |$)/g;
|
|
678
783
|
const lteMatch = curQuery.match(lteRegex);
|
|
679
784
|
if (lteMatch) {
|
|
680
785
|
selector.lte = [];
|
|
681
786
|
for (let match of lteMatch) {
|
|
682
787
|
try {
|
|
683
|
-
let [name, value] = match.trim()
|
|
788
|
+
let [name, value] = splitn(match.trim(), '<=', 2);
|
|
684
789
|
selector.lte.push([name, Number(value)]);
|
|
685
790
|
} catch (e: any) {
|
|
686
791
|
continue;
|
|
@@ -693,7 +798,7 @@ function selectorParser({
|
|
|
693
798
|
curQuery = curQuery.replace(lteRegex, '');
|
|
694
799
|
|
|
695
800
|
// eg. cdate<=yesterday or cdate<="2 days ago"
|
|
696
|
-
const lteRelativeRegex = /(?: |^)(\
|
|
801
|
+
const lteRelativeRegex = /(?: |^)([^\s=\[\]<>{}]+?)<=(\w+|"[^"]+")(?= |$)/g;
|
|
697
802
|
const lteRelativeMatch = curQuery.match(lteRelativeRegex);
|
|
698
803
|
if (lteRelativeMatch) {
|
|
699
804
|
if (selector.lte == null) {
|
|
@@ -701,7 +806,7 @@ function selectorParser({
|
|
|
701
806
|
}
|
|
702
807
|
for (let match of lteRelativeMatch) {
|
|
703
808
|
try {
|
|
704
|
-
let [name, value] = match.trim()
|
|
809
|
+
let [name, value] = splitn(match.trim(), '<=', 2);
|
|
705
810
|
(selector.lte as [string, null, string][]).push([
|
|
706
811
|
name,
|
|
707
812
|
null,
|
package/tsconfig.json
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
"extends": "@tsconfig/recommended/tsconfig.json",
|
|
3
3
|
|
|
4
4
|
"compilerOptions": {
|
|
5
|
-
"
|
|
6
|
-
"
|
|
5
|
+
"module": "ES2022",
|
|
6
|
+
"moduleResolution": "node",
|
|
7
|
+
"lib": ["DOM", "ES2022"],
|
|
8
|
+
"target": "ES2022",
|
|
7
9
|
"noImplicitAny": true,
|
|
8
|
-
"removeComments":
|
|
10
|
+
"removeComments": false,
|
|
9
11
|
"sourceMap": true,
|
|
10
|
-
"outDir": "
|
|
12
|
+
"outDir": "dist",
|
|
11
13
|
"resolveJsonModule": true,
|
|
12
14
|
"rootDir": "src/",
|
|
13
15
|
"declaration": true
|
package/typedoc.json
ADDED
package/webpack.config.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
mode: 'production',
|
|
5
|
-
devtool: 'source-map',
|
|
6
|
-
entry: {
|
|
7
|
-
NymphClient: './lib/index.js',
|
|
8
|
-
},
|
|
9
|
-
output: {
|
|
10
|
-
path: path.resolve(__dirname, 'dist'),
|
|
11
|
-
filename: 'index.js',
|
|
12
|
-
library: ['@nymphjs/client'],
|
|
13
|
-
libraryTarget: 'umd',
|
|
14
|
-
globalObject: 'this',
|
|
15
|
-
},
|
|
16
|
-
resolve: {
|
|
17
|
-
extensions: ['.tsx', '.ts', '.js'],
|
|
18
|
-
},
|
|
19
|
-
module: {
|
|
20
|
-
rules: [
|
|
21
|
-
{
|
|
22
|
-
test: /\.tsx?$/,
|
|
23
|
-
use: 'ts-loader',
|
|
24
|
-
exclude: /node_modules/,
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
},
|
|
28
|
-
};
|