@ballistix.digital/odata-query-builder 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module/query/domain/filter/node.model.d.ts +3 -2
- package/dist/module/query/domain/filter/node.model.js +3 -2
- package/dist/module/query/domain/filter/node.model.js.map +1 -1
- package/dist/module/query/service/emit/emit.facade.d.ts +2 -8
- package/dist/module/query/service/emit/emit.facade.js +3 -17
- package/dist/module/query/service/emit/emit.facade.js.map +1 -1
- package/dist/module/query/service/emit/emit.service.d.ts +38 -0
- package/dist/module/query/service/emit/emit.service.js +89 -0
- package/dist/module/query/service/emit/emit.service.js.map +1 -0
- package/dist/module/query/service/filter/filter.facade.d.ts +4 -17
- package/dist/module/query/service/filter/filter.facade.js +12 -61
- package/dist/module/query/service/filter/filter.facade.js.map +1 -1
- package/dist/module/query/service/filter/filter.service.d.ts +51 -0
- package/dist/module/query/service/filter/filter.service.js +88 -0
- package/dist/module/query/service/filter/filter.service.js.map +1 -0
- package/dist/module/query/service/filter/scope.service.d.ts +70 -0
- package/dist/module/query/service/filter/scope.service.js +260 -0
- package/dist/module/query/service/filter/scope.service.js.map +1 -0
- package/package.json +1 -1
- package/dist/module/query/util/emit/queryParts.util.d.ts +0 -16
- package/dist/module/query/util/emit/queryParts.util.js +0 -60
- package/dist/module/query/util/emit/queryParts.util.js.map +0 -1
- package/dist/module/query/util/filter/filterFunction.util.d.ts +0 -9
- package/dist/module/query/util/filter/filterFunction.util.js +0 -111
- package/dist/module/query/util/filter/filterFunction.util.js.map +0 -1
- package/dist/module/query/util/filter/literal.util.d.ts +0 -23
- package/dist/module/query/util/filter/literal.util.js +0 -81
- package/dist/module/query/util/filter/literal.util.js.map +0 -1
- package/dist/module/query/util/filter/scopeProxy.util.d.ts +0 -22
- package/dist/module/query/util/filter/scopeProxy.util.js +0 -93
- package/dist/module/query/util/filter/scopeProxy.util.js.map +0 -1
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ScopeService = exports.ExpressionNode = void 0;
|
|
4
|
+
const invalidFilter_exception_1 = require("../../exception/invalidFilter.exception");
|
|
5
|
+
const reservedName_exception_1 = require("../../exception/reservedName.exception");
|
|
6
|
+
const escape_util_1 = require("../../util/filter/escape.util");
|
|
7
|
+
const predicate_util_1 = require("../../util/filter/predicate.util");
|
|
8
|
+
class ExpressionNode {
|
|
9
|
+
text;
|
|
10
|
+
depth;
|
|
11
|
+
arithmetic;
|
|
12
|
+
constructor(text,
|
|
13
|
+
/** lambda nesting level, for deterministic alias letters */
|
|
14
|
+
depth,
|
|
15
|
+
/** true for `a add 1`: needs parentheses as an operand of `mul`. */
|
|
16
|
+
arithmetic = false) {
|
|
17
|
+
this.text = text;
|
|
18
|
+
this.depth = depth;
|
|
19
|
+
this.arithmetic = arithmetic;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.ExpressionNode = ExpressionNode;
|
|
23
|
+
class ScopeService {
|
|
24
|
+
/** The only key that reads a node. A DTO key can never be a symbol. */
|
|
25
|
+
static NODE = Symbol('odata.node');
|
|
26
|
+
/**
|
|
27
|
+
* The filter scope of an entity: an empty path at lambda depth 0. An
|
|
28
|
+
* expanded entity is filtered relative to itself, so it takes the same empty
|
|
29
|
+
* root.
|
|
30
|
+
*/
|
|
31
|
+
static rootScope() {
|
|
32
|
+
return ScopeService.createMember(new ExpressionNode('', 0));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* `createMember(node)` is a value; `createMember(node, parent, name)` is a
|
|
36
|
+
* member of `parent` that has not yet decided whether it is a path segment
|
|
37
|
+
* or a function call.
|
|
38
|
+
*
|
|
39
|
+
* The target is an arrow function so the proxy is callable. An arrow
|
|
40
|
+
* function has no `prototype`, and its `name`/`length` are configurable, so
|
|
41
|
+
* no Proxy invariant forces a value through — a DTO column called `name` or
|
|
42
|
+
* `length` still reaches the trap.
|
|
43
|
+
*
|
|
44
|
+
* `v.name.eq('x')` on `rootScope()` gives `name eq 'x'`. See
|
|
45
|
+
* docs/maintainer/architecture.md, How `Proxy` works here.
|
|
46
|
+
*/
|
|
47
|
+
static createMember(node, parent, name) {
|
|
48
|
+
// The target is never invoked: the `apply` trap owns every call. It only
|
|
49
|
+
// has to BE callable, so the Proxy accepts an `apply` trap at all.
|
|
50
|
+
return new Proxy(
|
|
51
|
+
/* istanbul ignore next */ (() => undefined), {
|
|
52
|
+
get(_target, property) {
|
|
53
|
+
if (property === ScopeService.NODE)
|
|
54
|
+
return node;
|
|
55
|
+
if (typeof property !== 'string')
|
|
56
|
+
return undefined;
|
|
57
|
+
// Reserved names THROW rather than return undefined, so `await q`,
|
|
58
|
+
// `JSON.stringify(q)` and an implicit `${q}`/arithmetic coercion
|
|
59
|
+
// fail loudly instead of silently — the last two would otherwise
|
|
60
|
+
// reach `apply` as a call to a function named `toString`/`valueOf`
|
|
61
|
+
// that the OData function table does not know, a confusing error
|
|
62
|
+
// to land on.
|
|
63
|
+
if (property === 'then' ||
|
|
64
|
+
property === 'toJSON' ||
|
|
65
|
+
property === 'toString' ||
|
|
66
|
+
property === 'valueOf')
|
|
67
|
+
throw new reservedName_exception_1.ReservedNameError(property);
|
|
68
|
+
return ScopeService.createMember(new ExpressionNode(node.text ? `${node.text}/${property}` : property, node.depth), node, property);
|
|
69
|
+
},
|
|
70
|
+
apply(_target, _thisArgument, callArguments) {
|
|
71
|
+
if (parent === undefined || name === undefined)
|
|
72
|
+
throw new invalidFilter_exception_1.InvalidFilterError(`"${node.text}" is a property path, not a function`, node.text);
|
|
73
|
+
const method = ScopeService.filterFunction(name);
|
|
74
|
+
if (method === undefined)
|
|
75
|
+
throw new invalidFilter_exception_1.InvalidFilterError(`${name}() is not an OData filter function served by this API`, name);
|
|
76
|
+
return method(parent, callArguments);
|
|
77
|
+
},
|
|
78
|
+
has: (_target, property) => typeof property === 'string',
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/** The node behind a scope proxy, or `undefined` for a plain value. */
|
|
82
|
+
static nodeOf(value) {
|
|
83
|
+
return typeof value === 'function' ||
|
|
84
|
+
(typeof value === 'object' && value !== null)
|
|
85
|
+
? value[ScopeService.NODE]
|
|
86
|
+
: undefined;
|
|
87
|
+
}
|
|
88
|
+
/** `a add 1` used as an operand of `mul` must become `(a add 1)`. */
|
|
89
|
+
static parenthesiseArithmetic(node) {
|
|
90
|
+
return node.arithmetic ? `(${node.text})` : node.text;
|
|
91
|
+
}
|
|
92
|
+
static isLuxonLike(value) {
|
|
93
|
+
return (typeof value === 'object' &&
|
|
94
|
+
value !== null &&
|
|
95
|
+
typeof value.toISO === 'function');
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* @param allowNull `in()` accepts a null member (`in (2024,null)` is a legal
|
|
99
|
+
* set test); every other position rejects it — `eq(null)` must look nothing
|
|
100
|
+
* like "no filter", so `isNull()`/`isNotNull()` are the only way to test for
|
|
101
|
+
* null. `undefined` is never a literal, in any position: it means "nothing
|
|
102
|
+
* was passed", not "the value is null", and reaching this method with it is
|
|
103
|
+
* only possible through an `any`/`as never` cast around the type layer.
|
|
104
|
+
*/
|
|
105
|
+
static literal(value, allowNull = false) {
|
|
106
|
+
if (value === undefined)
|
|
107
|
+
throw new invalidFilter_exception_1.InvalidFilterError('undefined is not an OData literal; omit the comparison entirely, or use isNull()/isNotNull() to test for null');
|
|
108
|
+
if (value === null) {
|
|
109
|
+
if (allowNull)
|
|
110
|
+
return 'null';
|
|
111
|
+
throw new invalidFilter_exception_1.InvalidFilterError('null is not an OData literal here; use isNull()/isNotNull() to test for null, or in() to allow it as a set member');
|
|
112
|
+
}
|
|
113
|
+
const node = ScopeService.nodeOf(value);
|
|
114
|
+
if (node)
|
|
115
|
+
return ScopeService.parenthesiseArithmetic(node);
|
|
116
|
+
if (typeof value === 'string')
|
|
117
|
+
return (0, escape_util_1.quote)(value);
|
|
118
|
+
if (typeof value === 'boolean')
|
|
119
|
+
return value ? 'true' : 'false';
|
|
120
|
+
if (typeof value === 'bigint')
|
|
121
|
+
return value.toString();
|
|
122
|
+
if (typeof value === 'number') {
|
|
123
|
+
if (!Number.isFinite(value))
|
|
124
|
+
throw new invalidFilter_exception_1.InvalidFilterError(`${value} is not an OData number literal`, String(value));
|
|
125
|
+
return String(value);
|
|
126
|
+
}
|
|
127
|
+
if (value instanceof Date) {
|
|
128
|
+
if (Number.isNaN(value.getTime()))
|
|
129
|
+
throw new invalidFilter_exception_1.InvalidFilterError('an invalid Date has no ISO literal');
|
|
130
|
+
return (0, escape_util_1.quote)(value.toISOString());
|
|
131
|
+
}
|
|
132
|
+
if (ScopeService.isLuxonLike(value)) {
|
|
133
|
+
const isoText = value.toISO();
|
|
134
|
+
if (isoText === null)
|
|
135
|
+
throw new invalidFilter_exception_1.InvalidFilterError('an invalid DateTime has no ISO literal');
|
|
136
|
+
return (0, escape_util_1.quote)(isoText);
|
|
137
|
+
}
|
|
138
|
+
throw new invalidFilter_exception_1.InvalidFilterError(`${Object.prototype.toString.call(value)} is not an OData literal`);
|
|
139
|
+
}
|
|
140
|
+
static comparison(operator) {
|
|
141
|
+
return (self, callArguments) => new predicate_util_1.PredicateNode(`${self.text} ${operator} ${ScopeService.literal(callArguments[0])}`);
|
|
142
|
+
}
|
|
143
|
+
/** A one-argument SQL function: `name(self)`. */
|
|
144
|
+
static unaryFunction(name) {
|
|
145
|
+
return (self) => ScopeService.createMember(new ExpressionNode(`${name}(${self.text})`, self.depth));
|
|
146
|
+
}
|
|
147
|
+
/** A two-argument SQL function: `name(self,argument)`. */
|
|
148
|
+
static binaryFunction(name) {
|
|
149
|
+
return (self, callArguments) => ScopeService.createMember(new ExpressionNode(`${name}(${self.text},${ScopeService.literal(callArguments[0])})`, self.depth));
|
|
150
|
+
}
|
|
151
|
+
static arithmetic(operator) {
|
|
152
|
+
return (self, callArguments) => ScopeService.createMember(new ExpressionNode(`${ScopeService.parenthesiseArithmetic(self)} ${operator} ${ScopeService.literal(callArguments[0])}`, self.depth, true));
|
|
153
|
+
}
|
|
154
|
+
static stringMatch(name) {
|
|
155
|
+
return (self, callArguments) => new predicate_util_1.PredicateNode(`${name}(${self.text},${ScopeService.literal(callArguments[0])})`);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* A distinct alias letter per lambda nesting level, so an inner lambda never
|
|
159
|
+
* shadows the outer one and `b/x ne a/y` stays expressible.
|
|
160
|
+
*/
|
|
161
|
+
static lambdaAlias(depth) {
|
|
162
|
+
return depth < 26
|
|
163
|
+
? String.fromCharCode(97 + depth)
|
|
164
|
+
: `${String.fromCharCode(97 + (depth % 26))}${Math.floor(depth / 26)}`;
|
|
165
|
+
}
|
|
166
|
+
static lambda(kind) {
|
|
167
|
+
return (self, callArguments) => {
|
|
168
|
+
const build = callArguments[0];
|
|
169
|
+
if (!build) {
|
|
170
|
+
if (kind === 'all')
|
|
171
|
+
throw new invalidFilter_exception_1.InvalidFilterError('all() requires a predicate; the server rejects a bare all()', 'all');
|
|
172
|
+
return new predicate_util_1.PredicateNode(`${self.text}/any()`);
|
|
173
|
+
}
|
|
174
|
+
const alias = ScopeService.lambdaAlias(self.depth);
|
|
175
|
+
const inner = build(ScopeService.createMember(new ExpressionNode(alias, self.depth + 1)));
|
|
176
|
+
if (!(inner instanceof predicate_util_1.PredicateNode))
|
|
177
|
+
throw new invalidFilter_exception_1.InvalidFilterError(`${kind}() must return a predicate, not a bare column`, kind);
|
|
178
|
+
// The colon carries no space: the grammar requires `any(a:…)`.
|
|
179
|
+
return new predicate_util_1.PredicateNode(`${self.text}/${kind}(${alias}:${inner.text})`);
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
static FILTER_FUNCTIONS = {
|
|
183
|
+
/* comparison */
|
|
184
|
+
eq: ScopeService.comparison('eq'),
|
|
185
|
+
ne: ScopeService.comparison('ne'),
|
|
186
|
+
gt: ScopeService.comparison('gt'),
|
|
187
|
+
ge: ScopeService.comparison('ge'),
|
|
188
|
+
lt: ScopeService.comparison('lt'),
|
|
189
|
+
le: ScopeService.comparison('le'),
|
|
190
|
+
in: (self, callArguments) => {
|
|
191
|
+
const values = callArguments[0];
|
|
192
|
+
if (!Array.isArray(values) || values.length === 0)
|
|
193
|
+
throw new invalidFilter_exception_1.InvalidFilterError('in() needs at least one value', 'in');
|
|
194
|
+
for (const member of values) {
|
|
195
|
+
if (ScopeService.nodeOf(member)?.arithmetic)
|
|
196
|
+
throw new invalidFilter_exception_1.InvalidFilterError('in() takes literals and columns as members; the server grammar rejects an arithmetic expression inside in (...)', 'in');
|
|
197
|
+
}
|
|
198
|
+
return new predicate_util_1.PredicateNode(`${self.text} in (${values
|
|
199
|
+
.map((value) => ScopeService.literal(value, true))
|
|
200
|
+
.join(',')})`);
|
|
201
|
+
},
|
|
202
|
+
isNull: (self) => new predicate_util_1.PredicateNode(`${self.text} eq null`),
|
|
203
|
+
isNotNull: (self) => new predicate_util_1.PredicateNode(`${self.text} ne null`),
|
|
204
|
+
isTrue: (self) => new predicate_util_1.PredicateNode(`${self.text} eq true`),
|
|
205
|
+
isFalse: (self) => new predicate_util_1.PredicateNode(`${self.text} eq false`),
|
|
206
|
+
/* string */
|
|
207
|
+
lower: ScopeService.unaryFunction('tolower'),
|
|
208
|
+
upper: ScopeService.unaryFunction('toupper'),
|
|
209
|
+
trim: ScopeService.unaryFunction('trim'),
|
|
210
|
+
length: ScopeService.unaryFunction('length'),
|
|
211
|
+
concat: ScopeService.binaryFunction('concat'),
|
|
212
|
+
substring: (self, callArguments) => ScopeService.createMember(new ExpressionNode(callArguments[1] === undefined
|
|
213
|
+
? `substring(${self.text},${ScopeService.literal(callArguments[0])})`
|
|
214
|
+
: `substring(${self.text},${ScopeService.literal(callArguments[0])},${ScopeService.literal(callArguments[1])})`, self.depth)),
|
|
215
|
+
indexOf: ScopeService.binaryFunction('indexof'),
|
|
216
|
+
contains: ScopeService.stringMatch('contains'),
|
|
217
|
+
startsWith: ScopeService.stringMatch('startswith'),
|
|
218
|
+
endsWith: ScopeService.stringMatch('endswith'),
|
|
219
|
+
/** A no-op: it only re-types an ISO-string column as temporal. */
|
|
220
|
+
asDate: (self) => ScopeService.createMember(self),
|
|
221
|
+
/* date/time */
|
|
222
|
+
year: ScopeService.unaryFunction('year'),
|
|
223
|
+
month: ScopeService.unaryFunction('month'),
|
|
224
|
+
day: ScopeService.unaryFunction('day'),
|
|
225
|
+
hour: ScopeService.unaryFunction('hour'),
|
|
226
|
+
minute: ScopeService.unaryFunction('minute'),
|
|
227
|
+
second: ScopeService.unaryFunction('second'),
|
|
228
|
+
fractionalseconds: ScopeService.unaryFunction('fractionalseconds'),
|
|
229
|
+
totaloffsetminutes: ScopeService.unaryFunction('totaloffsetminutes'),
|
|
230
|
+
totalseconds: ScopeService.unaryFunction('totalseconds'),
|
|
231
|
+
date: ScopeService.unaryFunction('date'),
|
|
232
|
+
time: ScopeService.unaryFunction('time'),
|
|
233
|
+
/* arithmetic */
|
|
234
|
+
add: ScopeService.arithmetic('add'),
|
|
235
|
+
sub: ScopeService.arithmetic('sub'),
|
|
236
|
+
mul: ScopeService.arithmetic('mul'),
|
|
237
|
+
div: ScopeService.arithmetic('div'),
|
|
238
|
+
mod: ScopeService.arithmetic('mod'),
|
|
239
|
+
ceiling: ScopeService.unaryFunction('ceiling'),
|
|
240
|
+
floor: ScopeService.unaryFunction('floor'),
|
|
241
|
+
round: ScopeService.unaryFunction('round'),
|
|
242
|
+
/* type */
|
|
243
|
+
cast: (self, callArguments) => ScopeService.createMember(new ExpressionNode(`cast(${self.text},${callArguments[0]})`, self.depth)),
|
|
244
|
+
/* lambdas */
|
|
245
|
+
any: ScopeService.lambda('any'),
|
|
246
|
+
all: ScopeService.lambda('all'),
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* Look a called name up in the table. `hasOwnProperty` rather than a plain
|
|
250
|
+
* index read, so `constructor` or `__proto__` cannot resolve to an inherited
|
|
251
|
+
* member of `Object.prototype`.
|
|
252
|
+
*/
|
|
253
|
+
static filterFunction(name) {
|
|
254
|
+
return Object.prototype.hasOwnProperty.call(ScopeService.FILTER_FUNCTIONS, name)
|
|
255
|
+
? ScopeService.FILTER_FUNCTIONS[name]
|
|
256
|
+
: undefined;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
exports.ScopeService = ScopeService;
|
|
260
|
+
//# sourceMappingURL=scope.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.service.js","sourceRoot":"","sources":["../../../../../src/module/query/service/filter/scope.service.ts"],"names":[],"mappings":";;;AA0CA,qFAA6E;AAC7E,mFAA2E;AAC3E,+DAAsD;AACtD,qEAAiE;AAEjE,MAAa,cAAc;IAEhB;IAEA;IAEA;IALV,YACU,IAAY;IACrB,4DAA4D;IACnD,KAAa;IACtB,oEAAoE;IAC3D,aAAsB,KAAK;QAJ3B,SAAI,GAAJ,IAAI,CAAQ;QAEZ,UAAK,GAAL,KAAK,CAAQ;QAEb,eAAU,GAAV,UAAU,CAAiB;IAClC,CAAC;CACJ;AARD,wCAQC;AAOD,MAAa,YAAY;IACxB,uEAAuE;IAC/D,MAAM,CAAU,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IAEpD;;;;OAIG;IACH,MAAM,CAAC,SAAS;QACf,OAAO,YAAY,CAAC,YAAY,CAAC,IAAI,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,YAAY,CAClB,IAAoB,EACpB,MAAuB,EACvB,IAAa;QAEb,yEAAyE;QACzE,mEAAmE;QACnE,OAAO,IAAI,KAAK;QACf,0BAA0B,CAAC,CAAC,GAAG,EAAE,CAAC,SAAS,CAAsB,EACjE;YACC,GAAG,CAAC,OAAO,EAAE,QAAQ;gBACpB,IAAI,QAAQ,KAAK,YAAY,CAAC,IAAI;oBAAE,OAAO,IAAI,CAAC;gBAChD,IAAI,OAAO,QAAQ,KAAK,QAAQ;oBAAE,OAAO,SAAS,CAAC;gBACnD,mEAAmE;gBACnE,iEAAiE;gBACjE,iEAAiE;gBACjE,mEAAmE;gBACnE,iEAAiE;gBACjE,cAAc;gBACd,IACC,QAAQ,KAAK,MAAM;oBACnB,QAAQ,KAAK,QAAQ;oBACrB,QAAQ,KAAK,UAAU;oBACvB,QAAQ,KAAK,SAAS;oBAEtB,MAAM,IAAI,0CAAiB,CAAC,QAAQ,CAAC,CAAC;gBACvC,OAAO,YAAY,CAAC,YAAY,CAC/B,IAAI,cAAc,CACjB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,EACjD,IAAI,CAAC,KAAK,CACV,EACD,IAAI,EACJ,QAAQ,CACR,CAAC;YACH,CAAC;YACD,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,aAAwB;gBACrD,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;oBAC7C,MAAM,IAAI,4CAAkB,CAC3B,IAAI,IAAI,CAAC,IAAI,sCAAsC,EACnD,IAAI,CAAC,IAAI,CACT,CAAC;gBACH,MAAM,MAAM,GAAG,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;gBACjD,IAAI,MAAM,KAAK,SAAS;oBACvB,MAAM,IAAI,4CAAkB,CAC3B,GAAG,IAAI,uDAAuD,EAC9D,IAAI,CACJ,CAAC;gBACH,OAAO,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;YACtC,CAAC;YACD,GAAG,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,OAAO,QAAQ,KAAK,QAAQ;SACxD,CACD,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,MAAM,CAAC,MAAM,CAAC,KAAc;QAC3B,OAAO,OAAO,KAAK,KAAK,UAAU;YACjC,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;YAC7C,CAAC,CAAG,KAAiC,CAAC,YAAY,CAAC,IAAI,CAEzC;YACd,CAAC,CAAC,SAAS,CAAC;IACd,CAAC;IAED,qEAAqE;IAC7D,MAAM,CAAC,sBAAsB,CAAC,IAAoB;QACzD,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IACvD,CAAC;IAEO,MAAM,CAAC,WAAW,CACzB,KAAc;QAEd,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;YACzB,KAAK,KAAK,IAAI;YACd,OAAQ,KAA6B,CAAC,KAAK,KAAK,UAAU,CAC1D,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACK,MAAM,CAAC,OAAO,CAAC,KAAc,EAAE,SAAS,GAAG,KAAK;QACvD,IAAI,KAAK,KAAK,SAAS;YACtB,MAAM,IAAI,4CAAkB,CAC3B,+GAA+G,CAC/G,CAAC;QACH,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACpB,IAAI,SAAS;gBAAE,OAAO,MAAM,CAAC;YAC7B,MAAM,IAAI,4CAAkB,CAC3B,mHAAmH,CACnH,CAAC;QACH,CAAC;QACD,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,IAAI;YAAE,OAAO,YAAY,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,IAAA,mBAAK,EAAC,KAAK,CAAC,CAAC;QACnD,IAAI,OAAO,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QAChE,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;QACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAC1B,MAAM,IAAI,4CAAkB,CAC3B,GAAG,KAAK,iCAAiC,EACzC,MAAM,CAAC,KAAK,CAAC,CACb,CAAC;YACH,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;YAC3B,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChC,MAAM,IAAI,4CAAkB,CAAC,oCAAoC,CAAC,CAAC;YACpE,OAAO,IAAA,mBAAK,EAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QACnC,CAAC;QACD,IAAI,YAAY,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,OAAO,KAAK,IAAI;gBACnB,MAAM,IAAI,4CAAkB,CAAC,wCAAwC,CAAC,CAAC;YACxE,OAAO,IAAA,mBAAK,EAAC,OAAO,CAAC,CAAC;QACvB,CAAC;QACD,MAAM,IAAI,4CAAkB,CAC3B,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAClE,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,UAAU,CAAC,QAAgB;QACzC,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,CAC9B,IAAI,8BAAa,CAChB,GAAG,IAAI,CAAC,IAAI,IAAI,QAAQ,IAAI,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CACpE,CAAC;IACJ,CAAC;IAED,iDAAiD;IACzC,MAAM,CAAC,aAAa,CAAC,IAAY;QACxC,OAAO,CAAC,IAAI,EAAE,EAAE,CACf,YAAY,CAAC,YAAY,CACxB,IAAI,cAAc,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,IAAI,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CACvD,CAAC;IACJ,CAAC;IAED,0DAA0D;IAClD,MAAM,CAAC,cAAc,CAAC,IAAY;QACzC,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,CAC9B,YAAY,CAAC,YAAY,CACxB,IAAI,cAAc,CACjB,GAAG,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,EACjE,IAAI,CAAC,KAAK,CACV,CACD,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,UAAU,CAAC,QAAgB;QACzC,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,CAC9B,YAAY,CAAC,YAAY,CACxB,IAAI,cAAc,CACjB,GAAG,YAAY,CAAC,sBAAsB,CACrC,IAAI,CACJ,IAAI,QAAQ,IAAI,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,EACzD,IAAI,CAAC,KAAK,EACV,IAAI,CACJ,CACD,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,WAAW,CAAC,IAAY;QACtC,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,CAC9B,IAAI,8BAAa,CAChB,GAAG,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CACjE,CAAC;IACJ,CAAC;IAED;;;OAGG;IACK,MAAM,CAAC,WAAW,CAAC,KAAa;QACvC,OAAO,KAAK,GAAG,EAAE;YAChB,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,GAAG,KAAK,CAAC;YACjC,CAAC,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,CAAC;IACzE,CAAC;IAEO,MAAM,CAAC,MAAM,CAAC,IAAmB;QACxC,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE;YAC9B,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAEjB,CAAC;YACb,IAAI,CAAC,KAAK,EAAE,CAAC;gBACZ,IAAI,IAAI,KAAK,KAAK;oBACjB,MAAM,IAAI,4CAAkB,CAC3B,6DAA6D,EAC7D,KAAK,CACL,CAAC;gBACH,OAAO,IAAI,8BAAa,CAAC,GAAG,IAAI,CAAC,IAAI,QAAQ,CAAC,CAAC;YAChD,CAAC;YACD,MAAM,KAAK,GAAG,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnD,MAAM,KAAK,GAAG,KAAK,CAClB,YAAY,CAAC,YAAY,CAAC,IAAI,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CACpE,CAAC;YACF,IAAI,CAAC,CAAC,KAAK,YAAY,8BAAa,CAAC;gBACpC,MAAM,IAAI,4CAAkB,CAC3B,GAAG,IAAI,+CAA+C,EACtD,IAAI,CACJ,CAAC;YACH,+DAA+D;YAC/D,OAAO,IAAI,8BAAa,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;QAC1E,CAAC,CAAC;IACH,CAAC;IAEO,MAAM,CAAU,gBAAgB,GAAmC;QAC1E,gBAAgB;QAChB,EAAE,EAAE,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;QACjC,EAAE,EAAE,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;QACjC,EAAE,EAAE,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;QACjC,EAAE,EAAE,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;QACjC,EAAE,EAAE,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;QACjC,EAAE,EAAE,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;QACjC,EAAE,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE;YAC3B,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;gBAChD,MAAM,IAAI,4CAAkB,CAAC,+BAA+B,EAAE,IAAI,CAAC,CAAC;YACrE,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE,CAAC;gBAC7B,IAAI,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU;oBAC1C,MAAM,IAAI,4CAAkB,CAC3B,iHAAiH,EACjH,IAAI,CACJ,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,8BAAa,CACvB,GAAG,IAAI,CAAC,IAAI,QAAQ,MAAM;iBACxB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;iBACjD,IAAI,CAAC,GAAG,CAAC,GAAG,CACd,CAAC;QACH,CAAC;QACD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,8BAAa,CAAC,GAAG,IAAI,CAAC,IAAI,UAAU,CAAC;QAC3D,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,8BAAa,CAAC,GAAG,IAAI,CAAC,IAAI,UAAU,CAAC;QAC9D,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,8BAAa,CAAC,GAAG,IAAI,CAAC,IAAI,UAAU,CAAC;QAC3D,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,8BAAa,CAAC,GAAG,IAAI,CAAC,IAAI,WAAW,CAAC;QAE7D,YAAY;QACZ,KAAK,EAAE,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC;QAC5C,KAAK,EAAE,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC;QAC5C,IAAI,EAAE,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC;QACxC,MAAM,EAAE,YAAY,CAAC,aAAa,CAAC,QAAQ,CAAC;QAC5C,MAAM,EAAE,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC;QAC7C,SAAS,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,CAClC,YAAY,CAAC,YAAY,CACxB,IAAI,cAAc,CACjB,aAAa,CAAC,CAAC,CAAC,KAAK,SAAS;YAC7B,CAAC,CAAC,aAAa,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC,OAAO,CAC9C,aAAa,CAAC,CAAC,CAAC,CACf,GAAG;YACN,CAAC,CAAC,aAAa,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC,OAAO,CAC9C,aAAa,CAAC,CAAC,CAAC,CACf,IAAI,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,EACjD,IAAI,CAAC,KAAK,CACV,CACD;QACF,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,SAAS,CAAC;QAC/C,QAAQ,EAAE,YAAY,CAAC,WAAW,CAAC,UAAU,CAAC;QAC9C,UAAU,EAAE,YAAY,CAAC,WAAW,CAAC,YAAY,CAAC;QAClD,QAAQ,EAAE,YAAY,CAAC,WAAW,CAAC,UAAU,CAAC;QAC9C,kEAAkE;QAClE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC;QAEjD,eAAe;QACf,IAAI,EAAE,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC;QACxC,KAAK,EAAE,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC;QAC1C,GAAG,EAAE,YAAY,CAAC,aAAa,CAAC,KAAK,CAAC;QACtC,IAAI,EAAE,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC;QACxC,MAAM,EAAE,YAAY,CAAC,aAAa,CAAC,QAAQ,CAAC;QAC5C,MAAM,EAAE,YAAY,CAAC,aAAa,CAAC,QAAQ,CAAC;QAC5C,iBAAiB,EAAE,YAAY,CAAC,aAAa,CAAC,mBAAmB,CAAC;QAClE,kBAAkB,EAAE,YAAY,CAAC,aAAa,CAAC,oBAAoB,CAAC;QACpE,YAAY,EAAE,YAAY,CAAC,aAAa,CAAC,cAAc,CAAC;QACxD,IAAI,EAAE,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC;QACxC,IAAI,EAAE,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC;QAExC,gBAAgB;QAChB,GAAG,EAAE,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC;QACnC,GAAG,EAAE,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC;QACnC,GAAG,EAAE,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC;QACnC,GAAG,EAAE,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC;QACnC,GAAG,EAAE,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC;QACnC,OAAO,EAAE,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC;QAC9C,KAAK,EAAE,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC;QAC1C,KAAK,EAAE,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC;QAE1C,UAAU;QACV,IAAI,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,CAC7B,YAAY,CAAC,YAAY,CACxB,IAAI,cAAc,CACjB,QAAQ,IAAI,CAAC,IAAI,IAAI,aAAa,CAAC,CAAC,CAAc,GAAG,EACrD,IAAI,CAAC,KAAK,CACV,CACD;QAEF,aAAa;QACb,GAAG,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC;QAC/B,GAAG,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC;KAC/B,CAAC;IAEF;;;;OAIG;IACK,MAAM,CAAC,cAAc,CAAC,IAAY;QACzC,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAC1C,YAAY,CAAC,gBAAgB,EAC7B,IAAI,CACJ;YACA,CAAC,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC;YACrC,CAAC,CAAC,SAAS,CAAC;IACd,CAAC;;AArVF,oCAsVC"}
|
package/package.json
CHANGED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* State -> parts. Nothing here builds state and nothing here validates it: the
|
|
3
|
-
* chain has already decided what the query says, and this file only decides
|
|
4
|
-
* how it is printed.
|
|
5
|
-
*
|
|
6
|
-
* Keeping the two apart is the same parse -> bind -> emit split
|
|
7
|
-
* @ballistix.digital/typeorm-extensions uses on the server side, and it is why
|
|
8
|
-
* a golden-string test can be written against a hand-built state.
|
|
9
|
-
*/
|
|
10
|
-
import type { QueryState } from '../../domain/queryState.model';
|
|
11
|
-
/**
|
|
12
|
-
* The root's options, as `$key=value` pairs in a stable order. The order is
|
|
13
|
-
* the one a reader scans for: what is selected, then how it is shaped, then
|
|
14
|
-
* how it is paged.
|
|
15
|
-
*/
|
|
16
|
-
export declare const toQueryParts: (queryState: QueryState) => [string, string][];
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toQueryParts = void 0;
|
|
4
|
-
const predicate_util_1 = require("../filter/predicate.util");
|
|
5
|
-
/** Repeated `.filter()` calls AND together. */
|
|
6
|
-
const filterText = (queryState) => (0, predicate_util_1.combine)('and', queryState.filters).text;
|
|
7
|
-
/**
|
|
8
|
-
* The options of ONE expanded level, in the order the root prints them.
|
|
9
|
-
* They are joined with `;` inside the relation's parentheses.
|
|
10
|
-
*/
|
|
11
|
-
const nestedParts = (queryState) => {
|
|
12
|
-
const parts = [];
|
|
13
|
-
if (queryState.filters.length)
|
|
14
|
-
parts.push(`$filter=${filterText(queryState)}`);
|
|
15
|
-
if (queryState.select.length)
|
|
16
|
-
parts.push(`$select=${queryState.select.join(',')}`);
|
|
17
|
-
if (queryState.expand.length)
|
|
18
|
-
parts.push(`$expand=${expandList(queryState)}`);
|
|
19
|
-
if (queryState.top !== undefined)
|
|
20
|
-
parts.push(`$top=${queryState.top}`);
|
|
21
|
-
if (queryState.skip !== undefined)
|
|
22
|
-
parts.push(`$skip=${queryState.skip}`);
|
|
23
|
-
return parts;
|
|
24
|
-
};
|
|
25
|
-
/** `a($select=x),b` — a relation with no options of its own prints bare. */
|
|
26
|
-
const expandList = (queryState) => queryState.expand
|
|
27
|
-
.map((entry) => {
|
|
28
|
-
const parts = nestedParts(entry.queryState);
|
|
29
|
-
return parts.length ? `${entry.name}(${parts.join(';')})` : entry.name;
|
|
30
|
-
})
|
|
31
|
-
.join(',');
|
|
32
|
-
/**
|
|
33
|
-
* The root's options, as `$key=value` pairs in a stable order. The order is
|
|
34
|
-
* the one a reader scans for: what is selected, then how it is shaped, then
|
|
35
|
-
* how it is paged.
|
|
36
|
-
*/
|
|
37
|
-
const toQueryParts = (queryState) => {
|
|
38
|
-
const parts = [];
|
|
39
|
-
if (queryState.filters.length)
|
|
40
|
-
parts.push(['$filter', filterText(queryState)]);
|
|
41
|
-
if (queryState.search) {
|
|
42
|
-
parts.push(['$search', queryState.search.term]);
|
|
43
|
-
parts.push(['$searchColumns', queryState.search.columns.join(',')]);
|
|
44
|
-
}
|
|
45
|
-
if (queryState.select.length)
|
|
46
|
-
parts.push(['$select', queryState.select.join(',')]);
|
|
47
|
-
if (queryState.expand.length)
|
|
48
|
-
parts.push(['$expand', expandList(queryState)]);
|
|
49
|
-
if (queryState.orderBy.length)
|
|
50
|
-
parts.push(['$orderby', queryState.orderBy.join(',')]);
|
|
51
|
-
if (queryState.top !== undefined)
|
|
52
|
-
parts.push(['$top', String(queryState.top)]);
|
|
53
|
-
if (queryState.skip !== undefined)
|
|
54
|
-
parts.push(['$skip', String(queryState.skip)]);
|
|
55
|
-
if (queryState.count)
|
|
56
|
-
parts.push(['$count', 'true']);
|
|
57
|
-
return parts;
|
|
58
|
-
};
|
|
59
|
-
exports.toQueryParts = toQueryParts;
|
|
60
|
-
//# sourceMappingURL=queryParts.util.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"queryParts.util.js","sourceRoot":"","sources":["../../../../../src/module/query/util/emit/queryParts.util.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { ExpressionNode } from './literal.util';
|
|
2
|
-
type FilterFunction = (self: ExpressionNode, callArguments: readonly unknown[]) => unknown;
|
|
3
|
-
/**
|
|
4
|
-
* Look a called name up in the table. `hasOwnProperty` rather than a plain
|
|
5
|
-
* index read, so `constructor` or `__proto__` cannot resolve to an inherited
|
|
6
|
-
* member of `Object.prototype`.
|
|
7
|
-
*/
|
|
8
|
-
export declare const filterFunction: (name: string) => FilterFunction | undefined;
|
|
9
|
-
export {};
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.filterFunction = void 0;
|
|
4
|
-
const invalidFilter_exception_1 = require("../../exception/invalidFilter.exception");
|
|
5
|
-
const literal_util_1 = require("./literal.util");
|
|
6
|
-
const predicate_util_1 = require("./predicate.util");
|
|
7
|
-
const scopeProxy_util_1 = require("./scopeProxy.util");
|
|
8
|
-
const comparison = (operator) => (self, callArguments) => new predicate_util_1.PredicateNode(`${self.text} ${operator} ${(0, literal_util_1.literal)(callArguments[0])}`);
|
|
9
|
-
/** A one-argument SQL function: `name(self)`. */
|
|
10
|
-
const unaryFunction = (name) => (self) => (0, scopeProxy_util_1.createMember)(new literal_util_1.ExpressionNode(`${name}(${self.text})`, self.depth));
|
|
11
|
-
/** A two-argument SQL function: `name(self,argument)`. */
|
|
12
|
-
const binaryFunction = (name) => (self, callArguments) => (0, scopeProxy_util_1.createMember)(new literal_util_1.ExpressionNode(`${name}(${self.text},${(0, literal_util_1.literal)(callArguments[0])})`, self.depth));
|
|
13
|
-
const arithmetic = (operator) => (self, callArguments) => (0, scopeProxy_util_1.createMember)(new literal_util_1.ExpressionNode(`${(0, literal_util_1.parenthesiseArithmetic)(self)} ${operator} ${(0, literal_util_1.literal)(callArguments[0])}`, self.depth, true));
|
|
14
|
-
const stringMatch = (name) => (self, callArguments) => new predicate_util_1.PredicateNode(`${name}(${self.text},${(0, literal_util_1.literal)(callArguments[0])})`);
|
|
15
|
-
/**
|
|
16
|
-
* A distinct alias letter per lambda nesting level, so an inner lambda never
|
|
17
|
-
* shadows the outer one and `b/x ne a/y` stays expressible.
|
|
18
|
-
*/
|
|
19
|
-
const lambdaAlias = (depth) => depth < 26
|
|
20
|
-
? String.fromCharCode(97 + depth)
|
|
21
|
-
: `${String.fromCharCode(97 + (depth % 26))}${Math.floor(depth / 26)}`;
|
|
22
|
-
const lambda = (kind) => (self, callArguments) => {
|
|
23
|
-
const build = callArguments[0];
|
|
24
|
-
if (!build) {
|
|
25
|
-
if (kind === 'all')
|
|
26
|
-
throw new invalidFilter_exception_1.InvalidFilterError('all() requires a predicate; the server rejects a bare all()', 'all');
|
|
27
|
-
return new predicate_util_1.PredicateNode(`${self.text}/any()`);
|
|
28
|
-
}
|
|
29
|
-
const alias = lambdaAlias(self.depth);
|
|
30
|
-
const inner = build((0, scopeProxy_util_1.createMember)(new literal_util_1.ExpressionNode(alias, self.depth + 1)));
|
|
31
|
-
if (!(inner instanceof predicate_util_1.PredicateNode))
|
|
32
|
-
throw new invalidFilter_exception_1.InvalidFilterError(`${kind}() must return a predicate, not a bare column`, kind);
|
|
33
|
-
// The colon carries no space: the grammar requires `any(a:…)`.
|
|
34
|
-
return new predicate_util_1.PredicateNode(`${self.text}/${kind}(${alias}:${inner.text})`);
|
|
35
|
-
};
|
|
36
|
-
const FILTER_FUNCTIONS = {
|
|
37
|
-
/* comparison */
|
|
38
|
-
eq: comparison('eq'),
|
|
39
|
-
ne: comparison('ne'),
|
|
40
|
-
gt: comparison('gt'),
|
|
41
|
-
ge: comparison('ge'),
|
|
42
|
-
lt: comparison('lt'),
|
|
43
|
-
le: comparison('le'),
|
|
44
|
-
in: (self, callArguments) => {
|
|
45
|
-
const values = callArguments[0];
|
|
46
|
-
if (!Array.isArray(values) || values.length === 0)
|
|
47
|
-
throw new invalidFilter_exception_1.InvalidFilterError('in() needs at least one value', 'in');
|
|
48
|
-
for (const member of values) {
|
|
49
|
-
if ((0, scopeProxy_util_1.nodeOf)(member)?.arithmetic)
|
|
50
|
-
throw new invalidFilter_exception_1.InvalidFilterError('in() takes literals and columns as members; the server grammar rejects an arithmetic expression inside in (...)', 'in');
|
|
51
|
-
}
|
|
52
|
-
return new predicate_util_1.PredicateNode(`${self.text} in (${values
|
|
53
|
-
.map((value) => (0, literal_util_1.literal)(value, true))
|
|
54
|
-
.join(',')})`);
|
|
55
|
-
},
|
|
56
|
-
isNull: (self) => new predicate_util_1.PredicateNode(`${self.text} eq null`),
|
|
57
|
-
isNotNull: (self) => new predicate_util_1.PredicateNode(`${self.text} ne null`),
|
|
58
|
-
isTrue: (self) => new predicate_util_1.PredicateNode(`${self.text} eq true`),
|
|
59
|
-
isFalse: (self) => new predicate_util_1.PredicateNode(`${self.text} eq false`),
|
|
60
|
-
/* string */
|
|
61
|
-
lower: unaryFunction('tolower'),
|
|
62
|
-
upper: unaryFunction('toupper'),
|
|
63
|
-
trim: unaryFunction('trim'),
|
|
64
|
-
length: unaryFunction('length'),
|
|
65
|
-
concat: binaryFunction('concat'),
|
|
66
|
-
substring: (self, callArguments) => (0, scopeProxy_util_1.createMember)(new literal_util_1.ExpressionNode(callArguments[1] === undefined
|
|
67
|
-
? `substring(${self.text},${(0, literal_util_1.literal)(callArguments[0])})`
|
|
68
|
-
: `substring(${self.text},${(0, literal_util_1.literal)(callArguments[0])},${(0, literal_util_1.literal)(callArguments[1])})`, self.depth)),
|
|
69
|
-
indexOf: binaryFunction('indexof'),
|
|
70
|
-
contains: stringMatch('contains'),
|
|
71
|
-
startsWith: stringMatch('startswith'),
|
|
72
|
-
endsWith: stringMatch('endswith'),
|
|
73
|
-
/** A no-op: it only re-types an ISO-string column as temporal. */
|
|
74
|
-
asDate: (self) => (0, scopeProxy_util_1.createMember)(self),
|
|
75
|
-
/* date/time */
|
|
76
|
-
year: unaryFunction('year'),
|
|
77
|
-
month: unaryFunction('month'),
|
|
78
|
-
day: unaryFunction('day'),
|
|
79
|
-
hour: unaryFunction('hour'),
|
|
80
|
-
minute: unaryFunction('minute'),
|
|
81
|
-
second: unaryFunction('second'),
|
|
82
|
-
fractionalseconds: unaryFunction('fractionalseconds'),
|
|
83
|
-
totaloffsetminutes: unaryFunction('totaloffsetminutes'),
|
|
84
|
-
totalseconds: unaryFunction('totalseconds'),
|
|
85
|
-
date: unaryFunction('date'),
|
|
86
|
-
time: unaryFunction('time'),
|
|
87
|
-
/* arithmetic */
|
|
88
|
-
add: arithmetic('add'),
|
|
89
|
-
sub: arithmetic('sub'),
|
|
90
|
-
mul: arithmetic('mul'),
|
|
91
|
-
div: arithmetic('div'),
|
|
92
|
-
mod: arithmetic('mod'),
|
|
93
|
-
ceiling: unaryFunction('ceiling'),
|
|
94
|
-
floor: unaryFunction('floor'),
|
|
95
|
-
round: unaryFunction('round'),
|
|
96
|
-
/* type */
|
|
97
|
-
cast: (self, callArguments) => (0, scopeProxy_util_1.createMember)(new literal_util_1.ExpressionNode(`cast(${self.text},${callArguments[0]})`, self.depth)),
|
|
98
|
-
/* lambdas */
|
|
99
|
-
any: lambda('any'),
|
|
100
|
-
all: lambda('all'),
|
|
101
|
-
};
|
|
102
|
-
/**
|
|
103
|
-
* Look a called name up in the table. `hasOwnProperty` rather than a plain
|
|
104
|
-
* index read, so `constructor` or `__proto__` cannot resolve to an inherited
|
|
105
|
-
* member of `Object.prototype`.
|
|
106
|
-
*/
|
|
107
|
-
const filterFunction = (name) => Object.prototype.hasOwnProperty.call(FILTER_FUNCTIONS, name)
|
|
108
|
-
? FILTER_FUNCTIONS[name]
|
|
109
|
-
: undefined;
|
|
110
|
-
exports.filterFunction = filterFunction;
|
|
111
|
-
//# sourceMappingURL=filterFunction.util.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"filterFunction.util.js","sourceRoot":"","sources":["../../../../../src/module/query/util/filter/filterFunction.util.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export declare class ExpressionNode {
|
|
2
|
-
readonly text: string;
|
|
3
|
-
/** lambda nesting level, for deterministic alias letters */
|
|
4
|
-
readonly depth: number;
|
|
5
|
-
/** true for `a add 1`: needs parentheses as an operand of `mul`. */
|
|
6
|
-
readonly arithmetic: boolean;
|
|
7
|
-
constructor(text: string,
|
|
8
|
-
/** lambda nesting level, for deterministic alias letters */
|
|
9
|
-
depth: number,
|
|
10
|
-
/** true for `a add 1`: needs parentheses as an operand of `mul`. */
|
|
11
|
-
arithmetic?: boolean);
|
|
12
|
-
}
|
|
13
|
-
/** `a add 1` used as an operand of `mul` must become `(a add 1)`. */
|
|
14
|
-
export declare const parenthesiseArithmetic: (node: ExpressionNode) => string;
|
|
15
|
-
/**
|
|
16
|
-
* @param allowNull `in()` accepts a null member (`in (2024,null)` is a legal
|
|
17
|
-
* set test); every other position rejects it — `eq(null)` must look nothing
|
|
18
|
-
* like "no filter", so `isNull()`/`isNotNull()` are the only way to test for null.
|
|
19
|
-
* `undefined` is never a literal, in any position: it means "nothing was
|
|
20
|
-
* passed", not "the value is null", and reaching this function with it is
|
|
21
|
-
* only possible through an `any`/`as never` cast around the type layer.
|
|
22
|
-
*/
|
|
23
|
-
export declare const literal: (value: unknown, allowNull?: boolean) => string;
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.literal = exports.parenthesiseArithmetic = exports.ExpressionNode = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* `ExpressionNode`, the node behind every non-boolean expression, and
|
|
6
|
-
* `literal()`, which turns a JS value into the OData text of that literal.
|
|
7
|
-
*
|
|
8
|
-
* `parenthesiseArithmetic` wraps an arithmetic expression (`a add 1`) in
|
|
9
|
-
* parentheses when it is used as an operand of another arithmetic operator
|
|
10
|
-
* (`mul`), so `(a add 1) mul 2` parses the way the caller wrote it rather than
|
|
11
|
-
* as `a add (1 mul 2)`.
|
|
12
|
-
*/
|
|
13
|
-
const invalidFilter_exception_1 = require("../../exception/invalidFilter.exception");
|
|
14
|
-
const escape_util_1 = require("./escape.util");
|
|
15
|
-
const scopeProxy_util_1 = require("./scopeProxy.util");
|
|
16
|
-
class ExpressionNode {
|
|
17
|
-
text;
|
|
18
|
-
depth;
|
|
19
|
-
arithmetic;
|
|
20
|
-
constructor(text,
|
|
21
|
-
/** lambda nesting level, for deterministic alias letters */
|
|
22
|
-
depth,
|
|
23
|
-
/** true for `a add 1`: needs parentheses as an operand of `mul`. */
|
|
24
|
-
arithmetic = false) {
|
|
25
|
-
this.text = text;
|
|
26
|
-
this.depth = depth;
|
|
27
|
-
this.arithmetic = arithmetic;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
exports.ExpressionNode = ExpressionNode;
|
|
31
|
-
/** `a add 1` used as an operand of `mul` must become `(a add 1)`. */
|
|
32
|
-
const parenthesiseArithmetic = (node) => node.arithmetic ? `(${node.text})` : node.text;
|
|
33
|
-
exports.parenthesiseArithmetic = parenthesiseArithmetic;
|
|
34
|
-
const isLuxonLike = (value) => typeof value === 'object' &&
|
|
35
|
-
value !== null &&
|
|
36
|
-
typeof value.toISO === 'function';
|
|
37
|
-
/**
|
|
38
|
-
* @param allowNull `in()` accepts a null member (`in (2024,null)` is a legal
|
|
39
|
-
* set test); every other position rejects it — `eq(null)` must look nothing
|
|
40
|
-
* like "no filter", so `isNull()`/`isNotNull()` are the only way to test for null.
|
|
41
|
-
* `undefined` is never a literal, in any position: it means "nothing was
|
|
42
|
-
* passed", not "the value is null", and reaching this function with it is
|
|
43
|
-
* only possible through an `any`/`as never` cast around the type layer.
|
|
44
|
-
*/
|
|
45
|
-
const literal = (value, allowNull = false) => {
|
|
46
|
-
if (value === undefined)
|
|
47
|
-
throw new invalidFilter_exception_1.InvalidFilterError('undefined is not an OData literal; omit the comparison entirely, or use isNull()/isNotNull() to test for null');
|
|
48
|
-
if (value === null) {
|
|
49
|
-
if (allowNull)
|
|
50
|
-
return 'null';
|
|
51
|
-
throw new invalidFilter_exception_1.InvalidFilterError('null is not an OData literal here; use isNull()/isNotNull() to test for null, or in() to allow it as a set member');
|
|
52
|
-
}
|
|
53
|
-
const node = (0, scopeProxy_util_1.nodeOf)(value);
|
|
54
|
-
if (node)
|
|
55
|
-
return (0, exports.parenthesiseArithmetic)(node);
|
|
56
|
-
if (typeof value === 'string')
|
|
57
|
-
return (0, escape_util_1.quote)(value);
|
|
58
|
-
if (typeof value === 'boolean')
|
|
59
|
-
return value ? 'true' : 'false';
|
|
60
|
-
if (typeof value === 'bigint')
|
|
61
|
-
return value.toString();
|
|
62
|
-
if (typeof value === 'number') {
|
|
63
|
-
if (!Number.isFinite(value))
|
|
64
|
-
throw new invalidFilter_exception_1.InvalidFilterError(`${value} is not an OData number literal`, String(value));
|
|
65
|
-
return String(value);
|
|
66
|
-
}
|
|
67
|
-
if (value instanceof Date) {
|
|
68
|
-
if (Number.isNaN(value.getTime()))
|
|
69
|
-
throw new invalidFilter_exception_1.InvalidFilterError('an invalid Date has no ISO literal');
|
|
70
|
-
return (0, escape_util_1.quote)(value.toISOString());
|
|
71
|
-
}
|
|
72
|
-
if (isLuxonLike(value)) {
|
|
73
|
-
const isoText = value.toISO();
|
|
74
|
-
if (isoText === null)
|
|
75
|
-
throw new invalidFilter_exception_1.InvalidFilterError('an invalid DateTime has no ISO literal');
|
|
76
|
-
return (0, escape_util_1.quote)(isoText);
|
|
77
|
-
}
|
|
78
|
-
throw new invalidFilter_exception_1.InvalidFilterError(`${Object.prototype.toString.call(value)} is not an OData literal`);
|
|
79
|
-
};
|
|
80
|
-
exports.literal = literal;
|
|
81
|
-
//# sourceMappingURL=literal.util.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"literal.util.js","sourceRoot":"","sources":["../../../../../src/module/query/util/filter/literal.util.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;GAQG;AACH,qFAA6E;AAC7E,+CAAsC;AACtC,uDAA2C;AAE3C,MAAa,cAAc;IAEhB;IAEA;IAEA;IALV,YACU,IAAY;IACrB,4DAA4D;IACnD,KAAa;IACtB,oEAAoE;IAC3D,aAAsB,KAAK;QAJ3B,SAAI,GAAJ,IAAI,CAAQ;QAEZ,UAAK,GAAL,KAAK,CAAQ;QAEb,eAAU,GAAV,UAAU,CAAiB;IAClC,CAAC;CACJ;AARD,wCAQC;AAED,qEAAqE;AAC9D,MAAM,sBAAsB,GAAG,CAAC,IAAoB,EAAU,EAAE,CACtE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;AADnC,QAAA,sBAAsB,0BACa;AAEhD,MAAM,WAAW,GAAG,CAAC,KAAc,EAAuC,EAAE,CAC3E,OAAO,KAAK,KAAK,QAAQ;IACzB,KAAK,KAAK,IAAI;IACd,OAAQ,KAA6B,CAAC,KAAK,KAAK,UAAU,CAAC;AAE5D;;;;;;;GAOG;AACI,MAAM,OAAO,GAAG,CAAC,KAAc,EAAE,SAAS,GAAG,KAAK,EAAU,EAAE;IACpE,IAAI,KAAK,KAAK,SAAS;QACtB,MAAM,IAAI,4CAAkB,CAC3B,+GAA+G,CAC/G,CAAC;IACH,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACpB,IAAI,SAAS;YAAE,OAAO,MAAM,CAAC;QAC7B,MAAM,IAAI,4CAAkB,CAC3B,mHAAmH,CACnH,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,IAAA,wBAAM,EAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,IAAI;QAAE,OAAO,IAAA,8BAAsB,EAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAA,mBAAK,EAAC,KAAK,CAAC,CAAC;IACnD,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC1B,MAAM,IAAI,4CAAkB,CAC3B,GAAG,KAAK,iCAAiC,EACzC,MAAM,CAAC,KAAK,CAAC,CACb,CAAC;QACH,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IACD,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC3B,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAChC,MAAM,IAAI,4CAAkB,CAAC,oCAAoC,CAAC,CAAC;QACpE,OAAO,IAAA,mBAAK,EAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,OAAO,KAAK,IAAI;YACnB,MAAM,IAAI,4CAAkB,CAAC,wCAAwC,CAAC,CAAC;QACxE,OAAO,IAAA,mBAAK,EAAC,OAAO,CAAC,CAAC;IACvB,CAAC;IACD,MAAM,IAAI,4CAAkB,CAC3B,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAClE,CAAC;AACH,CAAC,CAAC;AAtCW,QAAA,OAAO,WAsClB"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { ExpressionNode } from './literal.util';
|
|
2
|
-
/** The node behind a scope proxy, or `undefined` for a plain value. */
|
|
3
|
-
export declare const nodeOf: (value: unknown) => ExpressionNode | undefined;
|
|
4
|
-
/**
|
|
5
|
-
* `createMember(node)` is a value; `createMember(node, parent, name)` is a
|
|
6
|
-
* member of `parent` that has not yet decided whether it is a path segment or
|
|
7
|
-
* a function call.
|
|
8
|
-
*
|
|
9
|
-
* The target is an arrow function so the proxy is callable. An arrow function
|
|
10
|
-
* has no `prototype`, and its `name`/`length` are configurable, so no Proxy
|
|
11
|
-
* invariant forces a value through — a DTO column called `name` or `length`
|
|
12
|
-
* still reaches the trap.
|
|
13
|
-
*
|
|
14
|
-
* `v.name.eq('x')` on `rootScope()` gives `name eq 'x'`. See
|
|
15
|
-
* docs/maintainer/architecture.md, How `Proxy` works here.
|
|
16
|
-
*/
|
|
17
|
-
export declare const createMember: (node: ExpressionNode, parent?: ExpressionNode, name?: string) => any;
|
|
18
|
-
/**
|
|
19
|
-
* The filter scope of an entity: an empty path at lambda depth 0. An expanded
|
|
20
|
-
* entity is filtered relative to itself, so it takes the same empty root.
|
|
21
|
-
*/
|
|
22
|
-
export declare const rootScope: () => any;
|