search-input-query-parser 0.2.1 → 0.3.0
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/dist/cjs/first-pass-parser.js +1 -1
- package/dist/cjs/lexer.js +3 -3
- package/dist/cjs/parse-in-values.js +4 -4
- package/dist/cjs/parse-primary.js +4 -4
- package/dist/cjs/parser.js +1 -1
- package/dist/cjs/validate-expression-fields.js +15 -15
- package/dist/cjs/validate-in-expression.js +3 -3
- package/dist/cjs/validate-string.js +5 -5
- package/dist/cjs/validate-wildcard.js +3 -3
- package/dist/cjs/validator.js +27 -27
- package/dist/esm/first-pass-parser.js +1 -1
- package/dist/esm/lexer.js +3 -3
- package/dist/esm/parse-in-values.js +4 -4
- package/dist/esm/parse-primary.js +4 -4
- package/dist/esm/parser.js +1 -1
- package/dist/esm/validate-expression-fields.js +15 -15
- package/dist/esm/validate-in-expression.js +3 -3
- package/dist/esm/validate-string.js +5 -5
- package/dist/esm/validate-wildcard.js +3 -3
- package/dist/esm/validator.js +27 -27
- package/dist/types/validator.d.ts +27 -27
- package/package.json +1 -1
- package/src/first-pass-parser.ts +1 -2
- package/src/lexer.ts +3 -3
- package/src/parse-in-values.ts +4 -4
- package/src/parse-primary.ts +4 -4
- package/src/parser.test.ts +67 -67
- package/src/parser.ts +1 -1
- package/src/validate-expression-fields.ts +15 -15
- package/src/validate-in-expression.ts +3 -3
- package/src/validate-string.ts +5 -5
- package/src/validate-wildcard.ts +3 -3
- package/src/validator.test.ts +15 -15
- package/src/validator.ts +27 -27
package/src/parser.test.ts
CHANGED
|
@@ -104,48 +104,48 @@ describe("Search Query Parser", () => {
|
|
|
104
104
|
{
|
|
105
105
|
length: 6,
|
|
106
106
|
message: "Expected field value",
|
|
107
|
-
code: SearchQueryErrorCode.
|
|
107
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_VALUE_MISSING,
|
|
108
108
|
position: 0,
|
|
109
109
|
},
|
|
110
110
|
]);
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
testErrorQuery("field: value", [
|
|
113
113
|
{
|
|
114
114
|
length: 6,
|
|
115
115
|
message: "Expected field value",
|
|
116
|
-
code: SearchQueryErrorCode.
|
|
116
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_VALUE_MISSING,
|
|
117
117
|
position: 0,
|
|
118
118
|
},
|
|
119
119
|
]);
|
|
120
|
-
|
|
120
|
+
|
|
121
121
|
testErrorQuery("field : value", [
|
|
122
122
|
{
|
|
123
123
|
length: 1,
|
|
124
124
|
message: "Expected field value",
|
|
125
|
-
code: SearchQueryErrorCode.
|
|
125
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_VALUE_MISSING,
|
|
126
126
|
position: 6,
|
|
127
127
|
},
|
|
128
128
|
]);
|
|
129
129
|
testValidQuery('field:"quoted value"', "field:quoted value");
|
|
130
|
-
|
|
130
|
+
|
|
131
131
|
testErrorQuery('field: "quoted value"', [
|
|
132
132
|
{
|
|
133
133
|
length: 6,
|
|
134
134
|
message: "Expected field value",
|
|
135
|
-
code: SearchQueryErrorCode.
|
|
135
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_VALUE_MISSING,
|
|
136
136
|
position: 0,
|
|
137
137
|
},
|
|
138
138
|
]);
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
testErrorQuery('field :"quoted value"', [
|
|
141
141
|
{
|
|
142
142
|
length: 15,
|
|
143
143
|
message: "Missing field name",
|
|
144
|
-
code: SearchQueryErrorCode.
|
|
144
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_NAME_MISSING,
|
|
145
145
|
position: 6,
|
|
146
146
|
},
|
|
147
147
|
]);
|
|
148
|
-
})
|
|
148
|
+
});;
|
|
149
149
|
|
|
150
150
|
test("handles special characters in field values", () => {
|
|
151
151
|
testValidQuery('brand:"Nike\\Air"', "brand:Nike\\Air");
|
|
@@ -443,7 +443,7 @@ describe("Search Query Parser", () => {
|
|
|
443
443
|
{
|
|
444
444
|
length: 6,
|
|
445
445
|
message: "Expected field value",
|
|
446
|
-
code: SearchQueryErrorCode.
|
|
446
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_VALUE_MISSING,
|
|
447
447
|
position: 0,
|
|
448
448
|
},
|
|
449
449
|
]);
|
|
@@ -451,7 +451,7 @@ describe("Search Query Parser", () => {
|
|
|
451
451
|
{
|
|
452
452
|
length: 6,
|
|
453
453
|
message: "Missing field name",
|
|
454
|
-
code: SearchQueryErrorCode.
|
|
454
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_NAME_MISSING,
|
|
455
455
|
position: 0,
|
|
456
456
|
},
|
|
457
457
|
]);
|
|
@@ -459,7 +459,7 @@ describe("Search Query Parser", () => {
|
|
|
459
459
|
{
|
|
460
460
|
length: 1,
|
|
461
461
|
message: "Expected field value",
|
|
462
|
-
code: SearchQueryErrorCode.
|
|
462
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_VALUE_MISSING,
|
|
463
463
|
position: 0,
|
|
464
464
|
},
|
|
465
465
|
]);
|
|
@@ -467,13 +467,13 @@ describe("Search Query Parser", () => {
|
|
|
467
467
|
{
|
|
468
468
|
length: 6,
|
|
469
469
|
message: "Expected field value",
|
|
470
|
-
code: SearchQueryErrorCode.
|
|
470
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_VALUE_MISSING,
|
|
471
471
|
position: 0,
|
|
472
472
|
},
|
|
473
473
|
{
|
|
474
474
|
length: 1,
|
|
475
475
|
message: "Expected field value",
|
|
476
|
-
code: SearchQueryErrorCode.
|
|
476
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_VALUE_MISSING,
|
|
477
477
|
position: 6,
|
|
478
478
|
},
|
|
479
479
|
]);
|
|
@@ -484,7 +484,7 @@ describe("Search Query Parser", () => {
|
|
|
484
484
|
{
|
|
485
485
|
length: 3,
|
|
486
486
|
message: "AND is a reserved word",
|
|
487
|
-
code: SearchQueryErrorCode.
|
|
487
|
+
code: SearchQueryErrorCode.FIELD_NAME_RESERVED,
|
|
488
488
|
value: "AND",
|
|
489
489
|
position: 0,
|
|
490
490
|
},
|
|
@@ -493,7 +493,7 @@ describe("Search Query Parser", () => {
|
|
|
493
493
|
{
|
|
494
494
|
length: 2,
|
|
495
495
|
message: "OR is a reserved word",
|
|
496
|
-
code: SearchQueryErrorCode.
|
|
496
|
+
code: SearchQueryErrorCode.FIELD_NAME_RESERVED,
|
|
497
497
|
value: "OR",
|
|
498
498
|
position: 0,
|
|
499
499
|
},
|
|
@@ -505,7 +505,7 @@ describe("Search Query Parser", () => {
|
|
|
505
505
|
{
|
|
506
506
|
length: 1,
|
|
507
507
|
message: 'Unexpected ")"',
|
|
508
|
-
code: SearchQueryErrorCode.
|
|
508
|
+
code: SearchQueryErrorCode.SYNTAX_PARENTHESIS_UNEXPECTED,
|
|
509
509
|
position: 1,
|
|
510
510
|
},
|
|
511
511
|
]);
|
|
@@ -513,7 +513,7 @@ describe("Search Query Parser", () => {
|
|
|
513
513
|
{
|
|
514
514
|
length: 1,
|
|
515
515
|
message: 'Unexpected ")"',
|
|
516
|
-
code: SearchQueryErrorCode.
|
|
516
|
+
code: SearchQueryErrorCode.SYNTAX_PARENTHESIS_UNEXPECTED,
|
|
517
517
|
position: 6,
|
|
518
518
|
},
|
|
519
519
|
]);
|
|
@@ -524,7 +524,7 @@ describe("Search Query Parser", () => {
|
|
|
524
524
|
{
|
|
525
525
|
length: 6,
|
|
526
526
|
message: "Unterminated quoted string",
|
|
527
|
-
code: SearchQueryErrorCode.
|
|
527
|
+
code: SearchQueryErrorCode.SYNTAX_QUOTE_UNTERMINATED,
|
|
528
528
|
position: 6,
|
|
529
529
|
},
|
|
530
530
|
]);
|
|
@@ -532,7 +532,7 @@ describe("Search Query Parser", () => {
|
|
|
532
532
|
{
|
|
533
533
|
length: 7,
|
|
534
534
|
message: "Unterminated quoted string",
|
|
535
|
-
code: SearchQueryErrorCode.
|
|
535
|
+
code: SearchQueryErrorCode.SYNTAX_QUOTE_UNTERMINATED,
|
|
536
536
|
position: 6,
|
|
537
537
|
},
|
|
538
538
|
]);
|
|
@@ -540,7 +540,7 @@ describe("Search Query Parser", () => {
|
|
|
540
540
|
{
|
|
541
541
|
length: 8,
|
|
542
542
|
message: "Unterminated quoted string",
|
|
543
|
-
code: SearchQueryErrorCode.
|
|
543
|
+
code: SearchQueryErrorCode.SYNTAX_QUOTE_UNTERMINATED,
|
|
544
544
|
position: 6,
|
|
545
545
|
},
|
|
546
546
|
]);
|
|
@@ -548,7 +548,7 @@ describe("Search Query Parser", () => {
|
|
|
548
548
|
{
|
|
549
549
|
length: 16,
|
|
550
550
|
message: "Unterminated quoted string",
|
|
551
|
-
code: SearchQueryErrorCode.
|
|
551
|
+
code: SearchQueryErrorCode.SYNTAX_QUOTE_UNTERMINATED,
|
|
552
552
|
position: 0,
|
|
553
553
|
},
|
|
554
554
|
]);
|
|
@@ -559,7 +559,7 @@ describe("Search Query Parser", () => {
|
|
|
559
559
|
{
|
|
560
560
|
length: 3,
|
|
561
561
|
message: "AND is a reserved word",
|
|
562
|
-
code: SearchQueryErrorCode.
|
|
562
|
+
code: SearchQueryErrorCode.SYNTAX_KEYWORD_RESERVED,
|
|
563
563
|
value: "AND",
|
|
564
564
|
position: 0,
|
|
565
565
|
},
|
|
@@ -568,7 +568,7 @@ describe("Search Query Parser", () => {
|
|
|
568
568
|
{
|
|
569
569
|
length: 2,
|
|
570
570
|
message: "OR is a reserved word",
|
|
571
|
-
code: SearchQueryErrorCode.
|
|
571
|
+
code: SearchQueryErrorCode.SYNTAX_KEYWORD_RESERVED,
|
|
572
572
|
value: "OR",
|
|
573
573
|
position: 0,
|
|
574
574
|
},
|
|
@@ -577,7 +577,7 @@ describe("Search Query Parser", () => {
|
|
|
577
577
|
{
|
|
578
578
|
length: 3,
|
|
579
579
|
message: "Unexpected token: AND",
|
|
580
|
-
code: SearchQueryErrorCode.
|
|
580
|
+
code: SearchQueryErrorCode.SYNTAX_TOKEN_UNEXPECTED,
|
|
581
581
|
value: "AND",
|
|
582
582
|
position: 5,
|
|
583
583
|
},
|
|
@@ -586,7 +586,7 @@ describe("Search Query Parser", () => {
|
|
|
586
586
|
{
|
|
587
587
|
length: 2,
|
|
588
588
|
message: "Unexpected token: OR",
|
|
589
|
-
code: SearchQueryErrorCode.
|
|
589
|
+
code: SearchQueryErrorCode.SYNTAX_TOKEN_UNEXPECTED,
|
|
590
590
|
value: "OR",
|
|
591
591
|
position: 5,
|
|
592
592
|
},
|
|
@@ -595,7 +595,7 @@ describe("Search Query Parser", () => {
|
|
|
595
595
|
{
|
|
596
596
|
length: 3,
|
|
597
597
|
message: "AND is a reserved word",
|
|
598
|
-
code: SearchQueryErrorCode.
|
|
598
|
+
code: SearchQueryErrorCode.SYNTAX_KEYWORD_RESERVED,
|
|
599
599
|
value: "AND",
|
|
600
600
|
position: 0,
|
|
601
601
|
},
|
|
@@ -604,7 +604,7 @@ describe("Search Query Parser", () => {
|
|
|
604
604
|
{
|
|
605
605
|
length: 2,
|
|
606
606
|
message: "OR is a reserved word",
|
|
607
|
-
code: SearchQueryErrorCode.
|
|
607
|
+
code: SearchQueryErrorCode.SYNTAX_KEYWORD_RESERVED,
|
|
608
608
|
value: "OR",
|
|
609
609
|
position: 0,
|
|
610
610
|
},
|
|
@@ -618,19 +618,19 @@ describe("Search Query Parser", () => {
|
|
|
618
618
|
{
|
|
619
619
|
length: 6,
|
|
620
620
|
message: "Expected field value",
|
|
621
|
-
code: SearchQueryErrorCode.
|
|
621
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_VALUE_MISSING,
|
|
622
622
|
position: 29,
|
|
623
623
|
},
|
|
624
624
|
{
|
|
625
625
|
length: 6,
|
|
626
626
|
message: "Expected field value",
|
|
627
|
-
code: SearchQueryErrorCode.
|
|
627
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_VALUE_MISSING,
|
|
628
628
|
position: 39,
|
|
629
629
|
},
|
|
630
630
|
{
|
|
631
631
|
length: 5,
|
|
632
632
|
message: "Expected field value",
|
|
633
|
-
code: SearchQueryErrorCode.
|
|
633
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_VALUE_MISSING,
|
|
634
634
|
position: 51,
|
|
635
635
|
},
|
|
636
636
|
]
|
|
@@ -641,7 +641,7 @@ describe("Search Query Parser", () => {
|
|
|
641
641
|
{
|
|
642
642
|
length: 3,
|
|
643
643
|
message: "AND is a reserved word",
|
|
644
|
-
code: SearchQueryErrorCode.
|
|
644
|
+
code: SearchQueryErrorCode.SYNTAX_KEYWORD_RESERVED,
|
|
645
645
|
value: "AND",
|
|
646
646
|
position: 61,
|
|
647
647
|
},
|
|
@@ -653,7 +653,7 @@ describe("Search Query Parser", () => {
|
|
|
653
653
|
testSchemaErrorQuery("amount:>", [
|
|
654
654
|
{
|
|
655
655
|
message: "Expected range value",
|
|
656
|
-
code: SearchQueryErrorCode.
|
|
656
|
+
code: SearchQueryErrorCode.VALUE_RANGE_MISSING,
|
|
657
657
|
position: 8,
|
|
658
658
|
length: 0,
|
|
659
659
|
},
|
|
@@ -662,7 +662,7 @@ describe("Search Query Parser", () => {
|
|
|
662
662
|
testSchemaErrorQuery("price:>=>100", [
|
|
663
663
|
{
|
|
664
664
|
message: "Invalid range operator",
|
|
665
|
-
code: SearchQueryErrorCode.
|
|
665
|
+
code: SearchQueryErrorCode.VALUE_RANGE_OPERATOR_INVALID,
|
|
666
666
|
position: 6,
|
|
667
667
|
length: 3,
|
|
668
668
|
},
|
|
@@ -671,7 +671,7 @@ describe("Search Query Parser", () => {
|
|
|
671
671
|
testSchemaErrorQuery("price:>..", [
|
|
672
672
|
{
|
|
673
673
|
message: "Invalid numeric value",
|
|
674
|
-
code: SearchQueryErrorCode.
|
|
674
|
+
code: SearchQueryErrorCode.VALUE_NUMERIC_INVALID,
|
|
675
675
|
position: 6,
|
|
676
676
|
length: 1,
|
|
677
677
|
},
|
|
@@ -680,7 +680,7 @@ describe("Search Query Parser", () => {
|
|
|
680
680
|
testSchemaErrorQuery("price:...", [
|
|
681
681
|
{
|
|
682
682
|
message: "Invalid range format",
|
|
683
|
-
code: SearchQueryErrorCode.
|
|
683
|
+
code: SearchQueryErrorCode.VALUE_RANGE_FORMAT_INVALID,
|
|
684
684
|
position: 6,
|
|
685
685
|
length: 3,
|
|
686
686
|
},
|
|
@@ -689,7 +689,7 @@ describe("Search Query Parser", () => {
|
|
|
689
689
|
testSchemaErrorQuery("price:100...", [
|
|
690
690
|
{
|
|
691
691
|
message: "Invalid range format",
|
|
692
|
-
code: SearchQueryErrorCode.
|
|
692
|
+
code: SearchQueryErrorCode.VALUE_RANGE_FORMAT_INVALID,
|
|
693
693
|
position: 6,
|
|
694
694
|
length: 6,
|
|
695
695
|
},
|
|
@@ -698,7 +698,7 @@ describe("Search Query Parser", () => {
|
|
|
698
698
|
testSchemaErrorQuery("price:...200", [
|
|
699
699
|
{
|
|
700
700
|
message: "Invalid range format",
|
|
701
|
-
code: SearchQueryErrorCode.
|
|
701
|
+
code: SearchQueryErrorCode.VALUE_RANGE_FORMAT_INVALID,
|
|
702
702
|
position: 6,
|
|
703
703
|
length: 6,
|
|
704
704
|
},
|
|
@@ -709,13 +709,13 @@ describe("Search Query Parser", () => {
|
|
|
709
709
|
testSchemaErrorQuery("price:abc..def", [
|
|
710
710
|
{
|
|
711
711
|
message: "Invalid numeric value",
|
|
712
|
-
code: SearchQueryErrorCode.
|
|
712
|
+
code: SearchQueryErrorCode.VALUE_NUMERIC_INVALID,
|
|
713
713
|
position: 6,
|
|
714
714
|
length: 3,
|
|
715
715
|
},
|
|
716
716
|
{
|
|
717
717
|
message: "Invalid numeric value",
|
|
718
|
-
code: SearchQueryErrorCode.
|
|
718
|
+
code: SearchQueryErrorCode.VALUE_NUMERIC_INVALID,
|
|
719
719
|
position: 11,
|
|
720
720
|
length: 3,
|
|
721
721
|
},
|
|
@@ -724,7 +724,7 @@ describe("Search Query Parser", () => {
|
|
|
724
724
|
testSchemaErrorQuery("amount:>abc", [
|
|
725
725
|
{
|
|
726
726
|
message: "Invalid numeric value",
|
|
727
|
-
code: SearchQueryErrorCode.
|
|
727
|
+
code: SearchQueryErrorCode.VALUE_NUMERIC_INVALID,
|
|
728
728
|
position: 8,
|
|
729
729
|
length: 3,
|
|
730
730
|
},
|
|
@@ -735,7 +735,7 @@ describe("Search Query Parser", () => {
|
|
|
735
735
|
testSchemaErrorQuery("date:>not-a-date", [
|
|
736
736
|
{
|
|
737
737
|
message: "Invalid date format",
|
|
738
|
-
code: SearchQueryErrorCode.
|
|
738
|
+
code: SearchQueryErrorCode.VALUE_DATE_FORMAT_INVALID,
|
|
739
739
|
position: 5,
|
|
740
740
|
length: 11,
|
|
741
741
|
},
|
|
@@ -744,7 +744,7 @@ describe("Search Query Parser", () => {
|
|
|
744
744
|
testSchemaErrorQuery("date:2024-13-01..2024-12-31", [
|
|
745
745
|
{
|
|
746
746
|
message: "Invalid date format",
|
|
747
|
-
code: SearchQueryErrorCode.
|
|
747
|
+
code: SearchQueryErrorCode.VALUE_DATE_FORMAT_INVALID,
|
|
748
748
|
position: 5,
|
|
749
749
|
length: 22,
|
|
750
750
|
},
|
|
@@ -757,7 +757,7 @@ describe("Search Query Parser", () => {
|
|
|
757
757
|
testErrorQuery("test*test", [
|
|
758
758
|
{
|
|
759
759
|
message: "Wildcard (*) can only appear at the end of a term",
|
|
760
|
-
code: SearchQueryErrorCode.
|
|
760
|
+
code: SearchQueryErrorCode.WILDCARD_POSITION_INVALID,
|
|
761
761
|
position: 4,
|
|
762
762
|
length: 1,
|
|
763
763
|
},
|
|
@@ -766,13 +766,13 @@ describe("Search Query Parser", () => {
|
|
|
766
766
|
testErrorQuery("te*st*", [
|
|
767
767
|
{
|
|
768
768
|
message: "Wildcard (*) can only appear at the end of a term",
|
|
769
|
-
code: SearchQueryErrorCode.
|
|
769
|
+
code: SearchQueryErrorCode.WILDCARD_POSITION_INVALID,
|
|
770
770
|
position: 2,
|
|
771
771
|
length: 1,
|
|
772
772
|
},
|
|
773
773
|
{
|
|
774
774
|
message: "Only one trailing wildcard (*) is allowed",
|
|
775
|
-
code: SearchQueryErrorCode.
|
|
775
|
+
code: SearchQueryErrorCode.WILDCARD_MULTIPLE_NOT_PERMITTED,
|
|
776
776
|
position: 5,
|
|
777
777
|
length: 1,
|
|
778
778
|
},
|
|
@@ -783,7 +783,7 @@ describe("Search Query Parser", () => {
|
|
|
783
783
|
testErrorQuery("test**", [
|
|
784
784
|
{
|
|
785
785
|
message: "Only one trailing wildcard (*) is allowed",
|
|
786
|
-
code: SearchQueryErrorCode.
|
|
786
|
+
code: SearchQueryErrorCode.WILDCARD_MULTIPLE_NOT_PERMITTED,
|
|
787
787
|
position: 5,
|
|
788
788
|
length: 1,
|
|
789
789
|
},
|
|
@@ -792,7 +792,7 @@ describe("Search Query Parser", () => {
|
|
|
792
792
|
testErrorQuery('"test"**', [
|
|
793
793
|
{
|
|
794
794
|
message: "Only one trailing wildcard (*) is allowed",
|
|
795
|
-
code: SearchQueryErrorCode.
|
|
795
|
+
code: SearchQueryErrorCode.WILDCARD_MULTIPLE_NOT_PERMITTED,
|
|
796
796
|
position: 7,
|
|
797
797
|
length: 1,
|
|
798
798
|
},
|
|
@@ -801,7 +801,7 @@ describe("Search Query Parser", () => {
|
|
|
801
801
|
testErrorQuery('field:"test"**', [
|
|
802
802
|
{
|
|
803
803
|
message: "Only one trailing wildcard (*) is allowed",
|
|
804
|
-
code: SearchQueryErrorCode.
|
|
804
|
+
code: SearchQueryErrorCode.WILDCARD_MULTIPLE_NOT_PERMITTED,
|
|
805
805
|
position: 13,
|
|
806
806
|
length: 1,
|
|
807
807
|
},
|
|
@@ -812,13 +812,13 @@ describe("Search Query Parser", () => {
|
|
|
812
812
|
testErrorQuery("fie*ld:value", [
|
|
813
813
|
{
|
|
814
814
|
message: "Invalid characters in field name",
|
|
815
|
-
code: SearchQueryErrorCode.
|
|
815
|
+
code: SearchQueryErrorCode.FIELD_CHARS_INVALID,
|
|
816
816
|
position: 0,
|
|
817
817
|
length: 6,
|
|
818
818
|
},
|
|
819
819
|
{
|
|
820
820
|
message: "Wildcard (*) can only appear at the end of a term",
|
|
821
|
-
code: SearchQueryErrorCode.
|
|
821
|
+
code: SearchQueryErrorCode.WILDCARD_POSITION_INVALID,
|
|
822
822
|
position: 3,
|
|
823
823
|
length: 1,
|
|
824
824
|
},
|
|
@@ -827,13 +827,13 @@ describe("Search Query Parser", () => {
|
|
|
827
827
|
testErrorQuery("field*:value", [
|
|
828
828
|
{
|
|
829
829
|
message: "Invalid characters in field name",
|
|
830
|
-
code: SearchQueryErrorCode.
|
|
830
|
+
code: SearchQueryErrorCode.FIELD_CHARS_INVALID,
|
|
831
831
|
position: 0,
|
|
832
832
|
length: 6,
|
|
833
833
|
},
|
|
834
834
|
{
|
|
835
835
|
message: "Wildcard (*) can only appear at the end of a term",
|
|
836
|
-
code: SearchQueryErrorCode.
|
|
836
|
+
code: SearchQueryErrorCode.WILDCARD_POSITION_INVALID,
|
|
837
837
|
position: 5,
|
|
838
838
|
length: 1,
|
|
839
839
|
},
|
|
@@ -842,13 +842,13 @@ describe("Search Query Parser", () => {
|
|
|
842
842
|
testErrorQuery("f*:value", [
|
|
843
843
|
{
|
|
844
844
|
message: "Invalid characters in field name",
|
|
845
|
-
code: SearchQueryErrorCode.
|
|
845
|
+
code: SearchQueryErrorCode.FIELD_CHARS_INVALID,
|
|
846
846
|
position: 0,
|
|
847
847
|
length: 2,
|
|
848
848
|
},
|
|
849
849
|
{
|
|
850
850
|
message: "Wildcard (*) can only appear at the end of a term",
|
|
851
|
-
code: SearchQueryErrorCode.
|
|
851
|
+
code: SearchQueryErrorCode.WILDCARD_POSITION_INVALID,
|
|
852
852
|
position: 1,
|
|
853
853
|
length: 1,
|
|
854
854
|
},
|
|
@@ -859,13 +859,13 @@ describe("Search Query Parser", () => {
|
|
|
859
859
|
testErrorQuery('field*:"test"', [
|
|
860
860
|
{
|
|
861
861
|
message: "Invalid characters in field name",
|
|
862
|
-
code: SearchQueryErrorCode.
|
|
862
|
+
code: SearchQueryErrorCode.FIELD_CHARS_INVALID,
|
|
863
863
|
position: 0,
|
|
864
864
|
length: 6,
|
|
865
865
|
},
|
|
866
866
|
{
|
|
867
867
|
message: "Wildcard (*) can only appear at the end of a term",
|
|
868
|
-
code: SearchQueryErrorCode.
|
|
868
|
+
code: SearchQueryErrorCode.WILDCARD_POSITION_INVALID,
|
|
869
869
|
position: 5,
|
|
870
870
|
length: 1,
|
|
871
871
|
},
|
|
@@ -874,7 +874,7 @@ describe("Search Query Parser", () => {
|
|
|
874
874
|
testErrorQuery('field:"test * test"**', [
|
|
875
875
|
{
|
|
876
876
|
message: "Only one trailing wildcard (*) is allowed",
|
|
877
|
-
code: SearchQueryErrorCode.
|
|
877
|
+
code: SearchQueryErrorCode.WILDCARD_MULTIPLE_NOT_PERMITTED,
|
|
878
878
|
position: 20,
|
|
879
879
|
length: 1,
|
|
880
880
|
},
|
|
@@ -883,13 +883,13 @@ describe("Search Query Parser", () => {
|
|
|
883
883
|
testErrorQuery("test* field*:value", [
|
|
884
884
|
{
|
|
885
885
|
message: "Invalid characters in field name",
|
|
886
|
-
code: SearchQueryErrorCode.
|
|
886
|
+
code: SearchQueryErrorCode.FIELD_CHARS_INVALID,
|
|
887
887
|
position: 6,
|
|
888
888
|
length: 6,
|
|
889
889
|
},
|
|
890
890
|
{
|
|
891
891
|
message: "Wildcard (*) can only appear at the end of a term",
|
|
892
|
-
code: SearchQueryErrorCode.
|
|
892
|
+
code: SearchQueryErrorCode.WILDCARD_POSITION_INVALID,
|
|
893
893
|
position: 11,
|
|
894
894
|
length: 1,
|
|
895
895
|
},
|
|
@@ -958,13 +958,13 @@ describe("Search Query Parser", () => {
|
|
|
958
958
|
expect((invalidNumResult as SearchQueryError).errors).toStrictEqual([
|
|
959
959
|
{
|
|
960
960
|
message: "Invalid numeric value",
|
|
961
|
-
code: SearchQueryErrorCode.
|
|
961
|
+
code: SearchQueryErrorCode.VALUE_NUMERIC_INVALID,
|
|
962
962
|
position: 9,
|
|
963
963
|
length: 3,
|
|
964
964
|
},
|
|
965
965
|
{
|
|
966
966
|
message: "Invalid numeric value",
|
|
967
|
-
code: SearchQueryErrorCode.
|
|
967
|
+
code: SearchQueryErrorCode.VALUE_NUMERIC_INVALID,
|
|
968
968
|
position: 13,
|
|
969
969
|
length: 3,
|
|
970
970
|
},
|
|
@@ -999,7 +999,7 @@ describe("Search Query Parser", () => {
|
|
|
999
999
|
testErrorQuery("status:IN()", [
|
|
1000
1000
|
{
|
|
1001
1001
|
message: "IN operator requires at least one value",
|
|
1002
|
-
code: SearchQueryErrorCode.
|
|
1002
|
+
code: SearchQueryErrorCode.IN_LIST_EMPTY,
|
|
1003
1003
|
position: 10,
|
|
1004
1004
|
length: 1,
|
|
1005
1005
|
},
|
|
@@ -1010,7 +1010,7 @@ describe("Search Query Parser", () => {
|
|
|
1010
1010
|
testErrorQuery("status:IN(active,pending", [
|
|
1011
1011
|
{
|
|
1012
1012
|
message: "Expected ',' or ')' after IN value",
|
|
1013
|
-
code: SearchQueryErrorCode.
|
|
1013
|
+
code: SearchQueryErrorCode.IN_SEPARATOR_MISSING,
|
|
1014
1014
|
position: 5,
|
|
1015
1015
|
length: 1,
|
|
1016
1016
|
},
|
|
@@ -1032,7 +1032,7 @@ describe("Search Query Parser", () => {
|
|
|
1032
1032
|
testErrorQuery("status:IN(active pending)", [
|
|
1033
1033
|
{
|
|
1034
1034
|
message: "Expected ',' or ')' after IN value",
|
|
1035
|
-
code: SearchQueryErrorCode.
|
|
1035
|
+
code: SearchQueryErrorCode.IN_SEPARATOR_MISSING,
|
|
1036
1036
|
position: 17,
|
|
1037
1037
|
length: 1,
|
|
1038
1038
|
},
|
|
@@ -1043,7 +1043,7 @@ describe("Search Query Parser", () => {
|
|
|
1043
1043
|
testErrorQuery('status:IN("unclosed', [
|
|
1044
1044
|
{
|
|
1045
1045
|
message: "Unterminated quoted string",
|
|
1046
|
-
code: SearchQueryErrorCode.
|
|
1046
|
+
code: SearchQueryErrorCode.SYNTAX_QUOTE_UNTERMINATED,
|
|
1047
1047
|
position: 10,
|
|
1048
1048
|
length: 10,
|
|
1049
1049
|
},
|
package/src/parser.ts
CHANGED
|
@@ -146,7 +146,7 @@ export const parseSearchInputQuery = (
|
|
|
146
146
|
if (finalToken.type !== TokenType.EOF) {
|
|
147
147
|
throw {
|
|
148
148
|
message: 'Unexpected ")"',
|
|
149
|
-
code: SearchQueryErrorCode.
|
|
149
|
+
code: SearchQueryErrorCode.SYNTAX_PARENTHESIS_UNEXPECTED,
|
|
150
150
|
position: finalToken.position,
|
|
151
151
|
length: finalToken.length,
|
|
152
152
|
};
|
|
@@ -12,7 +12,7 @@ const validateNumber = (
|
|
|
12
12
|
if (isNaN(Number(value))) {
|
|
13
13
|
errors.push({
|
|
14
14
|
message: "Invalid numeric value",
|
|
15
|
-
code: SearchQueryErrorCode.
|
|
15
|
+
code: SearchQueryErrorCode.VALUE_NUMERIC_INVALID,
|
|
16
16
|
position,
|
|
17
17
|
length: value.length,
|
|
18
18
|
});
|
|
@@ -45,7 +45,7 @@ const validateNumericRange = (
|
|
|
45
45
|
if (startNum > endNum) {
|
|
46
46
|
errors.push({
|
|
47
47
|
message: "Range start must be less than or equal to range end",
|
|
48
|
-
code: SearchQueryErrorCode.
|
|
48
|
+
code: SearchQueryErrorCode.VALUE_RANGE_START_EXCEEDS_END,
|
|
49
49
|
position: basePosition,
|
|
50
50
|
length: start.length + 2 + end.length,
|
|
51
51
|
});
|
|
@@ -79,7 +79,7 @@ const validateFieldValue = (
|
|
|
79
79
|
if (!allowedFields.has(expr.field.toLowerCase())) {
|
|
80
80
|
errors.push({
|
|
81
81
|
message: `Invalid field: "${expr.field}"`,
|
|
82
|
-
code: SearchQueryErrorCode.
|
|
82
|
+
code: SearchQueryErrorCode.FIELD_NAME_INVALID,
|
|
83
83
|
value: expr.field,
|
|
84
84
|
position: expr.position,
|
|
85
85
|
length: expr.field.length,
|
|
@@ -95,7 +95,7 @@ const validateFieldValue = (
|
|
|
95
95
|
if (isNaN(Number(value))) {
|
|
96
96
|
errors.push({
|
|
97
97
|
message: "Invalid numeric value",
|
|
98
|
-
code: SearchQueryErrorCode.
|
|
98
|
+
code: SearchQueryErrorCode.VALUE_NUMERIC_INVALID,
|
|
99
99
|
position:
|
|
100
100
|
expr.position +
|
|
101
101
|
expr.field.length +
|
|
@@ -109,7 +109,7 @@ const validateFieldValue = (
|
|
|
109
109
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
110
110
|
errors.push({
|
|
111
111
|
message: "Invalid date format",
|
|
112
|
-
code: SearchQueryErrorCode.
|
|
112
|
+
code: SearchQueryErrorCode.VALUE_DATE_FORMAT_INVALID,
|
|
113
113
|
position:
|
|
114
114
|
expr.position +
|
|
115
115
|
expr.field.length +
|
|
@@ -130,7 +130,7 @@ const validateFieldValue = (
|
|
|
130
130
|
const schema = schemas.get(expr.prefix.toLowerCase());
|
|
131
131
|
if (schema?.type === "number" || schema?.type === "date") {
|
|
132
132
|
errors.push({
|
|
133
|
-
code: SearchQueryErrorCode.
|
|
133
|
+
code: SearchQueryErrorCode.VALUE_WILDCARD_NOT_PERMITTED,
|
|
134
134
|
value: schema.type,
|
|
135
135
|
message: `Wildcards are not allowed for ${schema.type} fields`,
|
|
136
136
|
position: expr.position,
|
|
@@ -150,7 +150,7 @@ const validateFieldValue = (
|
|
|
150
150
|
if (!allowedFields.has(fieldName.toLowerCase()) && colonIndex > 0) {
|
|
151
151
|
errors.push({
|
|
152
152
|
message: `Invalid field: "${fieldName}"`,
|
|
153
|
-
code: SearchQueryErrorCode.
|
|
153
|
+
code: SearchQueryErrorCode.FIELD_NAME_INVALID,
|
|
154
154
|
value: fieldName,
|
|
155
155
|
position: expr.position,
|
|
156
156
|
length: colonIndex,
|
|
@@ -160,7 +160,7 @@ const validateFieldValue = (
|
|
|
160
160
|
if (!value) {
|
|
161
161
|
errors.push({
|
|
162
162
|
message: "Expected field value",
|
|
163
|
-
code: SearchQueryErrorCode.
|
|
163
|
+
code: SearchQueryErrorCode.SYNTAX_VALUE_MISSING,
|
|
164
164
|
position: expr.position,
|
|
165
165
|
length: colonIndex + 1,
|
|
166
166
|
});
|
|
@@ -170,7 +170,7 @@ const validateFieldValue = (
|
|
|
170
170
|
if (value.startsWith(":")) {
|
|
171
171
|
errors.push({
|
|
172
172
|
message: "Missing field name",
|
|
173
|
-
code: SearchQueryErrorCode.
|
|
173
|
+
code: SearchQueryErrorCode.SYNTAX_FIELD_NAME_MISSING,
|
|
174
174
|
position: expr.position,
|
|
175
175
|
length: value.length + colonIndex + 1,
|
|
176
176
|
});
|
|
@@ -187,7 +187,7 @@ const validateFieldValue = (
|
|
|
187
187
|
if (value === ".." || value.includes("...")) {
|
|
188
188
|
errors.push({
|
|
189
189
|
message: "Invalid range format",
|
|
190
|
-
code: SearchQueryErrorCode.
|
|
190
|
+
code: SearchQueryErrorCode.VALUE_RANGE_FORMAT_INVALID,
|
|
191
191
|
position: valueStartPosition,
|
|
192
192
|
length: value.length,
|
|
193
193
|
});
|
|
@@ -207,7 +207,7 @@ const validateFieldValue = (
|
|
|
207
207
|
if (invalidOp.test(value)) {
|
|
208
208
|
errors.push({
|
|
209
209
|
message: "Invalid range operator",
|
|
210
|
-
code: SearchQueryErrorCode.
|
|
210
|
+
code: SearchQueryErrorCode.VALUE_RANGE_OPERATOR_INVALID,
|
|
211
211
|
position: valueStartPosition,
|
|
212
212
|
length: 3,
|
|
213
213
|
});
|
|
@@ -217,7 +217,7 @@ const validateFieldValue = (
|
|
|
217
217
|
if (!compValue) {
|
|
218
218
|
errors.push({
|
|
219
219
|
message: "Expected range value",
|
|
220
|
-
code: SearchQueryErrorCode.
|
|
220
|
+
code: SearchQueryErrorCode.VALUE_RANGE_MISSING,
|
|
221
221
|
position: valueStartPosition + operator.length,
|
|
222
222
|
length: 0,
|
|
223
223
|
});
|
|
@@ -255,7 +255,7 @@ const validateFieldValue = (
|
|
|
255
255
|
if (!dateValidator(start) || !dateValidator(end)) {
|
|
256
256
|
errors.push({
|
|
257
257
|
message: "Invalid date format",
|
|
258
|
-
code: SearchQueryErrorCode.
|
|
258
|
+
code: SearchQueryErrorCode.VALUE_DATE_FORMAT_INVALID,
|
|
259
259
|
position: valueStartPosition,
|
|
260
260
|
length: value.length,
|
|
261
261
|
});
|
|
@@ -268,7 +268,7 @@ const validateFieldValue = (
|
|
|
268
268
|
if (!dateValidator(dateStr)) {
|
|
269
269
|
errors.push({
|
|
270
270
|
message: "Invalid date format",
|
|
271
|
-
code: SearchQueryErrorCode.
|
|
271
|
+
code: SearchQueryErrorCode.VALUE_DATE_FORMAT_INVALID,
|
|
272
272
|
position: valueStartPosition,
|
|
273
273
|
length: value.length,
|
|
274
274
|
});
|
|
@@ -277,7 +277,7 @@ const validateFieldValue = (
|
|
|
277
277
|
} else if (!dateValidator(value)) {
|
|
278
278
|
errors.push({
|
|
279
279
|
message: "Invalid date format",
|
|
280
|
-
code: SearchQueryErrorCode.
|
|
280
|
+
code: SearchQueryErrorCode.VALUE_DATE_FORMAT_INVALID,
|
|
281
281
|
position: valueStartPosition,
|
|
282
282
|
length: value.length,
|
|
283
283
|
});
|