@ballistix.digital/odata-query-builder 0.7.0 → 0.9.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.
Files changed (35) hide show
  1. package/dist/module/query/domain/chain/expandChain.model.d.ts +4 -4
  2. package/dist/module/query/domain/filter/comparable.model.d.ts +4 -4
  3. package/dist/module/query/domain/filter/node.model.d.ts +3 -2
  4. package/dist/module/query/domain/filter/node.model.js +3 -2
  5. package/dist/module/query/domain/filter/node.model.js.map +1 -1
  6. package/dist/module/query/exception/queryBuilder.exception.d.ts +2 -2
  7. package/dist/module/query/exception/queryBuilder.exception.js +2 -2
  8. package/dist/module/query/service/emit/emit.facade.d.ts +2 -8
  9. package/dist/module/query/service/emit/emit.facade.js +3 -17
  10. package/dist/module/query/service/emit/emit.facade.js.map +1 -1
  11. package/dist/module/query/service/emit/emit.service.d.ts +38 -0
  12. package/dist/module/query/service/emit/emit.service.js +89 -0
  13. package/dist/module/query/service/emit/emit.service.js.map +1 -0
  14. package/dist/module/query/service/filter/filter.facade.d.ts +4 -17
  15. package/dist/module/query/service/filter/filter.facade.js +12 -61
  16. package/dist/module/query/service/filter/filter.facade.js.map +1 -1
  17. package/dist/module/query/service/filter/filter.service.d.ts +51 -0
  18. package/dist/module/query/service/filter/filter.service.js +88 -0
  19. package/dist/module/query/service/filter/filter.service.js.map +1 -0
  20. package/dist/module/query/service/filter/scope.service.d.ts +70 -0
  21. package/dist/module/query/service/filter/scope.service.js +260 -0
  22. package/dist/module/query/service/filter/scope.service.js.map +1 -0
  23. package/package.json +3 -2
  24. package/dist/module/query/util/emit/queryParts.util.d.ts +0 -16
  25. package/dist/module/query/util/emit/queryParts.util.js +0 -60
  26. package/dist/module/query/util/emit/queryParts.util.js.map +0 -1
  27. package/dist/module/query/util/filter/filterFunction.util.d.ts +0 -9
  28. package/dist/module/query/util/filter/filterFunction.util.js +0 -111
  29. package/dist/module/query/util/filter/filterFunction.util.js.map +0 -1
  30. package/dist/module/query/util/filter/literal.util.d.ts +0 -23
  31. package/dist/module/query/util/filter/literal.util.js +0 -81
  32. package/dist/module/query/util/filter/literal.util.js.map +0 -1
  33. package/dist/module/query/util/filter/scopeProxy.util.d.ts +0 -22
  34. package/dist/module/query/util/filter/scopeProxy.util.js +0 -93
  35. package/dist/module/query/util/filter/scopeProxy.util.js.map +0 -1
@@ -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;
@@ -1,93 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rootScope = exports.createMember = exports.nodeOf = void 0;
4
- /**
5
- * The JavaScript built-in class `Proxy` behind a filter scope: `createMember`, `rootScope`, and
6
- * `nodeOf` — the one place a node comes back out of a proxy.
7
- *
8
- * THE COLLISION PROBLEM AND ITS FIX
9
- * ---------------------------------
10
- * At runtime a property name carries no type, so `a.year` is ambiguous: the
11
- * `year()` date function, or a column actually called `year`. A single
12
- * "methods first, path second" Proxy has to guess, and guesses wrong on every
13
- * entity with a column named `year`, `name`, `length` or `date`.
14
- *
15
- * The fix: a property read NEVER resolves a function. Reading `x.foo` always
16
- * returns a *member* — a callable proxy that remembers (parent node, "foo").
17
- * - Read further from it -> "foo" was a path segment: `parent/foo`.
18
- * - CALL it -> "foo" was a function: `foo(parent)`.
19
- * A path segment is never called and a function is never left uncalled, so the
20
- * two roles are told apart by syntax the caller already writes. A column named
21
- * `year` therefore works, and so does `year()` over a sibling column, in the
22
- * same expression.
23
- *
24
- * The node itself is reachable only through a Symbol, which no DTO key can be.
25
- *
26
- * The import back into `filterFunction.util.ts` is a real (not type-only)
27
- * cycle, and so is `literal.util.ts`'s import back into this file. Both are
28
- * safe because nothing here runs at module load: a trap body is entered when a
29
- * caller builds a filter, long after every module has finished loading.
30
- */
31
- const invalidFilter_exception_1 = require("../../exception/invalidFilter.exception");
32
- const reservedName_exception_1 = require("../../exception/reservedName.exception");
33
- const filterFunction_util_1 = require("./filterFunction.util");
34
- const literal_util_1 = require("./literal.util");
35
- /** The only key that reads a node. A DTO key can never be a symbol. */
36
- const NODE = Symbol('odata.node');
37
- /** The node behind a scope proxy, or `undefined` for a plain value. */
38
- const nodeOf = (value) => typeof value === 'function' || (typeof value === 'object' && value !== null)
39
- ? value[NODE]
40
- : undefined;
41
- exports.nodeOf = nodeOf;
42
- /**
43
- * `createMember(node)` is a value; `createMember(node, parent, name)` is a
44
- * member of `parent` that has not yet decided whether it is a path segment or
45
- * a function call.
46
- *
47
- * The target is an arrow function so the proxy is callable. An arrow function
48
- * has no `prototype`, and its `name`/`length` are configurable, so no Proxy
49
- * invariant forces a value through — a DTO column called `name` or `length`
50
- * still reaches the trap.
51
- *
52
- * `v.name.eq('x')` on `rootScope()` gives `name eq 'x'`. See
53
- * docs/maintainer/architecture.md, How `Proxy` works here.
54
- */
55
- const createMember = (node, parent, name) =>
56
- // The target is never invoked: the `apply` trap owns every call. It only
57
- // has to BE callable, so the Proxy accepts an `apply` trap at all.
58
- new Proxy(/* istanbul ignore next */ (() => undefined), {
59
- get(_target, property) {
60
- if (property === NODE)
61
- return node;
62
- if (typeof property !== 'string')
63
- return undefined;
64
- // Reserved names THROW rather than return undefined, so `await q`,
65
- // `JSON.stringify(q)` and an implicit `${q}`/arithmetic coercion fail
66
- // loudly instead of silently — the last two would otherwise reach
67
- // `apply` as a call to a function named `toString`/`valueOf` that the
68
- // OData function table does not know, a confusing error to land on.
69
- if (property === 'then' ||
70
- property === 'toJSON' ||
71
- property === 'toString' ||
72
- property === 'valueOf')
73
- throw new reservedName_exception_1.ReservedNameError(property);
74
- return (0, exports.createMember)(new literal_util_1.ExpressionNode(node.text ? `${node.text}/${property}` : property, node.depth), node, property);
75
- },
76
- apply(_target, _thisArgument, callArguments) {
77
- if (parent === undefined || name === undefined)
78
- throw new invalidFilter_exception_1.InvalidFilterError(`"${node.text}" is a property path, not a function`, node.text);
79
- const method = (0, filterFunction_util_1.filterFunction)(name);
80
- if (method === undefined)
81
- throw new invalidFilter_exception_1.InvalidFilterError(`${name}() is not an OData filter function served by this API`, name);
82
- return method(parent, callArguments);
83
- },
84
- has: (_target, property) => typeof property === 'string',
85
- });
86
- exports.createMember = createMember;
87
- /**
88
- * The filter scope of an entity: an empty path at lambda depth 0. An expanded
89
- * entity is filtered relative to itself, so it takes the same empty root.
90
- */
91
- const rootScope = () => (0, exports.createMember)(new literal_util_1.ExpressionNode('', 0));
92
- exports.rootScope = rootScope;
93
- //# sourceMappingURL=scopeProxy.util.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scopeProxy.util.js","sourceRoot":"","sources":["../../../../../src/module/query/util/filter/scopeProxy.util.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qFAA6E;AAC7E,mFAA2E;AAC3E,+DAAuD;AACvD,iDAAgD;AAEhD,uEAAuE;AACvE,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AAElC,uEAAuE;AAChE,MAAM,MAAM,GAAG,CAAC,KAAc,EAA8B,EAAE,CACpE,OAAO,KAAK,KAAK,UAAU,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;IAC3E,CAAC,CAAG,KAAiC,CAAC,IAAI,CAAgC;IAC1E,CAAC,CAAC,SAAS,CAAC;AAHD,QAAA,MAAM,UAGL;AAEd;;;;;;;;;;;;GAYG;AACI,MAAM,YAAY,GAAG,CAC3B,IAAoB,EACpB,MAAuB,EACvB,IAAa,EACP,EAAE;AACR,yEAAyE;AACzE,mEAAmE;AACnE,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC,GAAG,EAAE,CAAC,SAAS,CAAsB,EAAE;IAC5E,GAAG,CAAC,OAAO,EAAE,QAAQ;QACpB,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACnC,IAAI,OAAO,QAAQ,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QACnD,mEAAmE;QACnE,sEAAsE;QACtE,kEAAkE;QAClE,sEAAsE;QACtE,oEAAoE;QACpE,IACC,QAAQ,KAAK,MAAM;YACnB,QAAQ,KAAK,QAAQ;YACrB,QAAQ,KAAK,UAAU;YACvB,QAAQ,KAAK,SAAS;YAEtB,MAAM,IAAI,0CAAiB,CAAC,QAAQ,CAAC,CAAC;QACvC,OAAO,IAAA,oBAAY,EAClB,IAAI,6BAAc,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;IACH,CAAC;IACD,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,aAAwB;QACrD,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;YAC7C,MAAM,IAAI,4CAAkB,CAC3B,IAAI,IAAI,CAAC,IAAI,sCAAsC,EACnD,IAAI,CAAC,IAAI,CACT,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,oCAAc,EAAC,IAAI,CAAC,CAAC;QACpC,IAAI,MAAM,KAAK,SAAS;YACvB,MAAM,IAAI,4CAAkB,CAC3B,GAAG,IAAI,uDAAuD,EAC9D,IAAI,CACJ,CAAC;QACH,OAAO,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACtC,CAAC;IACD,GAAG,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,OAAO,QAAQ,KAAK,QAAQ;CACxD,CAAC,CAAC;AA/CS,QAAA,YAAY,gBA+CrB;AAEJ;;;GAGG;AACI,MAAM,SAAS,GAAG,GAAQ,EAAE,CAAC,IAAA,oBAAY,EAAC,IAAI,6BAAc,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;AAA/D,QAAA,SAAS,aAAsD"}