search-input-query-parser 0.2.0 → 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 -26
- 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 -26
- package/dist/types/validator.d.ts +27 -26
- 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 +28 -26
|
@@ -34,7 +34,7 @@ const parseExpression = (stream, minPrecedence = 0) => {
|
|
|
34
34
|
if (nextToken.type === lexer_1.TokenType.EOF) {
|
|
35
35
|
throw {
|
|
36
36
|
message: `Unexpected token: ${token.value}`,
|
|
37
|
-
code: validator_1.SearchQueryErrorCode.
|
|
37
|
+
code: validator_1.SearchQueryErrorCode.SYNTAX_TOKEN_UNEXPECTED,
|
|
38
38
|
value: token.value,
|
|
39
39
|
position: token.position,
|
|
40
40
|
length: token.length,
|
package/dist/cjs/lexer.js
CHANGED
|
@@ -99,7 +99,7 @@ const tokenizeQuotedString = (input, position) => {
|
|
|
99
99
|
}
|
|
100
100
|
throw {
|
|
101
101
|
message: "Unterminated quoted string",
|
|
102
|
-
code: validator_1.SearchQueryErrorCode.
|
|
102
|
+
code: validator_1.SearchQueryErrorCode.SYNTAX_QUOTE_UNTERMINATED,
|
|
103
103
|
position,
|
|
104
104
|
length,
|
|
105
105
|
};
|
|
@@ -266,7 +266,7 @@ const tokenize = (input) => {
|
|
|
266
266
|
prevToken.type === TokenType.STRING)) {
|
|
267
267
|
throw {
|
|
268
268
|
message: "Invalid syntax: Missing operator or whitespace between terms",
|
|
269
|
-
code: validator_1.SearchQueryErrorCode.
|
|
269
|
+
code: validator_1.SearchQueryErrorCode.SYNTAX_OPERATOR_OR_SPACE_MISSING,
|
|
270
270
|
position: position,
|
|
271
271
|
length: 1,
|
|
272
272
|
};
|
|
@@ -279,7 +279,7 @@ const tokenize = (input) => {
|
|
|
279
279
|
!isSpecialChar(input[newPos])) {
|
|
280
280
|
throw {
|
|
281
281
|
message: "Invalid syntax: Missing operator or whitespace between terms",
|
|
282
|
-
code: validator_1.SearchQueryErrorCode.
|
|
282
|
+
code: validator_1.SearchQueryErrorCode.SYNTAX_OPERATOR_OR_SPACE_MISSING,
|
|
283
283
|
position: newPos,
|
|
284
284
|
length: 1,
|
|
285
285
|
};
|
|
@@ -10,7 +10,7 @@ const parseInValues = (stream, inValuePosition) => {
|
|
|
10
10
|
if ((0, lexer_1.currentToken)(currentStream).type !== lexer_1.TokenType.LPAREN) {
|
|
11
11
|
throw {
|
|
12
12
|
message: "Expected '(' after IN",
|
|
13
|
-
code: validator_1.SearchQueryErrorCode.
|
|
13
|
+
code: validator_1.SearchQueryErrorCode.IN_LPAREN_MISSING,
|
|
14
14
|
position: inValuePosition, // Use the position passed from the caller
|
|
15
15
|
length: 1,
|
|
16
16
|
};
|
|
@@ -22,7 +22,7 @@ const parseInValues = (stream, inValuePosition) => {
|
|
|
22
22
|
if (values.length === 0) {
|
|
23
23
|
throw {
|
|
24
24
|
message: "IN operator requires at least one value",
|
|
25
|
-
code: validator_1.SearchQueryErrorCode.
|
|
25
|
+
code: validator_1.SearchQueryErrorCode.IN_LIST_EMPTY,
|
|
26
26
|
position: token.position,
|
|
27
27
|
length: 1,
|
|
28
28
|
};
|
|
@@ -39,7 +39,7 @@ const parseInValues = (stream, inValuePosition) => {
|
|
|
39
39
|
token.type !== lexer_1.TokenType.COMMA)) {
|
|
40
40
|
throw {
|
|
41
41
|
message: "Expected ',' or ')' after IN value",
|
|
42
|
-
code: validator_1.SearchQueryErrorCode.
|
|
42
|
+
code: validator_1.SearchQueryErrorCode.IN_SEPARATOR_MISSING,
|
|
43
43
|
position: token.position,
|
|
44
44
|
length: 1,
|
|
45
45
|
};
|
|
@@ -59,7 +59,7 @@ const parseInValues = (stream, inValuePosition) => {
|
|
|
59
59
|
}
|
|
60
60
|
throw {
|
|
61
61
|
message: "Expected ',' or ')' after IN value",
|
|
62
|
-
code: validator_1.SearchQueryErrorCode.
|
|
62
|
+
code: validator_1.SearchQueryErrorCode.IN_SEPARATOR_MISSING,
|
|
63
63
|
position: nextToken.position,
|
|
64
64
|
length: 1,
|
|
65
65
|
};
|
|
@@ -10,7 +10,7 @@ const expectToken = (stream, type, message) => {
|
|
|
10
10
|
if (token.type !== type) {
|
|
11
11
|
throw {
|
|
12
12
|
message: message ? message : `Expected ${type}`,
|
|
13
|
-
code: validator_1.SearchQueryErrorCode.
|
|
13
|
+
code: validator_1.SearchQueryErrorCode.SYNTAX_TOKEN_MISSING,
|
|
14
14
|
value: type,
|
|
15
15
|
position: token.position,
|
|
16
16
|
length: token.length,
|
|
@@ -137,7 +137,7 @@ const parsePrimary = (stream) => {
|
|
|
137
137
|
case lexer_1.TokenType.OR:
|
|
138
138
|
throw {
|
|
139
139
|
message: `${token.value} is a reserved word`,
|
|
140
|
-
code: validator_1.SearchQueryErrorCode.
|
|
140
|
+
code: validator_1.SearchQueryErrorCode.SYNTAX_KEYWORD_RESERVED,
|
|
141
141
|
value: token.value,
|
|
142
142
|
position: token.position,
|
|
143
143
|
length: token.length,
|
|
@@ -145,14 +145,14 @@ const parsePrimary = (stream) => {
|
|
|
145
145
|
case lexer_1.TokenType.RPAREN:
|
|
146
146
|
throw {
|
|
147
147
|
message: 'Unexpected ")"',
|
|
148
|
-
code: validator_1.SearchQueryErrorCode.
|
|
148
|
+
code: validator_1.SearchQueryErrorCode.SYNTAX_PARENTHESIS_UNEXPECTED,
|
|
149
149
|
position: token.position,
|
|
150
150
|
length: token.length,
|
|
151
151
|
};
|
|
152
152
|
default:
|
|
153
153
|
throw {
|
|
154
154
|
message: "Unexpected token",
|
|
155
|
-
code: validator_1.SearchQueryErrorCode.
|
|
155
|
+
code: validator_1.SearchQueryErrorCode.SYNTAX_TOKEN_UNEXPECTED,
|
|
156
156
|
position: token.position,
|
|
157
157
|
length: token.length,
|
|
158
158
|
};
|
package/dist/cjs/parser.js
CHANGED
|
@@ -48,7 +48,7 @@ const parseSearchInputQuery = (input, fieldSchemas = []) => {
|
|
|
48
48
|
if (finalToken.type !== lexer_1.TokenType.EOF) {
|
|
49
49
|
throw {
|
|
50
50
|
message: 'Unexpected ")"',
|
|
51
|
-
code: validator_1.SearchQueryErrorCode.
|
|
51
|
+
code: validator_1.SearchQueryErrorCode.SYNTAX_PARENTHESIS_UNEXPECTED,
|
|
52
52
|
position: finalToken.position,
|
|
53
53
|
length: finalToken.length,
|
|
54
54
|
};
|
|
@@ -9,7 +9,7 @@ const validateNumber = (value, position, errors) => {
|
|
|
9
9
|
if (isNaN(Number(value))) {
|
|
10
10
|
errors.push({
|
|
11
11
|
message: "Invalid numeric value",
|
|
12
|
-
code: validator_1.SearchQueryErrorCode.
|
|
12
|
+
code: validator_1.SearchQueryErrorCode.VALUE_NUMERIC_INVALID,
|
|
13
13
|
position,
|
|
14
14
|
length: value.length,
|
|
15
15
|
});
|
|
@@ -34,7 +34,7 @@ const validateNumericRange = (start, end, basePosition, errors) => {
|
|
|
34
34
|
if (startNum > endNum) {
|
|
35
35
|
errors.push({
|
|
36
36
|
message: "Range start must be less than or equal to range end",
|
|
37
|
-
code: validator_1.SearchQueryErrorCode.
|
|
37
|
+
code: validator_1.SearchQueryErrorCode.VALUE_RANGE_START_EXCEEDS_END,
|
|
38
38
|
position: basePosition,
|
|
39
39
|
length: start.length + 2 + end.length,
|
|
40
40
|
});
|
|
@@ -55,7 +55,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
|
|
|
55
55
|
if (!allowedFields.has(expr.field.toLowerCase())) {
|
|
56
56
|
errors.push({
|
|
57
57
|
message: `Invalid field: "${expr.field}"`,
|
|
58
|
-
code: validator_1.SearchQueryErrorCode.
|
|
58
|
+
code: validator_1.SearchQueryErrorCode.FIELD_NAME_INVALID,
|
|
59
59
|
value: expr.field,
|
|
60
60
|
position: expr.position,
|
|
61
61
|
length: expr.field.length,
|
|
@@ -70,7 +70,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
|
|
|
70
70
|
if (isNaN(Number(value))) {
|
|
71
71
|
errors.push({
|
|
72
72
|
message: "Invalid numeric value",
|
|
73
|
-
code: validator_1.SearchQueryErrorCode.
|
|
73
|
+
code: validator_1.SearchQueryErrorCode.VALUE_NUMERIC_INVALID,
|
|
74
74
|
position: expr.position +
|
|
75
75
|
expr.field.length +
|
|
76
76
|
4 +
|
|
@@ -83,7 +83,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
|
|
|
83
83
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
84
84
|
errors.push({
|
|
85
85
|
message: "Invalid date format",
|
|
86
|
-
code: validator_1.SearchQueryErrorCode.
|
|
86
|
+
code: validator_1.SearchQueryErrorCode.VALUE_DATE_FORMAT_INVALID,
|
|
87
87
|
position: expr.position +
|
|
88
88
|
expr.field.length +
|
|
89
89
|
3 +
|
|
@@ -102,7 +102,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
|
|
|
102
102
|
const schema = schemas.get(expr.prefix.toLowerCase());
|
|
103
103
|
if ((schema === null || schema === void 0 ? void 0 : schema.type) === "number" || (schema === null || schema === void 0 ? void 0 : schema.type) === "date") {
|
|
104
104
|
errors.push({
|
|
105
|
-
code: validator_1.SearchQueryErrorCode.
|
|
105
|
+
code: validator_1.SearchQueryErrorCode.VALUE_WILDCARD_NOT_PERMITTED,
|
|
106
106
|
value: schema.type,
|
|
107
107
|
message: `Wildcards are not allowed for ${schema.type} fields`,
|
|
108
108
|
position: expr.position,
|
|
@@ -120,7 +120,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
|
|
|
120
120
|
if (!allowedFields.has(fieldName.toLowerCase()) && colonIndex > 0) {
|
|
121
121
|
errors.push({
|
|
122
122
|
message: `Invalid field: "${fieldName}"`,
|
|
123
|
-
code: validator_1.SearchQueryErrorCode.
|
|
123
|
+
code: validator_1.SearchQueryErrorCode.FIELD_NAME_INVALID,
|
|
124
124
|
value: fieldName,
|
|
125
125
|
position: expr.position,
|
|
126
126
|
length: colonIndex,
|
|
@@ -129,7 +129,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
|
|
|
129
129
|
if (!value) {
|
|
130
130
|
errors.push({
|
|
131
131
|
message: "Expected field value",
|
|
132
|
-
code: validator_1.SearchQueryErrorCode.
|
|
132
|
+
code: validator_1.SearchQueryErrorCode.SYNTAX_VALUE_MISSING,
|
|
133
133
|
position: expr.position,
|
|
134
134
|
length: colonIndex + 1,
|
|
135
135
|
});
|
|
@@ -138,7 +138,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
|
|
|
138
138
|
if (value.startsWith(":")) {
|
|
139
139
|
errors.push({
|
|
140
140
|
message: "Missing field name",
|
|
141
|
-
code: validator_1.SearchQueryErrorCode.
|
|
141
|
+
code: validator_1.SearchQueryErrorCode.SYNTAX_FIELD_NAME_MISSING,
|
|
142
142
|
position: expr.position,
|
|
143
143
|
length: value.length + colonIndex + 1,
|
|
144
144
|
});
|
|
@@ -153,7 +153,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
|
|
|
153
153
|
if (value === ".." || value.includes("...")) {
|
|
154
154
|
errors.push({
|
|
155
155
|
message: "Invalid range format",
|
|
156
|
-
code: validator_1.SearchQueryErrorCode.
|
|
156
|
+
code: validator_1.SearchQueryErrorCode.VALUE_RANGE_FORMAT_INVALID,
|
|
157
157
|
position: valueStartPosition,
|
|
158
158
|
length: value.length,
|
|
159
159
|
});
|
|
@@ -170,7 +170,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
|
|
|
170
170
|
if (invalidOp.test(value)) {
|
|
171
171
|
errors.push({
|
|
172
172
|
message: "Invalid range operator",
|
|
173
|
-
code: validator_1.SearchQueryErrorCode.
|
|
173
|
+
code: validator_1.SearchQueryErrorCode.VALUE_RANGE_OPERATOR_INVALID,
|
|
174
174
|
position: valueStartPosition,
|
|
175
175
|
length: 3,
|
|
176
176
|
});
|
|
@@ -179,7 +179,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
|
|
|
179
179
|
if (!compValue) {
|
|
180
180
|
errors.push({
|
|
181
181
|
message: "Expected range value",
|
|
182
|
-
code: validator_1.SearchQueryErrorCode.
|
|
182
|
+
code: validator_1.SearchQueryErrorCode.VALUE_RANGE_MISSING,
|
|
183
183
|
position: valueStartPosition + operator.length,
|
|
184
184
|
length: 0,
|
|
185
185
|
});
|
|
@@ -207,7 +207,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
|
|
|
207
207
|
if (!dateValidator(start) || !dateValidator(end)) {
|
|
208
208
|
errors.push({
|
|
209
209
|
message: "Invalid date format",
|
|
210
|
-
code: validator_1.SearchQueryErrorCode.
|
|
210
|
+
code: validator_1.SearchQueryErrorCode.VALUE_DATE_FORMAT_INVALID,
|
|
211
211
|
position: valueStartPosition,
|
|
212
212
|
length: value.length,
|
|
213
213
|
});
|
|
@@ -221,7 +221,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
|
|
|
221
221
|
if (!dateValidator(dateStr)) {
|
|
222
222
|
errors.push({
|
|
223
223
|
message: "Invalid date format",
|
|
224
|
-
code: validator_1.SearchQueryErrorCode.
|
|
224
|
+
code: validator_1.SearchQueryErrorCode.VALUE_DATE_FORMAT_INVALID,
|
|
225
225
|
position: valueStartPosition,
|
|
226
226
|
length: value.length,
|
|
227
227
|
});
|
|
@@ -231,7 +231,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
|
|
|
231
231
|
else if (!dateValidator(value)) {
|
|
232
232
|
errors.push({
|
|
233
233
|
message: "Invalid date format",
|
|
234
|
-
code: validator_1.SearchQueryErrorCode.
|
|
234
|
+
code: validator_1.SearchQueryErrorCode.VALUE_DATE_FORMAT_INVALID,
|
|
235
235
|
position: valueStartPosition,
|
|
236
236
|
length: value.length,
|
|
237
237
|
});
|
|
@@ -7,7 +7,7 @@ const validateInExpression = (expr, errors) => {
|
|
|
7
7
|
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(expr.field)) {
|
|
8
8
|
errors.push({
|
|
9
9
|
message: "Invalid characters in field name",
|
|
10
|
-
code: validator_1.SearchQueryErrorCode.
|
|
10
|
+
code: validator_1.SearchQueryErrorCode.FIELD_CHARS_INVALID,
|
|
11
11
|
position: expr.position,
|
|
12
12
|
length: expr.field.length,
|
|
13
13
|
});
|
|
@@ -16,7 +16,7 @@ const validateInExpression = (expr, errors) => {
|
|
|
16
16
|
if (validator_1.reservedWords.has(expr.field.toUpperCase())) {
|
|
17
17
|
errors.push({
|
|
18
18
|
message: `${expr.field} is a reserved word`,
|
|
19
|
-
code: validator_1.SearchQueryErrorCode.
|
|
19
|
+
code: validator_1.SearchQueryErrorCode.FIELD_NAME_RESERVED,
|
|
20
20
|
value: expr.field,
|
|
21
21
|
position: expr.position,
|
|
22
22
|
length: expr.field.length,
|
|
@@ -27,7 +27,7 @@ const validateInExpression = (expr, errors) => {
|
|
|
27
27
|
if (value.includes(",")) {
|
|
28
28
|
errors.push({
|
|
29
29
|
message: "Invalid character in IN value",
|
|
30
|
-
code: validator_1.SearchQueryErrorCode.
|
|
30
|
+
code: validator_1.SearchQueryErrorCode.IN_VALUE_INVALID,
|
|
31
31
|
position: expr.position + expr.field.length + 3 + index * (value.length + 1),
|
|
32
32
|
length: value.length,
|
|
33
33
|
});
|
|
@@ -16,7 +16,7 @@ const validateString = (expr, errors) => {
|
|
|
16
16
|
if (expr.value.endsWith(":")) {
|
|
17
17
|
errors.push({
|
|
18
18
|
message: "Expected field value",
|
|
19
|
-
code: validator_1.SearchQueryErrorCode.
|
|
19
|
+
code: validator_1.SearchQueryErrorCode.SYNTAX_FIELD_VALUE_MISSING,
|
|
20
20
|
position: expr.position,
|
|
21
21
|
length: expr.length,
|
|
22
22
|
});
|
|
@@ -26,7 +26,7 @@ const validateString = (expr, errors) => {
|
|
|
26
26
|
if (expr.value.startsWith(":")) {
|
|
27
27
|
errors.push({
|
|
28
28
|
message: "Missing field name",
|
|
29
|
-
code: validator_1.SearchQueryErrorCode.
|
|
29
|
+
code: validator_1.SearchQueryErrorCode.SYNTAX_FIELD_NAME_MISSING,
|
|
30
30
|
position: expr.position,
|
|
31
31
|
length: expr.length,
|
|
32
32
|
});
|
|
@@ -39,7 +39,7 @@ const validateString = (expr, errors) => {
|
|
|
39
39
|
if (validator_1.reservedWords.has(fieldName.toUpperCase())) {
|
|
40
40
|
errors.push({
|
|
41
41
|
message: `${fieldName} is a reserved word`,
|
|
42
|
-
code: validator_1.SearchQueryErrorCode.
|
|
42
|
+
code: validator_1.SearchQueryErrorCode.FIELD_NAME_RESERVED,
|
|
43
43
|
value: fieldName,
|
|
44
44
|
position: expr.position,
|
|
45
45
|
length: fieldName.length,
|
|
@@ -50,7 +50,7 @@ const validateString = (expr, errors) => {
|
|
|
50
50
|
if (!/^[a-zA-Z0-9_-]+$/.test(fieldName)) {
|
|
51
51
|
errors.push({
|
|
52
52
|
message: "Invalid characters in field name",
|
|
53
|
-
code: validator_1.SearchQueryErrorCode.
|
|
53
|
+
code: validator_1.SearchQueryErrorCode.FIELD_CHARS_INVALID,
|
|
54
54
|
position: expr.position,
|
|
55
55
|
length: fieldName.length,
|
|
56
56
|
});
|
|
@@ -62,7 +62,7 @@ const validateString = (expr, errors) => {
|
|
|
62
62
|
validator_1.reservedWords.has(expr.value.toUpperCase())) {
|
|
63
63
|
errors.push({
|
|
64
64
|
message: `${expr.value} is a reserved word`,
|
|
65
|
-
code: validator_1.SearchQueryErrorCode.
|
|
65
|
+
code: validator_1.SearchQueryErrorCode.FIELD_NAME_RESERVED,
|
|
66
66
|
value: expr.value,
|
|
67
67
|
position: expr.position,
|
|
68
68
|
length: expr.length,
|
|
@@ -14,7 +14,7 @@ const validateWildcard = (expr, errors) => {
|
|
|
14
14
|
const secondStar = value.indexOf("*", firstStar + 1);
|
|
15
15
|
errors.push({
|
|
16
16
|
message: "Only one trailing wildcard (*) is allowed",
|
|
17
|
-
code: validator_1.SearchQueryErrorCode.
|
|
17
|
+
code: validator_1.SearchQueryErrorCode.WILDCARD_MULTIPLE_NOT_PERMITTED,
|
|
18
18
|
position: expr.position + secondStar,
|
|
19
19
|
length: 1,
|
|
20
20
|
});
|
|
@@ -22,7 +22,7 @@ const validateWildcard = (expr, errors) => {
|
|
|
22
22
|
if ((firstStar !== -1 && firstStar !== value.length - 1) && !value.endsWith("**")) {
|
|
23
23
|
errors.push({
|
|
24
24
|
message: "Wildcard (*) can only appear at the end of a term",
|
|
25
|
-
code: validator_1.SearchQueryErrorCode.
|
|
25
|
+
code: validator_1.SearchQueryErrorCode.WILDCARD_POSITION_INVALID,
|
|
26
26
|
position: expr.position + firstStar,
|
|
27
27
|
length: 1,
|
|
28
28
|
});
|
|
@@ -34,7 +34,7 @@ const validateWildcard = (expr, errors) => {
|
|
|
34
34
|
if (value.endsWith("**")) {
|
|
35
35
|
errors.push({
|
|
36
36
|
message: "Only one trailing wildcard (*) is allowed",
|
|
37
|
-
code: validator_1.SearchQueryErrorCode.
|
|
37
|
+
code: validator_1.SearchQueryErrorCode.WILDCARD_MULTIPLE_NOT_PERMITTED,
|
|
38
38
|
position: expr.position + value.length - 1,
|
|
39
39
|
length: 1,
|
|
40
40
|
});
|
package/dist/cjs/validator.js
CHANGED
|
@@ -5,37 +5,38 @@ const validate_in_expression_1 = require("./validate-in-expression");
|
|
|
5
5
|
const validate_string_1 = require("./validate-string");
|
|
6
6
|
var SearchQueryErrorCode;
|
|
7
7
|
(function (SearchQueryErrorCode) {
|
|
8
|
+
SearchQueryErrorCode[SearchQueryErrorCode["UNKNOWN"] = 0] = "UNKNOWN";
|
|
8
9
|
// Syntax Errors (1000-1999)
|
|
9
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
10
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
11
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
12
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
13
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
14
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
15
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
16
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
17
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
18
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
10
|
+
SearchQueryErrorCode[SearchQueryErrorCode["SYNTAX_QUOTE_UNTERMINATED"] = 1001] = "SYNTAX_QUOTE_UNTERMINATED";
|
|
11
|
+
SearchQueryErrorCode[SearchQueryErrorCode["SYNTAX_VALUE_MISSING"] = 1002] = "SYNTAX_VALUE_MISSING";
|
|
12
|
+
SearchQueryErrorCode[SearchQueryErrorCode["SYNTAX_FIELD_NAME_MISSING"] = 1003] = "SYNTAX_FIELD_NAME_MISSING";
|
|
13
|
+
SearchQueryErrorCode[SearchQueryErrorCode["SYNTAX_FIELD_VALUE_MISSING"] = 1004] = "SYNTAX_FIELD_VALUE_MISSING";
|
|
14
|
+
SearchQueryErrorCode[SearchQueryErrorCode["SYNTAX_PARENTHESIS_UNEXPECTED"] = 1005] = "SYNTAX_PARENTHESIS_UNEXPECTED";
|
|
15
|
+
SearchQueryErrorCode[SearchQueryErrorCode["SYNTAX_PARENTHESIS_MISSING"] = 1006] = "SYNTAX_PARENTHESIS_MISSING";
|
|
16
|
+
SearchQueryErrorCode[SearchQueryErrorCode["SYNTAX_TOKEN_UNEXPECTED"] = 1007] = "SYNTAX_TOKEN_UNEXPECTED";
|
|
17
|
+
SearchQueryErrorCode[SearchQueryErrorCode["SYNTAX_TOKEN_MISSING"] = 1008] = "SYNTAX_TOKEN_MISSING";
|
|
18
|
+
SearchQueryErrorCode[SearchQueryErrorCode["SYNTAX_OPERATOR_OR_SPACE_MISSING"] = 1009] = "SYNTAX_OPERATOR_OR_SPACE_MISSING";
|
|
19
|
+
SearchQueryErrorCode[SearchQueryErrorCode["SYNTAX_KEYWORD_RESERVED"] = 1010] = "SYNTAX_KEYWORD_RESERVED";
|
|
19
20
|
// Field Validation Errors (2000-2999)
|
|
20
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
21
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
22
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
21
|
+
SearchQueryErrorCode[SearchQueryErrorCode["FIELD_NAME_INVALID"] = 2001] = "FIELD_NAME_INVALID";
|
|
22
|
+
SearchQueryErrorCode[SearchQueryErrorCode["FIELD_CHARS_INVALID"] = 2002] = "FIELD_CHARS_INVALID";
|
|
23
|
+
SearchQueryErrorCode[SearchQueryErrorCode["FIELD_NAME_RESERVED"] = 2003] = "FIELD_NAME_RESERVED";
|
|
23
24
|
// Value Validation Errors (3000-3999)
|
|
24
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
25
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
26
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
27
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
28
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
29
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
30
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
25
|
+
SearchQueryErrorCode[SearchQueryErrorCode["VALUE_NUMERIC_INVALID"] = 3001] = "VALUE_NUMERIC_INVALID";
|
|
26
|
+
SearchQueryErrorCode[SearchQueryErrorCode["VALUE_DATE_FORMAT_INVALID"] = 3002] = "VALUE_DATE_FORMAT_INVALID";
|
|
27
|
+
SearchQueryErrorCode[SearchQueryErrorCode["VALUE_RANGE_FORMAT_INVALID"] = 3003] = "VALUE_RANGE_FORMAT_INVALID";
|
|
28
|
+
SearchQueryErrorCode[SearchQueryErrorCode["VALUE_RANGE_OPERATOR_INVALID"] = 3004] = "VALUE_RANGE_OPERATOR_INVALID";
|
|
29
|
+
SearchQueryErrorCode[SearchQueryErrorCode["VALUE_RANGE_MISSING"] = 3005] = "VALUE_RANGE_MISSING";
|
|
30
|
+
SearchQueryErrorCode[SearchQueryErrorCode["VALUE_RANGE_START_EXCEEDS_END"] = 3006] = "VALUE_RANGE_START_EXCEEDS_END";
|
|
31
|
+
SearchQueryErrorCode[SearchQueryErrorCode["VALUE_WILDCARD_NOT_PERMITTED"] = 3007] = "VALUE_WILDCARD_NOT_PERMITTED";
|
|
31
32
|
// Wildcard Errors (4000-4999)
|
|
32
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
33
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
33
|
+
SearchQueryErrorCode[SearchQueryErrorCode["WILDCARD_POSITION_INVALID"] = 4001] = "WILDCARD_POSITION_INVALID";
|
|
34
|
+
SearchQueryErrorCode[SearchQueryErrorCode["WILDCARD_MULTIPLE_NOT_PERMITTED"] = 4002] = "WILDCARD_MULTIPLE_NOT_PERMITTED";
|
|
34
35
|
// IN Expression Errors (5000-5999)
|
|
35
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
36
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
37
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
38
|
-
SearchQueryErrorCode[SearchQueryErrorCode["
|
|
36
|
+
SearchQueryErrorCode[SearchQueryErrorCode["IN_LIST_EMPTY"] = 5001] = "IN_LIST_EMPTY";
|
|
37
|
+
SearchQueryErrorCode[SearchQueryErrorCode["IN_VALUE_INVALID"] = 5002] = "IN_VALUE_INVALID";
|
|
38
|
+
SearchQueryErrorCode[SearchQueryErrorCode["IN_SEPARATOR_MISSING"] = 5003] = "IN_SEPARATOR_MISSING";
|
|
39
|
+
SearchQueryErrorCode[SearchQueryErrorCode["IN_LPAREN_MISSING"] = 5004] = "IN_LPAREN_MISSING";
|
|
39
40
|
})(SearchQueryErrorCode || (exports.SearchQueryErrorCode = SearchQueryErrorCode = {}));
|
|
40
41
|
exports.reservedWords = new Set(["AND", "OR"]);
|
|
41
42
|
const walkExpression = (expr, errors) => {
|
|
@@ -31,7 +31,7 @@ export const parseExpression = (stream, minPrecedence = 0) => {
|
|
|
31
31
|
if (nextToken.type === TokenType.EOF) {
|
|
32
32
|
throw {
|
|
33
33
|
message: `Unexpected token: ${token.value}`,
|
|
34
|
-
code: SearchQueryErrorCode.
|
|
34
|
+
code: SearchQueryErrorCode.SYNTAX_TOKEN_UNEXPECTED,
|
|
35
35
|
value: token.value,
|
|
36
36
|
position: token.position,
|
|
37
37
|
length: token.length,
|
package/dist/esm/lexer.js
CHANGED
|
@@ -93,7 +93,7 @@ const tokenizeQuotedString = (input, position) => {
|
|
|
93
93
|
}
|
|
94
94
|
throw {
|
|
95
95
|
message: "Unterminated quoted string",
|
|
96
|
-
code: SearchQueryErrorCode.
|
|
96
|
+
code: SearchQueryErrorCode.SYNTAX_QUOTE_UNTERMINATED,
|
|
97
97
|
position,
|
|
98
98
|
length,
|
|
99
99
|
};
|
|
@@ -260,7 +260,7 @@ export const tokenize = (input) => {
|
|
|
260
260
|
prevToken.type === TokenType.STRING)) {
|
|
261
261
|
throw {
|
|
262
262
|
message: "Invalid syntax: Missing operator or whitespace between terms",
|
|
263
|
-
code: SearchQueryErrorCode.
|
|
263
|
+
code: SearchQueryErrorCode.SYNTAX_OPERATOR_OR_SPACE_MISSING,
|
|
264
264
|
position: position,
|
|
265
265
|
length: 1,
|
|
266
266
|
};
|
|
@@ -273,7 +273,7 @@ export const tokenize = (input) => {
|
|
|
273
273
|
!isSpecialChar(input[newPos])) {
|
|
274
274
|
throw {
|
|
275
275
|
message: "Invalid syntax: Missing operator or whitespace between terms",
|
|
276
|
-
code: SearchQueryErrorCode.
|
|
276
|
+
code: SearchQueryErrorCode.SYNTAX_OPERATOR_OR_SPACE_MISSING,
|
|
277
277
|
position: newPos,
|
|
278
278
|
length: 1,
|
|
279
279
|
};
|
|
@@ -7,7 +7,7 @@ export const parseInValues = (stream, inValuePosition) => {
|
|
|
7
7
|
if (currentToken(currentStream).type !== TokenType.LPAREN) {
|
|
8
8
|
throw {
|
|
9
9
|
message: "Expected '(' after IN",
|
|
10
|
-
code: SearchQueryErrorCode.
|
|
10
|
+
code: SearchQueryErrorCode.IN_LPAREN_MISSING,
|
|
11
11
|
position: inValuePosition, // Use the position passed from the caller
|
|
12
12
|
length: 1,
|
|
13
13
|
};
|
|
@@ -19,7 +19,7 @@ export const parseInValues = (stream, inValuePosition) => {
|
|
|
19
19
|
if (values.length === 0) {
|
|
20
20
|
throw {
|
|
21
21
|
message: "IN operator requires at least one value",
|
|
22
|
-
code: SearchQueryErrorCode.
|
|
22
|
+
code: SearchQueryErrorCode.IN_LIST_EMPTY,
|
|
23
23
|
position: token.position,
|
|
24
24
|
length: 1,
|
|
25
25
|
};
|
|
@@ -36,7 +36,7 @@ export const parseInValues = (stream, inValuePosition) => {
|
|
|
36
36
|
token.type !== TokenType.COMMA)) {
|
|
37
37
|
throw {
|
|
38
38
|
message: "Expected ',' or ')' after IN value",
|
|
39
|
-
code: SearchQueryErrorCode.
|
|
39
|
+
code: SearchQueryErrorCode.IN_SEPARATOR_MISSING,
|
|
40
40
|
position: token.position,
|
|
41
41
|
length: 1,
|
|
42
42
|
};
|
|
@@ -56,7 +56,7 @@ export const parseInValues = (stream, inValuePosition) => {
|
|
|
56
56
|
}
|
|
57
57
|
throw {
|
|
58
58
|
message: "Expected ',' or ')' after IN value",
|
|
59
|
-
code: SearchQueryErrorCode.
|
|
59
|
+
code: SearchQueryErrorCode.IN_SEPARATOR_MISSING,
|
|
60
60
|
position: nextToken.position,
|
|
61
61
|
length: 1,
|
|
62
62
|
};
|
|
@@ -7,7 +7,7 @@ export const expectToken = (stream, type, message) => {
|
|
|
7
7
|
if (token.type !== type) {
|
|
8
8
|
throw {
|
|
9
9
|
message: message ? message : `Expected ${type}`,
|
|
10
|
-
code: SearchQueryErrorCode.
|
|
10
|
+
code: SearchQueryErrorCode.SYNTAX_TOKEN_MISSING,
|
|
11
11
|
value: type,
|
|
12
12
|
position: token.position,
|
|
13
13
|
length: token.length,
|
|
@@ -131,7 +131,7 @@ export const parsePrimary = (stream) => {
|
|
|
131
131
|
case TokenType.OR:
|
|
132
132
|
throw {
|
|
133
133
|
message: `${token.value} is a reserved word`,
|
|
134
|
-
code: SearchQueryErrorCode.
|
|
134
|
+
code: SearchQueryErrorCode.SYNTAX_KEYWORD_RESERVED,
|
|
135
135
|
value: token.value,
|
|
136
136
|
position: token.position,
|
|
137
137
|
length: token.length,
|
|
@@ -139,14 +139,14 @@ export const parsePrimary = (stream) => {
|
|
|
139
139
|
case TokenType.RPAREN:
|
|
140
140
|
throw {
|
|
141
141
|
message: 'Unexpected ")"',
|
|
142
|
-
code: SearchQueryErrorCode.
|
|
142
|
+
code: SearchQueryErrorCode.SYNTAX_PARENTHESIS_UNEXPECTED,
|
|
143
143
|
position: token.position,
|
|
144
144
|
length: token.length,
|
|
145
145
|
};
|
|
146
146
|
default:
|
|
147
147
|
throw {
|
|
148
148
|
message: "Unexpected token",
|
|
149
|
-
code: SearchQueryErrorCode.
|
|
149
|
+
code: SearchQueryErrorCode.SYNTAX_TOKEN_UNEXPECTED,
|
|
150
150
|
position: token.position,
|
|
151
151
|
length: token.length,
|
|
152
152
|
};
|
package/dist/esm/parser.js
CHANGED
|
@@ -43,7 +43,7 @@ export const parseSearchInputQuery = (input, fieldSchemas = []) => {
|
|
|
43
43
|
if (finalToken.type !== TokenType.EOF) {
|
|
44
44
|
throw {
|
|
45
45
|
message: 'Unexpected ")"',
|
|
46
|
-
code: SearchQueryErrorCode.
|
|
46
|
+
code: SearchQueryErrorCode.SYNTAX_PARENTHESIS_UNEXPECTED,
|
|
47
47
|
position: finalToken.position,
|
|
48
48
|
length: finalToken.length,
|
|
49
49
|
};
|