qast 1.1.0 → 1.2.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 +52 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -11
- package/dist/index.js.map +1 -1
- package/dist/parser/validator.d.ts +5 -1
- package/dist/parser/validator.d.ts.map +1 -1
- package/dist/parser/validator.js +67 -0
- package/dist/parser/validator.js.map +1 -1
- package/dist/types/ast.d.ts +43 -0
- package/dist/types/ast.d.ts.map +1 -1
- package/package.json +7 -8
package/README.md
CHANGED
|
@@ -232,6 +232,11 @@ Parse a query string into an AST.
|
|
|
232
232
|
- `allowedFields?: string[]` - Whitelist of allowed field names
|
|
233
233
|
- `allowedOperators?: Operator[]` - Whitelist of allowed operators
|
|
234
234
|
- `validate?: boolean` - Whether to validate against whitelists (default: true if whitelists are provided)
|
|
235
|
+
- `maxDepth?: number` - Maximum allowed AST depth (to limit nested logical expressions)
|
|
236
|
+
- `maxNodes?: number` - Maximum allowed number of AST nodes (to limit overall query complexity)
|
|
237
|
+
- `maxQueryLength?: number` - Maximum allowed length of the raw query string (checked before parsing)
|
|
238
|
+
- `maxArrayLength?: number` - Maximum allowed length of array values (for `in` operator)
|
|
239
|
+
- `maxStringLength?: number` - Maximum allowed length of string values
|
|
235
240
|
|
|
236
241
|
**Returns:** The parsed AST node
|
|
237
242
|
|
|
@@ -241,6 +246,11 @@ const ast = parseQuery('age gt 25', {
|
|
|
241
246
|
allowedFields: ['age', 'name'],
|
|
242
247
|
allowedOperators: ['gt', 'eq'],
|
|
243
248
|
validate: true,
|
|
249
|
+
maxDepth: 5,
|
|
250
|
+
maxNodes: 50,
|
|
251
|
+
maxQueryLength: 1000,
|
|
252
|
+
maxArrayLength: 100,
|
|
253
|
+
maxStringLength: 200,
|
|
244
254
|
});
|
|
245
255
|
```
|
|
246
256
|
|
|
@@ -290,6 +300,33 @@ Extract all operators used in an AST.
|
|
|
290
300
|
|
|
291
301
|
**Returns:** Array of unique operators
|
|
292
302
|
|
|
303
|
+
### `validateQueryComplexity(ast: QastNode, options: ComplexityOptions): void`
|
|
304
|
+
|
|
305
|
+
Validate an AST against complexity limits.
|
|
306
|
+
|
|
307
|
+
**Parameters:**
|
|
308
|
+
- `ast` - The AST to validate
|
|
309
|
+
- `options` - Complexity options:
|
|
310
|
+
- `maxDepth?: number` - Maximum allowed AST depth
|
|
311
|
+
- `maxNodes?: number` - Maximum allowed number of nodes
|
|
312
|
+
- `maxArrayLength?: number` - Maximum allowed array length
|
|
313
|
+
- `maxStringLength?: number` - Maximum allowed string length
|
|
314
|
+
|
|
315
|
+
**Throws:** `ValidationError` if any limit is exceeded
|
|
316
|
+
|
|
317
|
+
**Example:**
|
|
318
|
+
```typescript
|
|
319
|
+
import { parseQuery, validateQueryComplexity } from 'qast';
|
|
320
|
+
|
|
321
|
+
const ast = parseQuery('age in [1,2,3,4,5]');
|
|
322
|
+
validateQueryComplexity(ast, {
|
|
323
|
+
maxDepth: 5,
|
|
324
|
+
maxNodes: 20,
|
|
325
|
+
maxArrayLength: 100,
|
|
326
|
+
maxStringLength: 200,
|
|
327
|
+
});
|
|
328
|
+
```
|
|
329
|
+
|
|
293
330
|
## Security Best Practices
|
|
294
331
|
|
|
295
332
|
1. **Always use whitelists**: Restrict which fields and operators can be used in queries.
|
|
@@ -304,7 +341,21 @@ const ast = parseQuery(req.query.filter, {
|
|
|
304
341
|
|
|
305
342
|
2. **Validate user input**: Don't trust user-provided query strings without validation.
|
|
306
343
|
|
|
307
|
-
3. **Limit query complexity**:
|
|
344
|
+
3. **Limit query complexity**: Use complexity limits to prevent DoS attacks.
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
const ast = parseQuery(req.query.filter, {
|
|
348
|
+
allowedFields: ['age', 'name', 'city'],
|
|
349
|
+
allowedOperators: ['gt', 'eq', 'lt', 'in'],
|
|
350
|
+
validate: true,
|
|
351
|
+
// Complexity limits
|
|
352
|
+
maxQueryLength: 1000, // Reject queries longer than 1000 chars
|
|
353
|
+
maxDepth: 5, // Max 5 levels of nesting
|
|
354
|
+
maxNodes: 20, // Max 20 conditions
|
|
355
|
+
maxArrayLength: 100, // Max 100 items in 'in' arrays
|
|
356
|
+
maxStringLength: 200, // Max 200 chars per string value
|
|
357
|
+
});
|
|
358
|
+
```
|
|
308
359
|
|
|
309
360
|
4. **Use type checking**: Ensure values match expected types for fields.
|
|
310
361
|
|
package/dist/index.d.ts
CHANGED
|
@@ -6,18 +6,18 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { parseQueryString } from './parser/parser';
|
|
8
8
|
export { Tokenizer, Token, TokenType } from './parser/tokenizer';
|
|
9
|
-
export { validateQuery, extractFields, extractOperators } from './parser/validator';
|
|
9
|
+
export { validateQuery, validateQueryComplexity, extractFields, extractOperators, } from './parser/validator';
|
|
10
10
|
export { toPrismaFilter, PrismaFilter } from './adapters/prisma';
|
|
11
11
|
export { toTypeORMFilter, TypeORMFilter } from './adapters/typeorm';
|
|
12
12
|
export { toSequelizeFilter, SequelizeFilter } from './adapters/sequelize';
|
|
13
|
-
export { QastNode, ComparisonNode, LogicalNode, LogicalOperator, Operator, QastValue, ParseOptions, WhitelistOptions, isComparisonNode, isLogicalNode, } from './types/ast';
|
|
13
|
+
export { QastNode, ComparisonNode, LogicalNode, LogicalOperator, Operator, QastValue, ParseOptions, WhitelistOptions, ComplexityOptions, isComparisonNode, isLogicalNode, } from './types/ast';
|
|
14
14
|
export { QastError, ParseError, ValidationError, TokenizationError, } from './errors';
|
|
15
15
|
import { ParseOptions, QastNode } from './types/ast';
|
|
16
16
|
/**
|
|
17
17
|
* Parse a query string into an AST
|
|
18
18
|
*
|
|
19
19
|
* @param query - The query string to parse (e.g., 'age gt 25 and name eq "John"')
|
|
20
|
-
* @param options - Optional parsing options (whitelisting, validation)
|
|
20
|
+
* @param options - Optional parsing options (whitelisting, validation, complexity limits)
|
|
21
21
|
* @returns The parsed AST node
|
|
22
22
|
*
|
|
23
23
|
* @example
|
|
@@ -31,6 +31,11 @@ import { ParseOptions, QastNode } from './types/ast';
|
|
|
31
31
|
* allowedFields: ['age', 'name'],
|
|
32
32
|
* allowedOperators: ['gt', 'eq'],
|
|
33
33
|
* validate: true,
|
|
34
|
+
* maxDepth: 5,
|
|
35
|
+
* maxNodes: 50,
|
|
36
|
+
* maxQueryLength: 1000,
|
|
37
|
+
* maxArrayLength: 100,
|
|
38
|
+
* maxStringLength: 200,
|
|
34
39
|
* });
|
|
35
40
|
* ```
|
|
36
41
|
*/
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGjE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGjE,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,aAAa,EACb,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG1E,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,eAAe,EACf,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,GACd,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,SAAS,EACT,UAAU,EACV,eAAe,EACf,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAKlB,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAoB,MAAM,aAAa,CAAC;AAGvE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,QAAQ,CA0C1E"}
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* and transforms them into ORM-compatible filter objects.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.TokenizationError = exports.ValidationError = exports.ParseError = exports.QastError = exports.isLogicalNode = exports.isComparisonNode = exports.toSequelizeFilter = exports.toTypeORMFilter = exports.toPrismaFilter = exports.extractOperators = exports.extractFields = exports.validateQuery = exports.TokenType = exports.Tokenizer = exports.parseQueryString = void 0;
|
|
9
|
+
exports.TokenizationError = exports.ValidationError = exports.ParseError = exports.QastError = exports.isLogicalNode = exports.isComparisonNode = exports.toSequelizeFilter = exports.toTypeORMFilter = exports.toPrismaFilter = exports.extractOperators = exports.extractFields = exports.validateQueryComplexity = exports.validateQuery = exports.TokenType = exports.Tokenizer = exports.parseQueryString = void 0;
|
|
10
10
|
exports.parseQuery = parseQuery;
|
|
11
11
|
// Export parser
|
|
12
12
|
var parser_1 = require("./parser/parser");
|
|
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "TokenType", { enumerable: true, get: function ()
|
|
|
17
17
|
// Export validators
|
|
18
18
|
var validator_1 = require("./parser/validator");
|
|
19
19
|
Object.defineProperty(exports, "validateQuery", { enumerable: true, get: function () { return validator_1.validateQuery; } });
|
|
20
|
+
Object.defineProperty(exports, "validateQueryComplexity", { enumerable: true, get: function () { return validator_1.validateQueryComplexity; } });
|
|
20
21
|
Object.defineProperty(exports, "extractFields", { enumerable: true, get: function () { return validator_1.extractFields; } });
|
|
21
22
|
Object.defineProperty(exports, "extractOperators", { enumerable: true, get: function () { return validator_1.extractOperators; } });
|
|
22
23
|
// Export adapters
|
|
@@ -39,11 +40,12 @@ Object.defineProperty(exports, "TokenizationError", { enumerable: true, get: fun
|
|
|
39
40
|
// Main parse function with options
|
|
40
41
|
const parser_2 = require("./parser/parser");
|
|
41
42
|
const validator_2 = require("./parser/validator");
|
|
43
|
+
const errors_2 = require("./errors");
|
|
42
44
|
/**
|
|
43
45
|
* Parse a query string into an AST
|
|
44
46
|
*
|
|
45
47
|
* @param query - The query string to parse (e.g., 'age gt 25 and name eq "John"')
|
|
46
|
-
* @param options - Optional parsing options (whitelisting, validation)
|
|
48
|
+
* @param options - Optional parsing options (whitelisting, validation, complexity limits)
|
|
47
49
|
* @returns The parsed AST node
|
|
48
50
|
*
|
|
49
51
|
* @example
|
|
@@ -57,20 +59,44 @@ const validator_2 = require("./parser/validator");
|
|
|
57
59
|
* allowedFields: ['age', 'name'],
|
|
58
60
|
* allowedOperators: ['gt', 'eq'],
|
|
59
61
|
* validate: true,
|
|
62
|
+
* maxDepth: 5,
|
|
63
|
+
* maxNodes: 50,
|
|
64
|
+
* maxQueryLength: 1000,
|
|
65
|
+
* maxArrayLength: 100,
|
|
66
|
+
* maxStringLength: 200,
|
|
60
67
|
* });
|
|
61
68
|
* ```
|
|
62
69
|
*/
|
|
63
70
|
function parseQuery(query, options) {
|
|
71
|
+
// Check query string length before parsing (early rejection)
|
|
72
|
+
if (options?.maxQueryLength !== undefined && query.length > options.maxQueryLength) {
|
|
73
|
+
throw new errors_2.ValidationError(`Query string is too long (${query.length} characters) - maximum allowed is ${options.maxQueryLength}`);
|
|
74
|
+
}
|
|
64
75
|
const ast = (0, parser_2.parseQueryString)(query);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
(
|
|
76
|
+
if (options) {
|
|
77
|
+
// Validate against whitelists if enabled
|
|
78
|
+
if (options.validate !== false) {
|
|
79
|
+
const whitelist = {
|
|
80
|
+
allowedFields: options.allowedFields,
|
|
81
|
+
allowedOperators: options.allowedOperators,
|
|
82
|
+
};
|
|
83
|
+
// Only validate if whitelists are provided
|
|
84
|
+
if (whitelist.allowedFields || whitelist.allowedOperators) {
|
|
85
|
+
(0, validator_2.validateQuery)(ast, whitelist);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Enforce complexity limits if configured
|
|
89
|
+
const hasComplexityLimits = options.maxDepth !== undefined ||
|
|
90
|
+
options.maxNodes !== undefined ||
|
|
91
|
+
options.maxArrayLength !== undefined ||
|
|
92
|
+
options.maxStringLength !== undefined;
|
|
93
|
+
if (hasComplexityLimits) {
|
|
94
|
+
(0, validator_2.validateQueryComplexity)(ast, {
|
|
95
|
+
maxDepth: options.maxDepth,
|
|
96
|
+
maxNodes: options.maxNodes,
|
|
97
|
+
maxArrayLength: options.maxArrayLength,
|
|
98
|
+
maxStringLength: options.maxStringLength,
|
|
99
|
+
});
|
|
74
100
|
}
|
|
75
101
|
}
|
|
76
102
|
return ast;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AA0EH,gCA0CC;AAlHD,gBAAgB;AAChB,0CAAmD;AAA1C,0GAAA,gBAAgB,OAAA;AACzB,gDAAiE;AAAxD,sGAAA,SAAS,OAAA;AAAS,sGAAA,SAAS,OAAA;AAEpC,oBAAoB;AACpB,gDAK4B;AAJ1B,0GAAA,aAAa,OAAA;AACb,oHAAA,uBAAuB,OAAA;AACvB,0GAAA,aAAa,OAAA;AACb,6GAAA,gBAAgB,OAAA;AAGlB,kBAAkB;AAClB,4CAAiE;AAAxD,wGAAA,cAAc,OAAA;AACvB,8CAAoE;AAA3D,0GAAA,eAAe,OAAA;AACxB,kDAA0E;AAAjE,8GAAA,iBAAiB,OAAA;AAE1B,eAAe;AACf,mCAYqB;AAFnB,uGAAA,gBAAgB,OAAA;AAChB,oGAAA,aAAa,OAAA;AAGf,gBAAgB;AAChB,mCAKkB;AAJhB,mGAAA,SAAS,OAAA;AACT,oGAAA,UAAU,OAAA;AACV,yGAAA,eAAe,OAAA;AACf,2GAAA,iBAAiB,OAAA;AAGnB,mCAAmC;AACnC,4CAAmD;AACnD,kDAA4E;AAE5E,qCAA2C;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,SAAgB,UAAU,CAAC,KAAa,EAAE,OAAsB;IAC9D,6DAA6D;IAC7D,IAAI,OAAO,EAAE,cAAc,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;QACnF,MAAM,IAAI,wBAAe,CACvB,6BAA6B,KAAK,CAAC,MAAM,qCAAqC,OAAO,CAAC,cAAc,EAAE,CACvG,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,IAAA,yBAAgB,EAAC,KAAK,CAAC,CAAC;IAEpC,IAAI,OAAO,EAAE,CAAC;QACZ,yCAAyC;QACzC,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAqB;gBAClC,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;aAC3C,CAAC;YAEF,2CAA2C;YAC3C,IAAI,SAAS,CAAC,aAAa,IAAI,SAAS,CAAC,gBAAgB,EAAE,CAAC;gBAC1D,IAAA,yBAAa,EAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;QAED,0CAA0C;QAC1C,MAAM,mBAAmB,GACvB,OAAO,CAAC,QAAQ,KAAK,SAAS;YAC9B,OAAO,CAAC,QAAQ,KAAK,SAAS;YAC9B,OAAO,CAAC,cAAc,KAAK,SAAS;YACpC,OAAO,CAAC,eAAe,KAAK,SAAS,CAAC;QAExC,IAAI,mBAAmB,EAAE,CAAC;YACxB,IAAA,mCAAuB,EAAC,GAAG,EAAE;gBAC3B,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,eAAe,EAAE,OAAO,CAAC,eAAe;aACzC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { QastNode, WhitelistOptions, Operator } from '../types/ast';
|
|
1
|
+
import { QastNode, WhitelistOptions, ComplexityOptions, Operator } from '../types/ast';
|
|
2
2
|
/**
|
|
3
3
|
* Validate an AST against whitelist options
|
|
4
4
|
*/
|
|
5
5
|
export declare function validateQuery(ast: QastNode, whitelist: WhitelistOptions): void;
|
|
6
|
+
/**
|
|
7
|
+
* Validate query complexity (depth, node count, array lengths, string lengths)
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateQueryComplexity(ast: QastNode, options: ComplexityOptions): void;
|
|
6
10
|
/**
|
|
7
11
|
* Extract all fields used in an AST
|
|
8
12
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/parser/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAA+B,gBAAgB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/parser/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAA+B,gBAAgB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAIpH;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAE9E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAmBvF;AAqGD;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,EAAE,CAIrD;AAcD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAI1D"}
|
package/dist/parser/validator.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.validateQuery = validateQuery;
|
|
4
|
+
exports.validateQueryComplexity = validateQueryComplexity;
|
|
4
5
|
exports.extractFields = extractFields;
|
|
5
6
|
exports.extractOperators = extractOperators;
|
|
6
7
|
const errors_1 = require("../errors");
|
|
@@ -11,6 +12,54 @@ const ast_1 = require("../types/ast");
|
|
|
11
12
|
function validateQuery(ast, whitelist) {
|
|
12
13
|
validateNode(ast, whitelist);
|
|
13
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Validate query complexity (depth, node count, array lengths, string lengths)
|
|
17
|
+
*/
|
|
18
|
+
function validateQueryComplexity(ast, options) {
|
|
19
|
+
const { depth, nodes } = computeComplexity(ast);
|
|
20
|
+
if (options.maxDepth !== undefined && depth > options.maxDepth) {
|
|
21
|
+
throw new errors_1.ValidationError(`Query is too deeply nested (depth ${depth}) - maximum allowed depth is ${options.maxDepth}`);
|
|
22
|
+
}
|
|
23
|
+
if (options.maxNodes !== undefined && nodes > options.maxNodes) {
|
|
24
|
+
throw new errors_1.ValidationError(`Query is too complex (node count ${nodes}) - maximum allowed nodes is ${options.maxNodes}`);
|
|
25
|
+
}
|
|
26
|
+
// Validate array and string lengths in values
|
|
27
|
+
if (options.maxArrayLength !== undefined || options.maxStringLength !== undefined) {
|
|
28
|
+
validateValueLimits(ast, options);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Recursively validate value limits (array lengths, string lengths)
|
|
33
|
+
*/
|
|
34
|
+
function validateValueLimits(node, options) {
|
|
35
|
+
if ((0, ast_1.isComparisonNode)(node)) {
|
|
36
|
+
const { value, field } = node;
|
|
37
|
+
// Check array length
|
|
38
|
+
if (options.maxArrayLength !== undefined && Array.isArray(value)) {
|
|
39
|
+
if (value.length > options.maxArrayLength) {
|
|
40
|
+
throw new errors_1.ValidationError(`Array value for field '${field}' has ${value.length} items - maximum allowed is ${options.maxArrayLength}`, field);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Check string length
|
|
44
|
+
if (options.maxStringLength !== undefined && typeof value === 'string') {
|
|
45
|
+
if (value.length > options.maxStringLength) {
|
|
46
|
+
throw new errors_1.ValidationError(`String value for field '${field}' has ${value.length} characters - maximum allowed is ${options.maxStringLength}`, field);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Check string lengths inside arrays
|
|
50
|
+
if (options.maxStringLength !== undefined && Array.isArray(value)) {
|
|
51
|
+
for (const item of value) {
|
|
52
|
+
if (typeof item === 'string' && item.length > options.maxStringLength) {
|
|
53
|
+
throw new errors_1.ValidationError(`String value in array for field '${field}' has ${item.length} characters - maximum allowed is ${options.maxStringLength}`, field);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else if ((0, ast_1.isLogicalNode)(node)) {
|
|
59
|
+
validateValueLimits(node.left, options);
|
|
60
|
+
validateValueLimits(node.right, options);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
14
63
|
/**
|
|
15
64
|
* Recursively validate a node
|
|
16
65
|
*/
|
|
@@ -91,4 +140,22 @@ function extractOperatorsRecursive(node, operators) {
|
|
|
91
140
|
extractOperatorsRecursive(node.right, operators);
|
|
92
141
|
}
|
|
93
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Compute depth and node count for a query AST
|
|
145
|
+
*/
|
|
146
|
+
function computeComplexity(node) {
|
|
147
|
+
if ((0, ast_1.isComparisonNode)(node)) {
|
|
148
|
+
return { depth: 1, nodes: 1 };
|
|
149
|
+
}
|
|
150
|
+
if ((0, ast_1.isLogicalNode)(node)) {
|
|
151
|
+
const left = computeComplexity(node.left);
|
|
152
|
+
const right = computeComplexity(node.right);
|
|
153
|
+
return {
|
|
154
|
+
depth: 1 + Math.max(left.depth, right.depth),
|
|
155
|
+
nodes: 1 + left.nodes + right.nodes,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
// Fallback (should not happen with current QastNode types)
|
|
159
|
+
return { depth: 1, nodes: 1 };
|
|
160
|
+
}
|
|
94
161
|
//# sourceMappingURL=validator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/parser/validator.ts"],"names":[],"mappings":";;AAOA,sCAEC;
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/parser/validator.ts"],"names":[],"mappings":"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"}
|
package/dist/types/ast.d.ts
CHANGED
|
@@ -55,6 +55,28 @@ export interface ParseOptions {
|
|
|
55
55
|
* Whether to validate the query against whitelists after parsing
|
|
56
56
|
*/
|
|
57
57
|
validate?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Maximum allowed depth of the AST (to limit nested logical expressions)
|
|
60
|
+
* e.g. a simple comparison has depth 1, `(a and b) or c` has depth 2.
|
|
61
|
+
*/
|
|
62
|
+
maxDepth?: number;
|
|
63
|
+
/**
|
|
64
|
+
* Maximum allowed number of nodes in the AST (to limit overall complexity)
|
|
65
|
+
* Each comparison or logical node counts as 1.
|
|
66
|
+
*/
|
|
67
|
+
maxNodes?: number;
|
|
68
|
+
/**
|
|
69
|
+
* Maximum allowed length of the raw query string (checked before parsing)
|
|
70
|
+
*/
|
|
71
|
+
maxQueryLength?: number;
|
|
72
|
+
/**
|
|
73
|
+
* Maximum allowed length of array values (for 'in' operator)
|
|
74
|
+
*/
|
|
75
|
+
maxArrayLength?: number;
|
|
76
|
+
/**
|
|
77
|
+
* Maximum allowed length of string values
|
|
78
|
+
*/
|
|
79
|
+
maxStringLength?: number;
|
|
58
80
|
}
|
|
59
81
|
/**
|
|
60
82
|
* Options for query validation
|
|
@@ -69,4 +91,25 @@ export interface WhitelistOptions {
|
|
|
69
91
|
*/
|
|
70
92
|
allowedOperators?: Operator[];
|
|
71
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Options for query complexity validation
|
|
96
|
+
*/
|
|
97
|
+
export interface ComplexityOptions {
|
|
98
|
+
/**
|
|
99
|
+
* Maximum allowed depth of the AST.
|
|
100
|
+
*/
|
|
101
|
+
maxDepth?: number;
|
|
102
|
+
/**
|
|
103
|
+
* Maximum allowed number of nodes in the AST.
|
|
104
|
+
*/
|
|
105
|
+
maxNodes?: number;
|
|
106
|
+
/**
|
|
107
|
+
* Maximum allowed length of array values (for 'in' operator).
|
|
108
|
+
*/
|
|
109
|
+
maxArrayLength?: number;
|
|
110
|
+
/**
|
|
111
|
+
* Maximum allowed length of string values.
|
|
112
|
+
*/
|
|
113
|
+
maxStringLength?: number;
|
|
114
|
+
}
|
|
72
115
|
//# sourceMappingURL=ast.d.ts.map
|
package/dist/types/ast.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/types/ast.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,UAAU,GAAG,YAAY,GAAG,UAAU,CAAC;AAEjH;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;AAE/E;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,IAAI,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,QAAQ,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,QAAQ,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,cAAc,CAAC;AAEpD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,IAAI,cAAc,CAEvE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,IAAI,WAAW,CAEjE;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB;;OAEG;IACH,gBAAgB,CAAC,EAAE,QAAQ,EAAE,CAAC;IAE9B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/types/ast.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,UAAU,GAAG,YAAY,GAAG,UAAU,CAAC;AAEjH;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;AAE/E;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,IAAI,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,QAAQ,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,QAAQ,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,cAAc,CAAC;AAEpD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,IAAI,cAAc,CAEvE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,IAAI,WAAW,CAEjE;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB;;OAEG;IACH,gBAAgB,CAAC,EAAE,QAAQ,EAAE,CAAC;IAE9B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB;;OAEG;IACH,gBAAgB,CAAC,EAAE,QAAQ,EAAE,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qast",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Query to AST to ORM - Parse human-readable query strings into AST and transform them into ORM-compatible filters",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -59,16 +59,15 @@
|
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@types/jest": "^29.5.0",
|
|
62
|
-
"@types/node": "^
|
|
63
|
-
"jest": "^
|
|
62
|
+
"@types/node": "^24.10.1",
|
|
63
|
+
"jest": "^30.2.0",
|
|
64
64
|
"ts-jest": "^29.1.0",
|
|
65
65
|
"typescript": "^5.0.0"
|
|
66
66
|
},
|
|
67
|
-
"dependencies": {},
|
|
68
67
|
"peerDependencies": {
|
|
69
68
|
"@prisma/client": "*",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
69
|
+
"sequelize": "*",
|
|
70
|
+
"typeorm": "*"
|
|
72
71
|
},
|
|
73
72
|
"peerDependenciesMeta": {
|
|
74
73
|
"@prisma/client": {
|
|
@@ -80,6 +79,6 @@
|
|
|
80
79
|
"sequelize": {
|
|
81
80
|
"optional": true
|
|
82
81
|
}
|
|
83
|
-
}
|
|
82
|
+
},
|
|
83
|
+
"dependencies": {}
|
|
84
84
|
}
|
|
85
|
-
|