@webda/ql 4.0.0-beta.2 → 4.0.0-beta.3

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.
Files changed (48) hide show
  1. package/README.md +135 -2
  2. package/lib/WebdaQLLexer.d.ts +19 -13
  3. package/lib/WebdaQLLexer.d.ts.map +1 -1
  4. package/lib/WebdaQLLexer.js +305 -252
  5. package/lib/WebdaQLLexer.js.map +1 -1
  6. package/lib/WebdaQLParserLexer.d.ts +19 -13
  7. package/lib/WebdaQLParserLexer.d.ts.map +1 -1
  8. package/lib/WebdaQLParserLexer.js +305 -252
  9. package/lib/WebdaQLParserLexer.js.map +1 -1
  10. package/lib/WebdaQLParserListener.d.ts +89 -3
  11. package/lib/WebdaQLParserListener.d.ts.map +1 -1
  12. package/lib/WebdaQLParserListener.js +1 -1
  13. package/lib/WebdaQLParserListener.js.map +1 -1
  14. package/lib/WebdaQLParserParser.d.ts +83 -22
  15. package/lib/WebdaQLParserParser.d.ts.map +1 -1
  16. package/lib/WebdaQLParserParser.js +790 -290
  17. package/lib/WebdaQLParserParser.js.map +1 -1
  18. package/lib/WebdaQLParserVisitor.d.ts +65 -2
  19. package/lib/WebdaQLParserVisitor.d.ts.map +1 -1
  20. package/lib/WebdaQLParserVisitor.js +1 -1
  21. package/lib/WebdaQLParserVisitor.js.map +1 -1
  22. package/lib/bind.d.ts +29 -0
  23. package/lib/bind.d.ts.map +1 -0
  24. package/lib/bind.js +139 -0
  25. package/lib/bind.js.map +1 -0
  26. package/lib/bind.spec.d.ts +2 -0
  27. package/lib/bind.spec.d.ts.map +1 -0
  28. package/lib/bind.spec.js +206 -0
  29. package/lib/bind.spec.js.map +1 -0
  30. package/lib/index.d.ts +4 -0
  31. package/lib/index.d.ts.map +1 -0
  32. package/lib/index.js +4 -0
  33. package/lib/index.js.map +1 -0
  34. package/lib/query.d.ts +395 -76
  35. package/lib/query.d.ts.map +1 -1
  36. package/lib/query.js +562 -91
  37. package/lib/query.js.map +1 -1
  38. package/lib/query.spec.js +593 -195
  39. package/lib/query.spec.js.map +1 -1
  40. package/lib/webdaql-string.d.ts +59 -0
  41. package/lib/webdaql-string.d.ts.map +1 -0
  42. package/lib/webdaql-string.js +112 -0
  43. package/lib/webdaql-string.js.map +1 -0
  44. package/lib/webdaql-string.spec.d.ts +2 -0
  45. package/lib/webdaql-string.spec.d.ts.map +1 -0
  46. package/lib/webdaql-string.spec.js +282 -0
  47. package/lib/webdaql-string.spec.js.map +1 -0
  48. package/package.json +30 -42
package/lib/query.d.ts CHANGED
@@ -1,76 +1,123 @@
1
1
  import { AbstractParseTreeVisitor, ParseTree } from "antlr4ts/tree/index.js";
2
2
  import { WebdaQLLexer } from "./WebdaQLLexer.js";
3
- import { AndLogicExpressionContext, BinaryComparisonExpressionContext, BooleanLiteralContext, ContainsExpressionContext, InExpressionContext, IntegerLiteralContext, LikeExpressionContext, LimitExpressionContext, OffsetExpressionContext, OrLogicExpressionContext, OrderExpressionContext, OrderFieldExpressionContext, SetExpressionContext, StringLiteralContext, WebdaqlContext } from "./WebdaQLParserParser.js";
3
+ import { AndLogicExpressionContext, AtomExpressionContext, BinaryComparisonExpressionContext, BooleanLiteralContext, ContainsExpressionContext, InExpressionContext, IntegerLiteralContext, IsNotNullExpressionContext, IsNullExpressionContext, LikeExpressionContext, LimitExpressionContext, NumberLiteralContext, OffsetExpressionContext, OrLogicExpressionContext, OrderExpressionContext, OrderFieldExpressionContext, ParameterContext, SetExpressionContext, StringLiteralContext, WebdaqlContext } from "./WebdaQLParserParser.js";
4
4
  import { WebdaQLParserVisitor } from "./WebdaQLParserVisitor.js";
5
+ /**
6
+ * Primitive value types supported by WebdaQL expressions
7
+ */
5
8
  type value = boolean | string | number;
6
9
  /**
7
- * Meta Query Language
10
+ * Strip the quotes of a WebdaQL string literal and unescape its contents.
8
11
  *
12
+ * Processes the inner text (between outer quotes) with these rules, applied left-to-right:
13
+ * - `\\` → `\` (escaped backslash)
14
+ * - `\` followed by the literal's quote char → the quote char (backslash-escaped quote)
15
+ * - the quote char doubled → one quote char (SQL-style doubled quote)
16
+ * - any other `\x` → `\x` kept verbatim (so LIKE's `\%` and `\_` reach likeToRegex unchanged)
9
17
  *
18
+ * @param literal - the literal including its surrounding quotes
19
+ * @returns the literal value
20
+ */
21
+ export declare function unescapeStringLiteral(literal: string): string;
22
+ /**
23
+ * Represents a single ORDER BY clause field with its sort direction
10
24
  */
11
25
  export interface OrderBy {
26
+ /** Field name (supports dot-notation for nested attributes) */
12
27
  field: string;
28
+ /** Sort direction */
13
29
  direction: "ASC" | "DESC";
14
30
  }
31
+ /**
32
+ * Prepend a condition to an existing query string using AND logic
33
+ *
34
+ * Parses both strings, merges them, and reconstructs the combined query.
35
+ * ORDER BY, LIMIT, and OFFSET clauses from the original query are preserved.
36
+ *
37
+ * @param query - existing query string (may include ORDER BY / LIMIT / OFFSET)
38
+ * @param condition - condition to prepend (filter expression only)
39
+ * @returns merged query string
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * PrependCondition("status = 'active' ORDER BY name LIMIT 10", "age > 18")
44
+ * // => 'status = "active" AND age > 18 ORDER BY name LIMIT 10'
45
+ * ```
46
+ */
15
47
  export declare function PrependCondition(query?: string, condition?: string): string;
16
48
  /**
17
- * Create Expression based on the parsed token
49
+ * ANTLR parse tree visitor that builds an optimized Expression AST from the parsed tokens
18
50
  *
19
- * Expression allow to optimize and split between Query and Filter
51
+ * Converts the ANTLR parse tree into a flat, evaluatable expression tree.
52
+ * Automatically flattens nested AND/OR expressions of the same type to reduce depth.
20
53
  */
21
54
  export declare class ExpressionBuilder extends AbstractParseTreeVisitor<Query> implements WebdaQLParserVisitor<any> {
22
55
  /**
23
- * Contain the parsed limit
56
+ * Parsed LIMIT value, if present
24
57
  */
25
58
  limit: number;
26
59
  /**
27
- * Contain the parsed offset
60
+ * Parsed OFFSET continuation token, if present
28
61
  */
29
62
  offset: string;
63
+ /**
64
+ * Parsed ORDER BY clauses, if present
65
+ */
30
66
  orderBy: OrderBy[];
31
67
  /**
32
- * Default result for the override
33
- * @returns
68
+ * Default result when no expression is matched (empty AND, always true)
69
+ * @returns an empty AND query
34
70
  */
35
71
  protected defaultResult(): Query;
36
72
  /**
37
- * Get offset
38
- * @returns
73
+ * Get parsed OFFSET continuation token
74
+ * @returns the offset token
39
75
  */
40
76
  getOffset(): string;
41
77
  /**
42
- * Get limit
43
- * @returns
78
+ * Get parsed LIMIT value
79
+ * @returns the limit value
44
80
  */
45
81
  getLimit(): number;
46
82
  /**
47
- * Read the limit
48
- * @param ctx
83
+ * Visit a LIMIT clause and store the integer value
84
+ * @param ctx - the limit expression context
49
85
  */
50
86
  visitLimitExpression(ctx: LimitExpressionContext): void;
51
87
  /**
52
- * Read the offset if provided
53
- * @param ctx
88
+ * Visit an OFFSET clause and store the string continuation token
89
+ * @param ctx - the offset expression context
54
90
  */
55
91
  visitOffsetExpression(ctx: OffsetExpressionContext): void;
56
92
  /**
57
93
  * Visit a order field expression
94
+ * @param ctx - the order field expression context
95
+ * @returns the parsed OrderBy
58
96
  */
59
97
  visitOrderFieldExpression(ctx: OrderFieldExpressionContext): OrderBy;
60
98
  /**
61
99
  * Read the order by values
100
+ * @param ctx - the order expression context
62
101
  */
63
102
  visitOrderExpression(ctx: OrderExpressionContext): void;
64
103
  /**
65
- * Return only AndExpression
66
- * @param ctx
67
- * @returns
104
+ * Visit the root `webdaql` rule and build the complete Query
105
+ *
106
+ * Parses filter expression, ORDER BY, LIMIT, and OFFSET clauses.
107
+ * Returns an empty AND expression (always true) when no filter is present.
108
+ * @param ctx - the webdaql parse context
109
+ * @returns the built Query
68
110
  */
69
111
  visitWebdaql(ctx: WebdaqlContext): Query;
70
112
  /**
71
- * Simplify Logic expression and regroup them
72
- * @param ctx
73
- * @returns
113
+ * Recursively flatten nested logical expressions of the same type
114
+ *
115
+ * ANTLR produces right-recursive trees like `a AND (b AND (c AND d))`.
116
+ * This method flattens them into `[a, b, c, d]` so a single LogicalExpression
117
+ * holds all children at one level.
118
+ *
119
+ * @param ctx - an AND or OR logical expression context
120
+ * @returns flat array of child parse tree nodes
74
121
  */
75
122
  getComparison(ctx: AndLogicExpressionContext | OrLogicExpressionContext): any[];
76
123
  /**
@@ -78,49 +125,98 @@ export declare class ExpressionBuilder extends AbstractParseTreeVisitor<Query> i
78
125
  *
79
126
  * By default the parser is doing a AND (b AND (c AND d)) creating 3 depth expressions
80
127
  * This visitor simplify to a AND b AND c AND d with only one Expression
128
+ * @param ctx - the AND logic expression context
129
+ * @returns the flattened AndExpression
81
130
  */
82
- visitAndLogicExpression(ctx: AndLogicExpressionContext): AndExpression;
131
+ visitAndLogicExpression(ctx: AndLogicExpressionContext): Expression;
83
132
  /**
84
133
  * Implement the BinaryComparison with all methods managed
134
+ * @param ctx - the binary comparison context
135
+ * @returns the comparison expression
85
136
  */
86
137
  visitBinaryComparisonExpression(ctx: BinaryComparisonExpressionContext): ComparisonExpression<ComparisonOperator>;
87
138
  /**
88
139
  * Visit each value of the [..., ..., ...] set
140
+ * @param ctx - the set expression context
141
+ * @returns the array of values
89
142
  */
90
143
  visitSetExpression(ctx: SetExpressionContext): value[];
91
144
  /**
92
- * a LIKE "%A?"
93
- * @param ctx
94
- * @returns
145
+ * Visit a LIKE expression (e.g. `field LIKE '%pattern_'`)
146
+ * @param ctx - the LIKE expression context
147
+ * @returns the comparison expression
95
148
  */
96
149
  visitLikeExpression(ctx: LikeExpressionContext): ComparisonExpression<"LIKE">;
97
150
  /**
98
151
  * Map the a IN ['b','c']
152
+ * @param ctx - the IN expression context
153
+ * @returns the comparison expression
99
154
  */
100
155
  visitInExpression(ctx: InExpressionContext): ComparisonExpression<"IN">;
101
156
  /**
102
157
  * Map the a CONTAINS 'b'
158
+ * @param ctx - the CONTAINS expression context
159
+ * @returns the comparison expression
103
160
  */
104
161
  visitContainsExpression(ctx: ContainsExpressionContext): ComparisonExpression<"CONTAINS">;
162
+ /**
163
+ * Map the a IS NULL
164
+ * @param ctx - the IS NULL expression context
165
+ * @returns the comparison expression
166
+ */
167
+ visitIsNullExpression(ctx: IsNullExpressionContext): ComparisonExpression<"IS NULL">;
168
+ /**
169
+ * Map the a IS NOT NULL
170
+ * @param ctx - the IS NOT NULL expression context
171
+ * @returns the comparison expression
172
+ */
173
+ visitIsNotNullExpression(ctx: IsNotNullExpressionContext): ComparisonExpression<"IS NOT NULL">;
105
174
  /**
106
175
  * Get the OrExpression, regrouping all the parameters
107
176
  *
108
177
  * By default the parser is doing a OR (b OR (c OR d)) creating 3 depth expressions
109
178
  * This visitor simplify to a OR b OR c OR d with only one Expression
179
+ * @param ctx - the OR logic expression context
180
+ * @returns the flattened OrExpression
110
181
  */
111
- visitOrLogicExpression(ctx: OrLogicExpressionContext): OrExpression;
182
+ visitOrLogicExpression(ctx: OrLogicExpressionContext): Expression;
112
183
  /**
113
- * Read the string literal (removing the simple or double bracket)
184
+ * A bare atom used as an expression: only `TRUE` / `FALSE` are valid
185
+ * @param ctx - the atom expression context
186
+ * @returns the constant expression
187
+ * @throws {SyntaxError} for identifiers, numbers and strings
188
+ */
189
+ visitAtomExpression(ctx: AtomExpressionContext): Expression;
190
+ /**
191
+ * Read a string literal, stripping the surrounding single or double quotes
192
+ * @param ctx - the string literal context
193
+ * @returns the unquoted string value
114
194
  */
115
195
  visitStringLiteral(ctx: StringLiteralContext): string;
116
196
  /**
117
197
  * Read the boolean literal
198
+ * @param ctx - the boolean literal context
199
+ * @returns the boolean value
118
200
  */
119
201
  visitBooleanLiteral(ctx: BooleanLiteralContext): boolean;
120
202
  /**
121
203
  * Read the number literal
204
+ * @param ctx - the integer literal context
205
+ * @returns the parsed integer value
122
206
  */
123
207
  visitIntegerLiteral(ctx: IntegerLiteralContext): number;
208
+ /**
209
+ * Read a signed or decimal number literal
210
+ * @param ctx - the number literal context
211
+ * @returns the parsed number
212
+ */
213
+ visitNumberLiteral(ctx: NumberLiteralContext): number;
214
+ /**
215
+ * A `?` or `:name` placeholder reaching evaluation was never bound
216
+ * @param ctx - the parameter context
217
+ * @throws {WebdaQLError} always: use `bind()` or pass the parameters to `query()`
218
+ */
219
+ visitParameter(ctx: ParameterContext): never;
124
220
  }
125
221
  /**
126
222
  * Represent a full Query
@@ -152,6 +248,9 @@ export interface Query {
152
248
  */
153
249
  export declare abstract class Expression<T = string> {
154
250
  operator: T;
251
+ /** Create a new Expression.
252
+ * @param operator - the expression operator
253
+ */
155
254
  constructor(operator: T);
156
255
  /**
157
256
  * Evaluate the expression for the target object
@@ -164,9 +263,28 @@ export declare abstract class Expression<T = string> {
164
263
  */
165
264
  abstract toString(depth?: number): string;
166
265
  }
167
- export type ComparisonOperator = "=" | "<=" | ">=" | "<" | ">" | "!=" | "LIKE" | "IN" | "CONTAINS";
168
266
  /**
169
- * Comparison expression
267
+ * All supported comparison operators
268
+ *
269
+ * - `=` / `!=` use loose equality (`==` / `!=`)
270
+ * - `<`, `<=`, `>`, `>=` use standard JS comparison
271
+ * - `LIKE` uses SQL-style pattern matching (`%` = any chars, `_` = single char)
272
+ * - `IN` checks membership in a set (`field IN ['a', 'b']`)
273
+ * - `CONTAINS` checks if an array field contains a value (`field CONTAINS 'a'`)
274
+ * - `IS NULL` matches a missing, `undefined` or `null` field (`field IS NULL`)
275
+ * - `IS NOT NULL` matches any other value (`field IS NOT NULL`)
276
+ */
277
+ export type ComparisonOperator = "=" | "<=" | ">=" | "<" | ">" | "!=" | "LIKE" | "IN" | "CONTAINS" | "IS NULL" | "IS NOT NULL";
278
+ /**
279
+ * Comparison operators that take no value
280
+ */
281
+ export declare const UNARY_COMPARISON_OPERATORS: readonly ComparisonOperator[];
282
+ /**
283
+ * A leaf expression comparing an object attribute against a literal value
284
+ *
285
+ * Supports dot-notation for nested attribute access (e.g. `user.profile.name`).
286
+ *
287
+ * @typeParam T - the specific comparison operator type
170
288
  */
171
289
  export declare class ComparisonExpression<T extends ComparisonOperator = ComparisonOperator> extends Expression<T> {
172
290
  /**
@@ -178,25 +296,36 @@ export declare class ComparisonExpression<T extends ComparisonOperator = Compari
178
296
  */
179
297
  attribute: string[];
180
298
  /**
181
- *
182
- * @param operator of the expression
183
- * @param attribute of the object to read
184
- * @param value
299
+ * @param operator - comparison operator
300
+ * @param attribute - dot-notation path to the object property (e.g. `"user.name"`)
301
+ * @param value - literal value or array of values (for IN operator) to compare against
185
302
  */
186
303
  constructor(operator: T, attribute: string, value: value | any[]);
304
+ /**
305
+ * Convert a SQL LIKE pattern to a JavaScript RegExp
306
+ *
307
+ * - `%` matches zero or more characters
308
+ * - `_` matches exactly one character
309
+ * - `\%` and `\_` are literal percent/underscore
310
+ * - Common regex metacharacters are escaped
311
+ *
312
+ * @param like - SQL LIKE pattern string
313
+ * @returns compiled RegExp
314
+ */
187
315
  static likeToRegex(like: string): RegExp;
188
316
  /**
189
- * Read the value from the object
317
+ * Traverse an object using a dot-notation attribute path
190
318
  *
191
- * @param target
192
- * @returns
319
+ * @param target - object to read from
320
+ * @param attribute - path segments (e.g. `["user", "profile", "name"]`)
321
+ * @returns the resolved value, or `undefined` if any segment is missing
193
322
  */
194
323
  static getAttributeValue(target: any, attribute: string[]): any;
195
324
  /**
196
325
  * Set the value of the attribute based on the assignment
197
326
  *
198
327
  * If used as a Set expression
199
- * @param target
328
+ * @param target - the object to assign to
200
329
  */
201
330
  setAttributeValue(target: any): void;
202
331
  /**
@@ -204,15 +333,21 @@ export declare class ComparisonExpression<T extends ComparisonOperator = Compari
204
333
  */
205
334
  eval(target: any): boolean;
206
335
  /**
207
- * Return a string represantation of a value
336
+ * Serialize a value to its WebdaQL string representation
337
+ *
338
+ * Strings are double-quoted, booleans are uppercased, arrays are bracket-wrapped.
339
+ * @param value - the value to serialize
340
+ * @returns the serialized string
208
341
  */
209
342
  toStringValue(value: value | value[]): string;
210
343
  /**
211
344
  * Allow subclass to create different display
345
+ * @returns the attribute string
212
346
  */
213
347
  toStringAttribute(): string;
214
348
  /**
215
349
  * Allow subclass to create different display
350
+ * @returns the operator string
216
351
  */
217
352
  toStringOperator(): T;
218
353
  /**
@@ -221,19 +356,18 @@ export declare class ComparisonExpression<T extends ComparisonOperator = Compari
221
356
  toString(): string;
222
357
  }
223
358
  /**
224
- * Abstract logic expression (AND|OR)
359
+ * Abstract base for logical expressions that combine child expressions (AND / OR)
225
360
  *
226
- * Could add XOR in the future
361
+ * @typeParam T - the literal operator type (`"AND"` or `"OR"`)
227
362
  */
228
363
  export declare abstract class LogicalExpression<T> extends Expression<T> {
229
364
  /**
230
- * Contains the members of the logical expression
365
+ * Child expressions combined by this logical operator
231
366
  */
232
367
  children: Expression[];
233
368
  /**
234
- *
235
- * @param operator
236
- * @param children
369
+ * @param operator - logical operator
370
+ * @param children - child expressions to combine
237
371
  */
238
372
  constructor(operator: T, children: Expression[]);
239
373
  /**
@@ -242,7 +376,10 @@ export declare abstract class LogicalExpression<T> extends Expression<T> {
242
376
  toString(depth?: number): string;
243
377
  }
244
378
  /**
245
- * AND Expression implementation
379
+ * Logical AND expression — evaluates to `true` only if all children are `true`
380
+ *
381
+ * Uses short-circuit evaluation: returns `false` as soon as any child fails.
382
+ * An empty AND (no children) evaluates to `true`.
246
383
  */
247
384
  export declare class AndExpression extends LogicalExpression<"AND"> {
248
385
  /**
@@ -255,7 +392,10 @@ export declare class AndExpression extends LogicalExpression<"AND"> {
255
392
  eval(target: any): boolean;
256
393
  }
257
394
  /**
258
- * OR Expression implementation
395
+ * Logical OR expression — evaluates to `true` if any child is `true`
396
+ *
397
+ * Uses short-circuit evaluation: returns `true` as soon as any child passes.
398
+ * An empty OR (no children) evaluates to `true`.
259
399
  */
260
400
  export declare class OrExpression extends LogicalExpression<"OR"> {
261
401
  /**
@@ -268,7 +408,55 @@ export declare class OrExpression extends LogicalExpression<"OR"> {
268
408
  eval(target: any): boolean;
269
409
  }
270
410
  /**
411
+ * Constant expression from a `TRUE` / `FALSE` literal
412
+ *
413
+ * Constants are folded while the tree is built (see `foldLogical`), so this only
414
+ * remains when the whole filter is `FALSE`; a filter that is entirely `TRUE` is
415
+ * the match-everything `AndExpression([])`.
416
+ */
417
+ export declare class BooleanExpression extends Expression<"TRUE" | "FALSE"> {
418
+ /**
419
+ * The constant value
420
+ */
421
+ value: boolean;
422
+ /**
423
+ * @param value - the constant value
424
+ */
425
+ constructor(value: boolean);
426
+ /**
427
+ * @override
428
+ */
429
+ eval(_target: any): boolean;
430
+ /**
431
+ * @override
432
+ */
433
+ toString(): string;
434
+ }
435
+ /**
436
+ * Check a query against the WebdaQL grammar without evaluating it
437
+ *
438
+ * Unlike {@link QueryValidator}, unbound `?` / `:name` parameters are accepted, so a
439
+ * query can be checked before its parameters are bound.
440
+ *
441
+ * @param query - the query string
442
+ * @throws {SyntaxError} if the query does not follow the grammar
443
+ */
444
+ export declare function validateSyntax(query: string): void;
445
+ /**
446
+ * Parses a WebdaQL query string and provides evaluation, merging, and serialization
447
+ *
448
+ * This is the main entry point for working with WebdaQL queries. It handles:
449
+ * - Parsing query strings via ANTLR into an expression AST
450
+ * - Evaluating objects against the parsed filter
451
+ * - Merging multiple queries together
452
+ * - Serializing back to a query string
271
453
  *
454
+ * @example
455
+ * ```ts
456
+ * const validator = new QueryValidator("status = 'active' AND age > 18 LIMIT 50");
457
+ * validator.eval({ status: "active", age: 25 }); // true
458
+ * validator.getLimit(); // 50
459
+ * ```
272
460
  */
273
461
  export declare class QueryValidator {
274
462
  protected sql: string;
@@ -276,114 +464,245 @@ export declare class QueryValidator {
276
464
  protected tree: WebdaqlContext;
277
465
  protected query: Query;
278
466
  protected builder: ExpressionBuilder;
467
+ /**
468
+ * Parse a WebdaQL query string
469
+ *
470
+ * @param sql - the query string to parse
471
+ * @param builder - expression builder to use (override for custom expression types)
472
+ * @throws {SyntaxError} if the query string is malformed
473
+ */
279
474
  constructor(sql: string, builder?: ExpressionBuilder);
280
475
  /**
281
- * Get offset
282
- * @returns
476
+ * Get parsed OFFSET continuation token, or empty string if none
477
+ * @returns the offset token
283
478
  */
284
479
  getOffset(): string;
480
+ /**
481
+ * Check whether the query has a non-empty filter condition
482
+ *
483
+ * An empty AND expression (no children) is considered to have no condition.
484
+ * @returns true if there is a filter condition
485
+ */
285
486
  hasCondition(): boolean;
487
+ /**
488
+ * Reconstruct the query string from the parsed AST
489
+ *
490
+ * Includes filter, ORDER BY, LIMIT, and OFFSET clauses.
491
+ * @returns the reconstructed query string
492
+ */
286
493
  toString(): string;
494
+ /**
495
+ * Merge another query string into this query
496
+ *
497
+ * Filter expressions are combined using the specified logical operator.
498
+ * LIMIT, OFFSET, and ORDER BY from the merged query override existing values.
499
+ *
500
+ * @param query - query string to merge in
501
+ * @param type - logical operator to combine filters (`"AND"` or `"OR"`)
502
+ * @returns `this` for chaining
503
+ */
287
504
  merge(query: string, type?: "OR" | "AND"): this;
288
505
  /**
289
- * Get limit
290
- * @returns
506
+ * Get parsed LIMIT value, defaulting to 1000
507
+ * @returns the limit value
291
508
  */
292
509
  getLimit(): number;
293
510
  /**
294
- * Get the expression by itself
295
- * @returns
511
+ * Get the filter expression (without LIMIT / OFFSET / ORDER BY)
512
+ * @returns the filter expression
296
513
  */
297
514
  getExpression(): Expression;
298
515
  /**
299
- * Retrieve parsed query
300
- * @returns
516
+ * Retrieve the full parsed query including filter, limit, offset, and orderBy
517
+ * @returns the full query object
301
518
  */
302
519
  getQuery(): Query;
303
520
  /**
304
521
  * Verify if a target fit the expression
305
- * @param target
306
- * @returns
522
+ * @param target - the object to evaluate
523
+ * @returns true if the target matches
307
524
  */
308
525
  eval(target: any): boolean;
309
526
  /**
310
527
  * Display parse tree back as query
311
- * @param tree
312
- * @returns
528
+ * @param tree - the parse tree to display
529
+ * @returns the query string representation
313
530
  */
314
531
  displayTree(tree?: ParseTree): string;
315
532
  }
316
533
  /**
317
- * For now reuse same parser
534
+ * A query validator that operates in assignment mode
535
+ *
536
+ * Instead of filtering objects, it assigns values to object properties.
537
+ * Only supports `=` (assignment) combined with `AND`. No comparisons, OR, or other operators.
538
+ *
539
+ * Protects against prototype pollution by ignoring `__proto__` attributes.
540
+ *
541
+ * @example
542
+ * ```ts
543
+ * const target: any = {};
544
+ * new SetterValidator('name = "John" AND age = 30').eval(target);
545
+ * // target = { name: "John", age: 30 }
546
+ * ```
547
+ *
548
+ * @throws {SyntaxError} if non-assignment operators or OR expressions are used
318
549
  */
319
550
  export declare class SetterValidator extends QueryValidator {
551
+ /**
552
+ * @param sql - assignment expression (e.g. `'field = "value" AND other = 10'`)
553
+ * @throws {SyntaxError} if the expression contains non-assignment operators
554
+ */
320
555
  constructor(sql: string);
556
+ /**
557
+ * Apply the assignments to the target object
558
+ *
559
+ * @param target - object to assign values to (mutated in place)
560
+ * @returns always `true`
561
+ */
321
562
  eval(target: any): boolean;
563
+ /**
564
+ * Recursively walk the expression tree and apply assignments
565
+ *
566
+ * @param target - object to assign values to
567
+ * @param expression - must be an AndExpression or a `=` ComparisonExpression
568
+ * @throws {SyntaxError} if any non-assignment expression is encountered
569
+ */
322
570
  assign(target: any, expression: Expression): void;
323
571
  }
572
+ /**
573
+ * A query validator that supports partial object matching
574
+ *
575
+ * In partial mode, comparisons against `undefined` attributes evaluate to `true`
576
+ * (the missing field is ignored). This is useful for PATCH operations where only
577
+ * a subset of fields is provided.
578
+ *
579
+ * @example
580
+ * ```ts
581
+ * const v = new PartialValidator("name = 'John' AND age > 18");
582
+ * v.eval({ name: "John" }); // true (age is undefined, skipped)
583
+ * v.wasPartialMatch(); // true
584
+ * v.eval({ name: "John" }, false); // false (strict mode, age required)
585
+ * ```
586
+ */
324
587
  export declare class PartialValidator extends QueryValidator {
325
588
  builder: PartialExpressionBuilder;
589
+ /**
590
+ * @param query - WebdaQL query string
591
+ * @param builder - partial expression builder (override for customization)
592
+ */
326
593
  constructor(query: string, builder?: PartialExpressionBuilder);
327
594
  /**
328
595
  * Eval the query
329
- * @param target
330
- * @param partial
331
- * @returns
596
+ * @param target - the object to evaluate
597
+ * @param partial - whether to use partial matching
598
+ * @returns true if the target matches
332
599
  */
333
600
  eval(target: any, partial?: boolean): boolean;
334
601
  /**
335
602
  * Return if the result ignored some fields
336
- * @returns
603
+ * @returns true if some fields were skipped
337
604
  */
338
605
  wasPartialMatch(): boolean;
339
606
  }
607
+ /**
608
+ * A comparison expression that treats `undefined` attributes as a match in partial mode
609
+ *
610
+ * When the builder is in partial mode and the target attribute is `undefined`,
611
+ * evaluation returns `true` and flags the result as a partial match.
612
+ *
613
+ * @typeParam T - the specific comparison operator type
614
+ */
340
615
  export declare class PartialComparisonExpression<T extends ComparisonOperator = ComparisonOperator> extends ComparisonExpression<T> {
341
616
  protected builder: PartialExpressionBuilder;
617
+ /**
618
+ * @param builder - the partial expression builder (used to read partial mode flag)
619
+ * @param op - comparison operator
620
+ * @param attribute - dot-notation attribute path
621
+ * @param value - value to compare against
622
+ */
342
623
  constructor(builder: PartialExpressionBuilder, op: T, attribute: string, value: any);
343
624
  /**
344
625
  * Override the eval to check if the attribute is present
345
626
  * if not and we are in partial mode, return true
346
627
  *
347
- * @param target
348
- * @returns
628
+ * @param target - the object to evaluate
629
+ * @returns true if the target matches
349
630
  */
350
631
  eval(target: any): boolean;
351
632
  }
633
+ /**
634
+ * Expression builder that creates {@link PartialComparisonExpression} nodes
635
+ * instead of regular {@link ComparisonExpression} nodes
636
+ *
637
+ * Used by {@link PartialValidator} to support partial object matching.
638
+ */
352
639
  export declare class PartialExpressionBuilder extends ExpressionBuilder {
353
640
  /**
354
- * Enforce the partial mode
641
+ * Whether partial mode is active (undefined attributes treated as matching)
355
642
  */
356
643
  partial: boolean;
357
644
  /**
358
- * If eval was called in partial mode
645
+ * Set to `true` during evaluation if any attribute was undefined and skipped
359
646
  */
360
647
  partialMatch: boolean;
648
+ /**
649
+ * Enable or disable partial evaluation mode
650
+ * @param partial - whether to enable partial mode
651
+ */
361
652
  setPartial(partial: boolean): void;
653
+ /**
654
+ * Set the partial match flag (reset before each evaluation)
655
+ * @param partial - the partial match flag value
656
+ */
362
657
  setPartialMatch(partial: boolean): void;
363
658
  /**
364
- * a LIKE "%A?"
365
- * @param ctx
366
- * @returns
659
+ * Visit a LIKE expression, returning a PartialComparisonExpression
660
+ * @param ctx - the LIKE expression context
661
+ * @returns the partial comparison expression
367
662
  */
368
663
  visitLikeExpression(ctx: any): PartialComparisonExpression<"LIKE">;
369
664
  /**
370
- * Implement the BinaryComparison with all methods managed
665
+ * Visit a binary comparison, returning a PartialComparisonExpression
666
+ * @param ctx - the binary comparison context
667
+ * @returns the partial comparison expression
371
668
  */
372
669
  visitBinaryComparisonExpression(ctx: any): PartialComparisonExpression<any>;
373
670
  /**
374
- * Map the a IN ['b','c']
671
+ * Visit an IN expression, returning a PartialComparisonExpression
672
+ * @param ctx - the IN expression context
673
+ * @returns the partial comparison expression
375
674
  */
376
675
  visitInExpression(ctx: any): PartialComparisonExpression<"IN">;
377
676
  /**
378
- * Map the a CONTAINS 'b'
677
+ * Visit a CONTAINS expression, returning a PartialComparisonExpression
678
+ * @param ctx - the CONTAINS expression context
679
+ * @returns the partial comparison expression
379
680
  */
380
681
  visitContainsExpression(ctx: any): PartialComparisonExpression<"CONTAINS">;
682
+ /**
683
+ * Visit an IS NULL expression, returning a PartialComparisonExpression
684
+ * @param ctx - the IS NULL expression context
685
+ * @returns the partial comparison expression
686
+ */
687
+ visitIsNullExpression(ctx: any): PartialComparisonExpression<"IS NULL">;
688
+ /**
689
+ * Visit an IS NOT NULL expression, returning a PartialComparisonExpression
690
+ * @param ctx - the IS NOT NULL expression context
691
+ * @returns the partial comparison expression
692
+ */
693
+ visitIsNotNullExpression(ctx: any): PartialComparisonExpression<"IS NOT NULL">;
381
694
  }
382
695
  /**
383
696
  * Remove artifact from sanitize-html inside query
384
- * @param query
385
- * @returns
697
+ * @param query - the query string to unsanitize
698
+ * @returns the cleaned query string
386
699
  */
387
700
  export declare function unsanitize(query: string): string;
701
+ /**
702
+ * Parse a query string into a Query object
703
+ * @param query - the query string to parse
704
+ * @returns the parsed Query object
705
+ */
706
+ export declare function parse(query: string): Query;
388
707
  export {};
389
708
  //# sourceMappingURL=query.d.ts.map