search-input-query-parser 0.3.0 → 0.4.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/README.md CHANGED
@@ -20,7 +20,8 @@ import {
20
20
  const schemas: FieldSchema[] = [
21
21
  { name: 'title', type: 'string' },
22
22
  { name: 'price', type: 'number' },
23
- { name: 'date', type: 'date' }
23
+ { name: 'date', type: 'date' },
24
+ { name: 'in_stock', type: 'boolean' }
24
25
  ];
25
26
 
26
27
  // Parse a search query
@@ -58,7 +59,8 @@ const searchableColumns = ['title', 'description'];
58
59
  const schemas: FieldSchema[] = [
59
60
  { name: 'title', type: 'string' },
60
61
  { name: 'price', type: 'number' },
61
- { name: 'date', type: 'date' }
62
+ { name: 'date', type: 'date' },
63
+ { name: 'in_stock', type: 'boolean' }
62
64
  ];
63
65
 
64
66
  // Convert a search query to SQL
@@ -92,6 +92,19 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
92
92
  });
93
93
  }
94
94
  break;
95
+ case "boolean":
96
+ if (!["true", "false"].includes(value.toLowerCase())) {
97
+ errors.push({
98
+ message: "Invalid boolean value",
99
+ code: validator_1.SearchQueryErrorCode.VALUE_BOOLEAN_INVALID,
100
+ position: expr.position +
101
+ expr.field.length +
102
+ 3 +
103
+ index * (value.length + 1),
104
+ length: value.length,
105
+ });
106
+ }
107
+ break;
95
108
  }
96
109
  });
97
110
  }
@@ -100,7 +113,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
100
113
  case "WILDCARD": {
101
114
  // For wildcard patterns, validate against field type constraints
102
115
  const schema = schemas.get(expr.prefix.toLowerCase());
103
- if ((schema === null || schema === void 0 ? void 0 : schema.type) === "number" || (schema === null || schema === void 0 ? void 0 : schema.type) === "date") {
116
+ if ((schema === null || schema === void 0 ? void 0 : schema.type) === "number" || (schema === null || schema === void 0 ? void 0 : schema.type) === "date" || (schema === null || schema === void 0 ? void 0 : schema.type) === "boolean") {
104
117
  errors.push({
105
118
  code: validator_1.SearchQueryErrorCode.VALUE_WILDCARD_NOT_PERMITTED,
106
119
  value: schema.type,
@@ -239,6 +252,16 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
239
252
  }
240
253
  }
241
254
  }
255
+ if (schema.type === "boolean") {
256
+ if (!["true", "false"].includes(value.toLowerCase())) {
257
+ errors.push({
258
+ message: "Invalid boolean value",
259
+ code: validator_1.SearchQueryErrorCode.VALUE_BOOLEAN_INVALID,
260
+ position: valueStartPosition,
261
+ length: value.length,
262
+ });
263
+ }
264
+ }
242
265
  break;
243
266
  }
244
267
  }
@@ -29,6 +29,7 @@ var SearchQueryErrorCode;
29
29
  SearchQueryErrorCode[SearchQueryErrorCode["VALUE_RANGE_MISSING"] = 3005] = "VALUE_RANGE_MISSING";
30
30
  SearchQueryErrorCode[SearchQueryErrorCode["VALUE_RANGE_START_EXCEEDS_END"] = 3006] = "VALUE_RANGE_START_EXCEEDS_END";
31
31
  SearchQueryErrorCode[SearchQueryErrorCode["VALUE_WILDCARD_NOT_PERMITTED"] = 3007] = "VALUE_WILDCARD_NOT_PERMITTED";
32
+ SearchQueryErrorCode[SearchQueryErrorCode["VALUE_BOOLEAN_INVALID"] = 3008] = "VALUE_BOOLEAN_INVALID";
32
33
  // Wildcard Errors (4000-4999)
33
34
  SearchQueryErrorCode[SearchQueryErrorCode["WILDCARD_POSITION_INVALID"] = 4001] = "WILDCARD_POSITION_INVALID";
34
35
  SearchQueryErrorCode[SearchQueryErrorCode["WILDCARD_MULTIPLE_NOT_PERMITTED"] = 4002] = "WILDCARD_MULTIPLE_NOT_PERMITTED";
@@ -89,6 +89,19 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
89
89
  });
90
90
  }
91
91
  break;
92
+ case "boolean":
93
+ if (!["true", "false"].includes(value.toLowerCase())) {
94
+ errors.push({
95
+ message: "Invalid boolean value",
96
+ code: SearchQueryErrorCode.VALUE_BOOLEAN_INVALID,
97
+ position: expr.position +
98
+ expr.field.length +
99
+ 3 +
100
+ index * (value.length + 1),
101
+ length: value.length,
102
+ });
103
+ }
104
+ break;
92
105
  }
93
106
  });
94
107
  }
@@ -97,7 +110,7 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
97
110
  case "WILDCARD": {
98
111
  // For wildcard patterns, validate against field type constraints
99
112
  const schema = schemas.get(expr.prefix.toLowerCase());
100
- if ((schema === null || schema === void 0 ? void 0 : schema.type) === "number" || (schema === null || schema === void 0 ? void 0 : schema.type) === "date") {
113
+ if ((schema === null || schema === void 0 ? void 0 : schema.type) === "number" || (schema === null || schema === void 0 ? void 0 : schema.type) === "date" || (schema === null || schema === void 0 ? void 0 : schema.type) === "boolean") {
101
114
  errors.push({
102
115
  code: SearchQueryErrorCode.VALUE_WILDCARD_NOT_PERMITTED,
103
116
  value: schema.type,
@@ -236,6 +249,16 @@ const validateFieldValue = (expr, allowedFields, errors, schemas) => {
236
249
  }
237
250
  }
238
251
  }
252
+ if (schema.type === "boolean") {
253
+ if (!["true", "false"].includes(value.toLowerCase())) {
254
+ errors.push({
255
+ message: "Invalid boolean value",
256
+ code: SearchQueryErrorCode.VALUE_BOOLEAN_INVALID,
257
+ position: valueStartPosition,
258
+ length: value.length,
259
+ });
260
+ }
261
+ }
239
262
  break;
240
263
  }
241
264
  }
@@ -26,6 +26,7 @@ export var SearchQueryErrorCode;
26
26
  SearchQueryErrorCode[SearchQueryErrorCode["VALUE_RANGE_MISSING"] = 3005] = "VALUE_RANGE_MISSING";
27
27
  SearchQueryErrorCode[SearchQueryErrorCode["VALUE_RANGE_START_EXCEEDS_END"] = 3006] = "VALUE_RANGE_START_EXCEEDS_END";
28
28
  SearchQueryErrorCode[SearchQueryErrorCode["VALUE_WILDCARD_NOT_PERMITTED"] = 3007] = "VALUE_WILDCARD_NOT_PERMITTED";
29
+ SearchQueryErrorCode[SearchQueryErrorCode["VALUE_BOOLEAN_INVALID"] = 3008] = "VALUE_BOOLEAN_INVALID";
29
30
  // Wildcard Errors (4000-4999)
30
31
  SearchQueryErrorCode[SearchQueryErrorCode["WILDCARD_POSITION_INVALID"] = 4001] = "WILDCARD_POSITION_INVALID";
31
32
  SearchQueryErrorCode[SearchQueryErrorCode["WILDCARD_MULTIPLE_NOT_PERMITTED"] = 4002] = "WILDCARD_MULTIPLE_NOT_PERMITTED";
@@ -21,6 +21,7 @@ export declare enum SearchQueryErrorCode {
21
21
  VALUE_RANGE_MISSING = 3005,
22
22
  VALUE_RANGE_START_EXCEEDS_END = 3006,
23
23
  VALUE_WILDCARD_NOT_PERMITTED = 3007,
24
+ VALUE_BOOLEAN_INVALID = 3008,
24
25
  WILDCARD_POSITION_INVALID = 4001,
25
26
  WILDCARD_MULTIPLE_NOT_PERMITTED = 4002,
26
27
  IN_LIST_EMPTY = 5001,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "search-input-query-parser",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "A parser for advanced search query syntax with field:value support",
5
5
  "keywords": [
6
6
  "search",
@@ -33,6 +33,7 @@ describe("Search Query Parser", () => {
33
33
  { name: "amount", type: "number" },
34
34
  { name: "date", type: "date" },
35
35
  { name: "title", type: "string" },
36
+ { name: "in_stock", type: "boolean" },
36
37
  ];
37
38
 
38
39
  const testSchemaQuery = (input: string, expected: string) => {
@@ -334,6 +335,29 @@ describe("Search Query Parser", () => {
334
335
  });
335
336
  });
336
337
 
338
+ describe("Boolean field support", () => {
339
+ test("parses boolean values", () => {
340
+ testSchemaQuery("in_stock:true", "in_stock:true");
341
+ testSchemaQuery("in_stock:false", "in_stock:false");
342
+ });
343
+
344
+ test("parses boolean fields with other fields", () => {
345
+ testSchemaQuery("title:red AND in_stock:true", "(title:red AND in_stock:true)");
346
+ testSchemaQuery("in_stock:true AND amount:42", "(in_stock:true AND amount:42)");
347
+ });
348
+
349
+ test("parses boolean fields with complex expressions", () => {
350
+ testSchemaQuery(
351
+ "title:red AND in_stock:true OR amount:42",
352
+ "((title:red AND in_stock:true) OR amount:42)"
353
+ );
354
+ testSchemaQuery(
355
+ "title:red AND (in_stock:true OR amount:42)",
356
+ "(title:red AND (in_stock:true OR amount:42))"
357
+ );
358
+ });
359
+ });
360
+
337
361
  describe("Range Query Support", () => {
338
362
  test("parses comparison operators", () => {
339
363
  testSchemaQuery("price:>100", "price:>100");
@@ -750,6 +774,17 @@ describe("Search Query Parser", () => {
750
774
  },
751
775
  ]);
752
776
  });
777
+
778
+ test("handles invalid boolean values", () => {
779
+ testSchemaErrorQuery("in_stock:maybe", [
780
+ {
781
+ message: "Invalid boolean value",
782
+ code: SearchQueryErrorCode.VALUE_BOOLEAN_INVALID,
783
+ position: 9,
784
+ length: 5,
785
+ },
786
+ ]);
787
+ });
753
788
  });
754
789
 
755
790
  describe("Wildcard Error Cases", () => {
@@ -119,6 +119,20 @@ const validateFieldValue = (
119
119
  });
120
120
  }
121
121
  break;
122
+ case "boolean":
123
+ if (!["true", "false"].includes(value.toLowerCase())) {
124
+ errors.push({
125
+ message: "Invalid boolean value",
126
+ code: SearchQueryErrorCode.VALUE_BOOLEAN_INVALID,
127
+ position:
128
+ expr.position +
129
+ expr.field.length +
130
+ 3 +
131
+ index * (value.length + 1),
132
+ length: value.length,
133
+ });
134
+ }
135
+ break;
122
136
  }
123
137
  });
124
138
  }
@@ -128,7 +142,7 @@ const validateFieldValue = (
128
142
  case "WILDCARD": {
129
143
  // For wildcard patterns, validate against field type constraints
130
144
  const schema = schemas.get(expr.prefix.toLowerCase());
131
- if (schema?.type === "number" || schema?.type === "date") {
145
+ if (schema?.type === "number" || schema?.type === "date" || schema?.type === "boolean") {
132
146
  errors.push({
133
147
  code: SearchQueryErrorCode.VALUE_WILDCARD_NOT_PERMITTED,
134
148
  value: schema.type,
@@ -285,6 +299,16 @@ const validateFieldValue = (
285
299
  }
286
300
  }
287
301
  }
302
+ if (schema.type === "boolean") {
303
+ if (!["true", "false"].includes(value.toLowerCase())) {
304
+ errors.push({
305
+ message: "Invalid boolean value",
306
+ code: SearchQueryErrorCode.VALUE_BOOLEAN_INVALID,
307
+ position: valueStartPosition,
308
+ length: value.length,
309
+ });
310
+ }
311
+ }
288
312
  break;
289
313
  }
290
314
  }
package/src/validator.ts CHANGED
@@ -34,6 +34,7 @@ export enum SearchQueryErrorCode {
34
34
  VALUE_RANGE_MISSING = 3005,
35
35
  VALUE_RANGE_START_EXCEEDS_END = 3006,
36
36
  VALUE_WILDCARD_NOT_PERMITTED = 3007,
37
+ VALUE_BOOLEAN_INVALID = 3008,
37
38
 
38
39
  // Wildcard Errors (4000-4999)
39
40
  WILDCARD_POSITION_INVALID = 4001,