qast 1.2.0 → 2.0.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 +260 -5
- package/README.zh-CN.md +520 -0
- package/dist/adapters/drizzle.d.ts +66 -0
- package/dist/adapters/drizzle.d.ts.map +1 -0
- package/dist/adapters/drizzle.js +222 -0
- package/dist/adapters/drizzle.js.map +1 -0
- package/dist/adapters/knex.d.ts +22 -0
- package/dist/adapters/knex.d.ts.map +1 -0
- package/dist/adapters/knex.js +158 -0
- package/dist/adapters/knex.js.map +1 -0
- package/dist/adapters/mongoose.d.ts +15 -0
- package/dist/adapters/mongoose.d.ts.map +1 -0
- package/dist/adapters/mongoose.js +152 -0
- package/dist/adapters/mongoose.js.map +1 -0
- package/dist/adapters/prisma.d.ts +5 -2
- package/dist/adapters/prisma.d.ts.map +1 -1
- package/dist/adapters/prisma.js +103 -4
- package/dist/adapters/prisma.js.map +1 -1
- package/dist/adapters/sequelize.d.ts +26 -8
- package/dist/adapters/sequelize.d.ts.map +1 -1
- package/dist/adapters/sequelize.js +168 -7
- package/dist/adapters/sequelize.js.map +1 -1
- package/dist/adapters/typeorm.d.ts +32 -2
- package/dist/adapters/typeorm.d.ts.map +1 -1
- package/dist/adapters/typeorm.js +169 -3
- package/dist/adapters/typeorm.js.map +1 -1
- package/dist/builder/query-builder.d.ts +139 -0
- package/dist/builder/query-builder.d.ts.map +1 -0
- package/dist/builder/query-builder.js +320 -0
- package/dist/builder/query-builder.js.map +1 -0
- package/dist/errors.d.ts +18 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +127 -9
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +83 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +108 -8
- package/dist/index.js.map +1 -1
- package/dist/integrations/express.d.ts +14 -0
- package/dist/integrations/express.d.ts.map +1 -0
- package/dist/integrations/express.js +33 -0
- package/dist/integrations/express.js.map +1 -0
- package/dist/integrations/fastify.d.ts +17 -0
- package/dist/integrations/fastify.d.ts.map +1 -0
- package/dist/integrations/fastify.js +35 -0
- package/dist/integrations/fastify.js.map +1 -0
- package/dist/integrations/hono.d.ts +14 -0
- package/dist/integrations/hono.d.ts.map +1 -0
- package/dist/integrations/hono.js +30 -0
- package/dist/integrations/hono.js.map +1 -0
- package/dist/integrations/nestjs.d.ts +23 -0
- package/dist/integrations/nestjs.d.ts.map +1 -0
- package/dist/integrations/nestjs.js +137 -0
- package/dist/integrations/nestjs.js.map +1 -0
- package/dist/parser/parser.d.ts +15 -7
- package/dist/parser/parser.d.ts.map +1 -1
- package/dist/parser/parser.js +117 -15
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/tokenizer.d.ts +11 -1
- package/dist/parser/tokenizer.d.ts.map +1 -1
- package/dist/parser/tokenizer.js +67 -10
- package/dist/parser/tokenizer.js.map +1 -1
- package/dist/parser/validator.d.ts +39 -0
- package/dist/parser/validator.d.ts.map +1 -1
- package/dist/parser/validator.js +144 -3
- package/dist/parser/validator.js.map +1 -1
- package/dist/types/ast.d.ts +59 -3
- package/dist/types/ast.d.ts.map +1 -1
- package/dist/types/ast.js +21 -0
- package/dist/types/ast.js.map +1 -1
- package/dist/utils/ast-utils.d.ts +43 -0
- package/dist/utils/ast-utils.d.ts.map +1 -0
- package/dist/utils/ast-utils.js +205 -0
- package/dist/utils/ast-utils.js.map +1 -0
- package/dist/utils/cache.d.ts +47 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +132 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/serializer.d.ts +6 -0
- package/dist/utils/serializer.d.ts.map +1 -0
- package/dist/utils/serializer.js +140 -0
- package/dist/utils/serializer.js.map +1 -0
- package/package.json +29 -5
package/dist/adapters/typeorm.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.toTypeORMFilter = toTypeORMFilter;
|
|
4
|
+
exports.transformTypeORMOperators = transformTypeORMOperators;
|
|
4
5
|
const ast_1 = require("../types/ast");
|
|
5
6
|
/**
|
|
6
7
|
* Transform a QAST AST node to a TypeORM filter
|
|
@@ -8,10 +9,123 @@ const ast_1 = require("../types/ast");
|
|
|
8
9
|
* Note: TypeORM uses operator functions like MoreThan(), LessThan(), etc.
|
|
9
10
|
* This adapter returns a structure that can be used with TypeORM's FindOptions.
|
|
10
11
|
* For production use, users may need to wrap values with TypeORM operators.
|
|
12
|
+
*
|
|
13
|
+
* Use transformTypeORMOperators() helper function to convert metadata to actual TypeORM operators.
|
|
11
14
|
*/
|
|
12
15
|
function toTypeORMFilter(ast) {
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
if ('filter' in ast) {
|
|
17
|
+
// It's a QueryAST
|
|
18
|
+
const queryAST = ast;
|
|
19
|
+
const result = {
|
|
20
|
+
where: transformNode(queryAST.filter),
|
|
21
|
+
};
|
|
22
|
+
if (queryAST.orderBy && queryAST.orderBy.length > 0) {
|
|
23
|
+
if (queryAST.orderBy.length === 1) {
|
|
24
|
+
result.order = {
|
|
25
|
+
[queryAST.orderBy[0].field]: queryAST.orderBy[0].direction.toUpperCase(),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
result.order = queryAST.orderBy.map(clause => ({
|
|
30
|
+
[clause.field]: clause.direction.toUpperCase(),
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (queryAST.limit !== undefined) {
|
|
35
|
+
result.take = queryAST.limit;
|
|
36
|
+
}
|
|
37
|
+
if (queryAST.offset !== undefined) {
|
|
38
|
+
result.skip = queryAST.offset;
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// It's just a QastNode (backward compatibility)
|
|
44
|
+
return {
|
|
45
|
+
where: transformNode(ast),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Helper function to transform QAST metadata to TypeORM operators
|
|
51
|
+
* This function requires TypeORM to be installed and imported.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* import { MoreThan, LessThan, Like, In, Not, IsNull } from 'typeorm';
|
|
56
|
+
* import { toTypeORMFilter, transformTypeORMOperators } from 'qast';
|
|
57
|
+
*
|
|
58
|
+
* const filter = toTypeORMFilter(ast);
|
|
59
|
+
* const transformed = transformTypeORMOperators(filter.where, {
|
|
60
|
+
* MoreThan, LessThan, Like, In, Not, IsNull
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
function transformTypeORMOperators(where, operators) {
|
|
65
|
+
if (Array.isArray(where)) {
|
|
66
|
+
return where.map(item => transformTypeORMOperators(item, operators));
|
|
67
|
+
}
|
|
68
|
+
const result = {};
|
|
69
|
+
for (const [key, value] of Object.entries(where)) {
|
|
70
|
+
if (value && typeof value === 'object' && '__qast_operator__' in value) {
|
|
71
|
+
const op = value.__qast_operator__;
|
|
72
|
+
const opValue = value.value;
|
|
73
|
+
switch (op) {
|
|
74
|
+
case 'gt':
|
|
75
|
+
result[key] = operators.MoreThan ? operators.MoreThan(opValue) : value;
|
|
76
|
+
break;
|
|
77
|
+
case 'lt':
|
|
78
|
+
result[key] = operators.LessThan ? operators.LessThan(opValue) : value;
|
|
79
|
+
break;
|
|
80
|
+
case 'gte':
|
|
81
|
+
result[key] = operators.MoreThanOrEqual ? operators.MoreThanOrEqual(opValue) : value;
|
|
82
|
+
break;
|
|
83
|
+
case 'lte':
|
|
84
|
+
result[key] = operators.LessThanOrEqual ? operators.LessThanOrEqual(opValue) : value;
|
|
85
|
+
break;
|
|
86
|
+
case 'in':
|
|
87
|
+
result[key] = operators.In ? operators.In(opValue) : value;
|
|
88
|
+
break;
|
|
89
|
+
case 'notIn':
|
|
90
|
+
result[key] = operators.Not && operators.In ? operators.Not(operators.In(opValue)) : value;
|
|
91
|
+
break;
|
|
92
|
+
case 'contains':
|
|
93
|
+
result[key] = operators.Like ? operators.Like(`%${opValue}%`) : value;
|
|
94
|
+
break;
|
|
95
|
+
case 'startsWith':
|
|
96
|
+
result[key] = operators.Like ? operators.Like(`${opValue}%`) : value;
|
|
97
|
+
break;
|
|
98
|
+
case 'endsWith':
|
|
99
|
+
result[key] = operators.Like ? operators.Like(`%${opValue}`) : value;
|
|
100
|
+
break;
|
|
101
|
+
case 'like':
|
|
102
|
+
result[key] = operators.Like ? operators.Like(opValue) : value;
|
|
103
|
+
break;
|
|
104
|
+
case 'regex':
|
|
105
|
+
case 'matches':
|
|
106
|
+
// TypeORM doesn't support regex directly, use Like as fallback
|
|
107
|
+
result[key] = operators.Like ? operators.Like(opValue) : value;
|
|
108
|
+
break;
|
|
109
|
+
case 'ne':
|
|
110
|
+
result[key] = operators.Not ? operators.Not(opValue) : value;
|
|
111
|
+
break;
|
|
112
|
+
default:
|
|
113
|
+
result[key] = value;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else if (value && typeof value === 'object' && '__qast_null_check__' in value) {
|
|
117
|
+
if (value.__qast_null_check__ === true) {
|
|
118
|
+
result[key] = operators.IsNull ? operators.IsNull() : null;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
result[key] = operators.Not && operators.IsNull ? operators.Not(operators.IsNull()) : { not: null };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
result[key] = value;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
15
129
|
}
|
|
16
130
|
/**
|
|
17
131
|
* Transform a node to TypeORM format
|
|
@@ -23,7 +137,16 @@ function transformNode(node) {
|
|
|
23
137
|
else if ((0, ast_1.isLogicalNode)(node)) {
|
|
24
138
|
return transformLogicalNode(node);
|
|
25
139
|
}
|
|
26
|
-
|
|
140
|
+
else if ((0, ast_1.isNotNode)(node)) {
|
|
141
|
+
return transformNotNode(node);
|
|
142
|
+
}
|
|
143
|
+
else if ((0, ast_1.isBetweenNode)(node)) {
|
|
144
|
+
return transformBetweenNode(node);
|
|
145
|
+
}
|
|
146
|
+
else if ((0, ast_1.isNullCheckNode)(node)) {
|
|
147
|
+
return transformNullCheckNode(node);
|
|
148
|
+
}
|
|
149
|
+
throw new Error(`Invalid node type: ${node.type}`);
|
|
27
150
|
}
|
|
28
151
|
/**
|
|
29
152
|
* Transform a comparison node to TypeORM format
|
|
@@ -74,6 +197,16 @@ function transformComparisonNode(node) {
|
|
|
74
197
|
case 'endsWith':
|
|
75
198
|
// Ends with - requires Like(`%${value}`) from TypeORM
|
|
76
199
|
return { [field]: { __qast_operator__: 'endsWith', value } };
|
|
200
|
+
case 'notIn':
|
|
201
|
+
// Not in array - requires Not(In(value)) from TypeORM
|
|
202
|
+
return { [field]: { __qast_operator__: 'notIn', value } };
|
|
203
|
+
case 'like':
|
|
204
|
+
// Like pattern - requires Like(value) from TypeORM
|
|
205
|
+
return { [field]: { __qast_operator__: 'like', value } };
|
|
206
|
+
case 'regex':
|
|
207
|
+
case 'matches':
|
|
208
|
+
// Regex matching - TypeORM doesn't support regex directly, use Like as fallback
|
|
209
|
+
return { [field]: { __qast_operator__: 'regex', value } };
|
|
77
210
|
default:
|
|
78
211
|
throw new Error(`Unsupported operator: ${op}`);
|
|
79
212
|
}
|
|
@@ -115,4 +248,37 @@ function mergeFilters(left, right) {
|
|
|
115
248
|
// Both are objects, merge them
|
|
116
249
|
return { ...left, ...right };
|
|
117
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Transform a NOT node to TypeORM format
|
|
253
|
+
*/
|
|
254
|
+
function transformNotNode(node) {
|
|
255
|
+
const operandFilter = transformNode(node.operand);
|
|
256
|
+
// TypeORM uses NOT operator - wrap the operand
|
|
257
|
+
return {
|
|
258
|
+
__qast_not__: operandFilter,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Transform a BETWEEN node to TypeORM format
|
|
263
|
+
*/
|
|
264
|
+
function transformBetweenNode(node) {
|
|
265
|
+
// TypeORM uses MoreThanOrEqual and LessThanOrEqual for between
|
|
266
|
+
return {
|
|
267
|
+
[node.field]: {
|
|
268
|
+
__qast_operator__: 'between',
|
|
269
|
+
min: node.min,
|
|
270
|
+
max: node.max,
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Transform a NULL_CHECK node to TypeORM format
|
|
276
|
+
*/
|
|
277
|
+
function transformNullCheckNode(node) {
|
|
278
|
+
return {
|
|
279
|
+
[node.field]: {
|
|
280
|
+
__qast_null_check__: node.isNull,
|
|
281
|
+
},
|
|
282
|
+
};
|
|
283
|
+
}
|
|
118
284
|
//# sourceMappingURL=typeorm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typeorm.js","sourceRoot":"","sources":["../../src/adapters/typeorm.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"typeorm.js","sourceRoot":"","sources":["../../src/adapters/typeorm.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { QastNode, QueryAST, Operator, QastValue, SortDirection } from '../types/ast';
|
|
2
|
+
/**
|
|
3
|
+
* Field builder for building comparison operations
|
|
4
|
+
*/
|
|
5
|
+
export declare class FieldBuilder {
|
|
6
|
+
private field;
|
|
7
|
+
private builder;
|
|
8
|
+
constructor(field: string, builder: QueryBuilder);
|
|
9
|
+
/**
|
|
10
|
+
* Equal operator
|
|
11
|
+
*/
|
|
12
|
+
eq(value: QastValue): QueryBuilder;
|
|
13
|
+
/**
|
|
14
|
+
* Not equal operator
|
|
15
|
+
*/
|
|
16
|
+
ne(value: QastValue): QueryBuilder;
|
|
17
|
+
/**
|
|
18
|
+
* Greater than operator
|
|
19
|
+
*/
|
|
20
|
+
gt(value: number | string): QueryBuilder;
|
|
21
|
+
/**
|
|
22
|
+
* Less than operator
|
|
23
|
+
*/
|
|
24
|
+
lt(value: number | string): QueryBuilder;
|
|
25
|
+
/**
|
|
26
|
+
* Greater than or equal operator
|
|
27
|
+
*/
|
|
28
|
+
gte(value: number | string): QueryBuilder;
|
|
29
|
+
/**
|
|
30
|
+
* Less than or equal operator
|
|
31
|
+
*/
|
|
32
|
+
lte(value: number | string): QueryBuilder;
|
|
33
|
+
/**
|
|
34
|
+
* In array operator
|
|
35
|
+
*/
|
|
36
|
+
in(value: string[] | number[]): QueryBuilder;
|
|
37
|
+
/**
|
|
38
|
+
* Not in array operator
|
|
39
|
+
*/
|
|
40
|
+
notIn(value: string[] | number[]): QueryBuilder;
|
|
41
|
+
/**
|
|
42
|
+
* Contains substring operator
|
|
43
|
+
*/
|
|
44
|
+
contains(value: string): QueryBuilder;
|
|
45
|
+
/**
|
|
46
|
+
* Starts with operator
|
|
47
|
+
*/
|
|
48
|
+
startsWith(value: string): QueryBuilder;
|
|
49
|
+
/**
|
|
50
|
+
* Ends with operator
|
|
51
|
+
*/
|
|
52
|
+
endsWith(value: string): QueryBuilder;
|
|
53
|
+
/**
|
|
54
|
+
* Like pattern matching operator
|
|
55
|
+
*/
|
|
56
|
+
like(value: string): QueryBuilder;
|
|
57
|
+
/**
|
|
58
|
+
* Regex matching operator
|
|
59
|
+
*/
|
|
60
|
+
regex(value: string): QueryBuilder;
|
|
61
|
+
/**
|
|
62
|
+
* Matches regex operator (alias for regex)
|
|
63
|
+
*/
|
|
64
|
+
matches(value: string): QueryBuilder;
|
|
65
|
+
/**
|
|
66
|
+
* Between operator
|
|
67
|
+
*/
|
|
68
|
+
between(min: number | string, max: number | string): QueryBuilder;
|
|
69
|
+
/**
|
|
70
|
+
* Is null check
|
|
71
|
+
*/
|
|
72
|
+
isNull(): QueryBuilder;
|
|
73
|
+
/**
|
|
74
|
+
* Is not null check
|
|
75
|
+
*/
|
|
76
|
+
isNotNull(): QueryBuilder;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Query builder for programmatically building QAST queries
|
|
80
|
+
*/
|
|
81
|
+
export declare class QueryBuilder {
|
|
82
|
+
private filter;
|
|
83
|
+
private orderByClauses;
|
|
84
|
+
private limitValue?;
|
|
85
|
+
private offsetValue?;
|
|
86
|
+
/**
|
|
87
|
+
* Start building a field comparison
|
|
88
|
+
*/
|
|
89
|
+
field(name: string): FieldBuilder;
|
|
90
|
+
/**
|
|
91
|
+
* Add a comparison node
|
|
92
|
+
*/
|
|
93
|
+
addComparison(field: string, op: Operator, value: QastValue): QueryBuilder;
|
|
94
|
+
/**
|
|
95
|
+
* Add a between node
|
|
96
|
+
*/
|
|
97
|
+
addBetween(field: string, min: number | string, max: number | string): QueryBuilder;
|
|
98
|
+
/**
|
|
99
|
+
* Add a null check node
|
|
100
|
+
*/
|
|
101
|
+
addNullCheck(field: string, isNull: boolean): QueryBuilder;
|
|
102
|
+
/**
|
|
103
|
+
* Add an AND condition
|
|
104
|
+
*/
|
|
105
|
+
and(condition: QastNode | QueryBuilder): QueryBuilder;
|
|
106
|
+
/**
|
|
107
|
+
* Add an OR condition
|
|
108
|
+
*/
|
|
109
|
+
or(condition: QastNode | QueryBuilder): QueryBuilder;
|
|
110
|
+
/**
|
|
111
|
+
* Add a NOT condition
|
|
112
|
+
*/
|
|
113
|
+
not(condition: QastNode | QueryBuilder): QueryBuilder;
|
|
114
|
+
/**
|
|
115
|
+
* Add order by clause
|
|
116
|
+
*/
|
|
117
|
+
orderBy(field: string, direction?: SortDirection): QueryBuilder;
|
|
118
|
+
/**
|
|
119
|
+
* Set limit
|
|
120
|
+
*/
|
|
121
|
+
limit(value: number): QueryBuilder;
|
|
122
|
+
/**
|
|
123
|
+
* Set offset
|
|
124
|
+
*/
|
|
125
|
+
offset(value: number): QueryBuilder;
|
|
126
|
+
/**
|
|
127
|
+
* Build the query AST
|
|
128
|
+
*/
|
|
129
|
+
build(): QueryAST;
|
|
130
|
+
/**
|
|
131
|
+
* Build just the filter (backward compatibility)
|
|
132
|
+
*/
|
|
133
|
+
buildFilter(): QastNode;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Create a new query builder instance
|
|
137
|
+
*/
|
|
138
|
+
export declare function queryBuilder(): QueryBuilder;
|
|
139
|
+
//# sourceMappingURL=query-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-builder.d.ts","sourceRoot":"","sources":["../../src/builder/query-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QueryBuilder = exports.FieldBuilder = void 0;
|
|
4
|
+
exports.queryBuilder = queryBuilder;
|
|
5
|
+
/**
|
|
6
|
+
* Field builder for building comparison operations
|
|
7
|
+
*/
|
|
8
|
+
class FieldBuilder {
|
|
9
|
+
constructor(field, builder) {
|
|
10
|
+
this.field = field;
|
|
11
|
+
this.builder = builder;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Equal operator
|
|
15
|
+
*/
|
|
16
|
+
eq(value) {
|
|
17
|
+
return this.builder.addComparison(this.field, 'eq', value);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Not equal operator
|
|
21
|
+
*/
|
|
22
|
+
ne(value) {
|
|
23
|
+
return this.builder.addComparison(this.field, 'ne', value);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Greater than operator
|
|
27
|
+
*/
|
|
28
|
+
gt(value) {
|
|
29
|
+
return this.builder.addComparison(this.field, 'gt', value);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Less than operator
|
|
33
|
+
*/
|
|
34
|
+
lt(value) {
|
|
35
|
+
return this.builder.addComparison(this.field, 'lt', value);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Greater than or equal operator
|
|
39
|
+
*/
|
|
40
|
+
gte(value) {
|
|
41
|
+
return this.builder.addComparison(this.field, 'gte', value);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Less than or equal operator
|
|
45
|
+
*/
|
|
46
|
+
lte(value) {
|
|
47
|
+
return this.builder.addComparison(this.field, 'lte', value);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* In array operator
|
|
51
|
+
*/
|
|
52
|
+
in(value) {
|
|
53
|
+
return this.builder.addComparison(this.field, 'in', value);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Not in array operator
|
|
57
|
+
*/
|
|
58
|
+
notIn(value) {
|
|
59
|
+
return this.builder.addComparison(this.field, 'notIn', value);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Contains substring operator
|
|
63
|
+
*/
|
|
64
|
+
contains(value) {
|
|
65
|
+
return this.builder.addComparison(this.field, 'contains', value);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Starts with operator
|
|
69
|
+
*/
|
|
70
|
+
startsWith(value) {
|
|
71
|
+
return this.builder.addComparison(this.field, 'startsWith', value);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Ends with operator
|
|
75
|
+
*/
|
|
76
|
+
endsWith(value) {
|
|
77
|
+
return this.builder.addComparison(this.field, 'endsWith', value);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Like pattern matching operator
|
|
81
|
+
*/
|
|
82
|
+
like(value) {
|
|
83
|
+
return this.builder.addComparison(this.field, 'like', value);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Regex matching operator
|
|
87
|
+
*/
|
|
88
|
+
regex(value) {
|
|
89
|
+
return this.builder.addComparison(this.field, 'regex', value);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Matches regex operator (alias for regex)
|
|
93
|
+
*/
|
|
94
|
+
matches(value) {
|
|
95
|
+
return this.builder.addComparison(this.field, 'matches', value);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Between operator
|
|
99
|
+
*/
|
|
100
|
+
between(min, max) {
|
|
101
|
+
return this.builder.addBetween(this.field, min, max);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Is null check
|
|
105
|
+
*/
|
|
106
|
+
isNull() {
|
|
107
|
+
return this.builder.addNullCheck(this.field, true);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Is not null check
|
|
111
|
+
*/
|
|
112
|
+
isNotNull() {
|
|
113
|
+
return this.builder.addNullCheck(this.field, false);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.FieldBuilder = FieldBuilder;
|
|
117
|
+
/**
|
|
118
|
+
* Query builder for programmatically building QAST queries
|
|
119
|
+
*/
|
|
120
|
+
class QueryBuilder {
|
|
121
|
+
constructor() {
|
|
122
|
+
this.filter = null;
|
|
123
|
+
this.orderByClauses = [];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Start building a field comparison
|
|
127
|
+
*/
|
|
128
|
+
field(name) {
|
|
129
|
+
return new FieldBuilder(name, this);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Add a comparison node
|
|
133
|
+
*/
|
|
134
|
+
addComparison(field, op, value) {
|
|
135
|
+
const comparison = {
|
|
136
|
+
type: 'COMPARISON',
|
|
137
|
+
field,
|
|
138
|
+
op,
|
|
139
|
+
value,
|
|
140
|
+
};
|
|
141
|
+
if (this.filter === null) {
|
|
142
|
+
this.filter = comparison;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// Combine with existing filter using AND
|
|
146
|
+
this.filter = {
|
|
147
|
+
type: 'AND',
|
|
148
|
+
left: this.filter,
|
|
149
|
+
right: comparison,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Add a between node
|
|
156
|
+
*/
|
|
157
|
+
addBetween(field, min, max) {
|
|
158
|
+
const between = {
|
|
159
|
+
type: 'BETWEEN',
|
|
160
|
+
field,
|
|
161
|
+
min,
|
|
162
|
+
max,
|
|
163
|
+
};
|
|
164
|
+
if (this.filter === null) {
|
|
165
|
+
this.filter = between;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
this.filter = {
|
|
169
|
+
type: 'AND',
|
|
170
|
+
left: this.filter,
|
|
171
|
+
right: between,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return this;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Add a null check node
|
|
178
|
+
*/
|
|
179
|
+
addNullCheck(field, isNull) {
|
|
180
|
+
const nullCheck = {
|
|
181
|
+
type: 'NULL_CHECK',
|
|
182
|
+
field,
|
|
183
|
+
isNull,
|
|
184
|
+
};
|
|
185
|
+
if (this.filter === null) {
|
|
186
|
+
this.filter = nullCheck;
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
this.filter = {
|
|
190
|
+
type: 'AND',
|
|
191
|
+
left: this.filter,
|
|
192
|
+
right: nullCheck,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
return this;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Add an AND condition
|
|
199
|
+
*/
|
|
200
|
+
and(condition) {
|
|
201
|
+
const node = condition instanceof QueryBuilder ? condition.filter : condition;
|
|
202
|
+
if (node === null) {
|
|
203
|
+
return this;
|
|
204
|
+
}
|
|
205
|
+
if (this.filter === null) {
|
|
206
|
+
this.filter = node;
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
this.filter = {
|
|
210
|
+
type: 'AND',
|
|
211
|
+
left: this.filter,
|
|
212
|
+
right: node,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
return this;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Add an OR condition
|
|
219
|
+
*/
|
|
220
|
+
or(condition) {
|
|
221
|
+
const node = condition instanceof QueryBuilder ? condition.filter : condition;
|
|
222
|
+
if (node === null) {
|
|
223
|
+
return this;
|
|
224
|
+
}
|
|
225
|
+
if (this.filter === null) {
|
|
226
|
+
this.filter = node;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
this.filter = {
|
|
230
|
+
type: 'OR',
|
|
231
|
+
left: this.filter,
|
|
232
|
+
right: node,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
return this;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Add a NOT condition
|
|
239
|
+
*/
|
|
240
|
+
not(condition) {
|
|
241
|
+
const node = condition instanceof QueryBuilder ? condition.filter : condition;
|
|
242
|
+
if (node === null) {
|
|
243
|
+
return this;
|
|
244
|
+
}
|
|
245
|
+
const notNode = {
|
|
246
|
+
type: 'NOT',
|
|
247
|
+
operand: node,
|
|
248
|
+
};
|
|
249
|
+
if (this.filter === null) {
|
|
250
|
+
this.filter = notNode;
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
this.filter = {
|
|
254
|
+
type: 'AND',
|
|
255
|
+
left: this.filter,
|
|
256
|
+
right: notNode,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Add order by clause
|
|
263
|
+
*/
|
|
264
|
+
orderBy(field, direction = 'asc') {
|
|
265
|
+
this.orderByClauses.push({ field, direction });
|
|
266
|
+
return this;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Set limit
|
|
270
|
+
*/
|
|
271
|
+
limit(value) {
|
|
272
|
+
this.limitValue = value;
|
|
273
|
+
return this;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Set offset
|
|
277
|
+
*/
|
|
278
|
+
offset(value) {
|
|
279
|
+
this.offsetValue = value;
|
|
280
|
+
return this;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Build the query AST
|
|
284
|
+
*/
|
|
285
|
+
build() {
|
|
286
|
+
if (this.filter === null) {
|
|
287
|
+
throw new Error('Query builder must have at least one condition');
|
|
288
|
+
}
|
|
289
|
+
const result = {
|
|
290
|
+
filter: this.filter,
|
|
291
|
+
};
|
|
292
|
+
if (this.orderByClauses.length > 0) {
|
|
293
|
+
result.orderBy = this.orderByClauses;
|
|
294
|
+
}
|
|
295
|
+
if (this.limitValue !== undefined) {
|
|
296
|
+
result.limit = this.limitValue;
|
|
297
|
+
}
|
|
298
|
+
if (this.offsetValue !== undefined) {
|
|
299
|
+
result.offset = this.offsetValue;
|
|
300
|
+
}
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Build just the filter (backward compatibility)
|
|
305
|
+
*/
|
|
306
|
+
buildFilter() {
|
|
307
|
+
if (this.filter === null) {
|
|
308
|
+
throw new Error('Query builder must have at least one condition');
|
|
309
|
+
}
|
|
310
|
+
return this.filter;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
exports.QueryBuilder = QueryBuilder;
|
|
314
|
+
/**
|
|
315
|
+
* Create a new query builder instance
|
|
316
|
+
*/
|
|
317
|
+
function queryBuilder() {
|
|
318
|
+
return new QueryBuilder();
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=query-builder.js.map
|