@ballistix.digital/odata-query-builder 0.10.0 → 0.12.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/index.d.ts +3 -3
- package/dist/index.js.map +1 -1
- package/dist/module/query/domain/chain/chain.model.d.ts +25 -6
- package/dist/module/query/domain/chain/expandChain.model.d.ts +15 -9
- package/dist/module/query/domain/chain/itemChain.model.d.ts +8 -5
- package/dist/module/query/domain/exceptionDetail.model.d.ts +3 -2
- package/dist/module/query/domain/exceptionDetail.model.js +3 -2
- package/dist/module/query/domain/exceptionDetail.model.js.map +1 -1
- package/dist/module/query/domain/filter/dateExpr.model.d.ts +1 -1
- 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/domain/filter/scope.model.d.ts +24 -10
- package/dist/module/query/domain/queryState.model.d.ts +3 -3
- package/dist/module/query/exception/invalidFilter.exception.js +4 -0
- package/dist/module/query/exception/invalidFilter.exception.js.map +1 -1
- package/dist/module/query/exception/queryBuilder.exception.d.ts +4 -1
- package/dist/module/query/exception/queryBuilder.exception.js +4 -1
- package/dist/module/query/exception/queryBuilder.exception.js.map +1 -1
- package/dist/module/query/exception/reservedName.exception.d.ts +2 -0
- package/dist/module/query/exception/reservedName.exception.js +12 -5
- package/dist/module/query/exception/reservedName.exception.js.map +1 -1
- package/dist/module/query/service/emit/emit.service.d.ts +5 -3
- package/dist/module/query/service/emit/emit.service.js.map +1 -1
- package/dist/module/query/service/filter/filter.service.js +5 -3
- package/dist/module/query/service/filter/filter.service.js.map +1 -1
- package/dist/module/query/service/filter/scope.service.d.ts +8 -7
- package/dist/module/query/service/filter/scope.service.js +39 -24
- package/dist/module/query/service/filter/scope.service.js.map +1 -1
- package/dist/module/query/service/queryChain.service.d.ts +17 -8
- package/dist/module/query/service/queryChain.service.js +25 -14
- package/dist/module/query/service/queryChain.service.js.map +1 -1
- package/dist/module/query/util/filter/predicate.util.js +2 -0
- package/dist/module/query/util/filter/predicate.util.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* 400 is deliberately absent, so it is a compile error rather than a runtime
|
|
7
7
|
* failure.
|
|
8
8
|
*/
|
|
9
|
-
import type { Chain, ExpandKey, ExpandNamespace, QueryParams } from './module/query/domain/chain/chain.model';
|
|
9
|
+
import type { Chain, EmbeddedExpandNamespace, ExpandKey, ExpandNamespace, QueryParams } from './module/query/domain/chain/chain.model';
|
|
10
10
|
import type { ExpandChain, ToOneExpandChain } from './module/query/domain/chain/expandChain.model';
|
|
11
11
|
import type { ItemChain } from './module/query/domain/chain/itemChain.model';
|
|
12
12
|
import { QueryBuilderExceptionCode } from './module/query/domain/exceptionCode.model';
|
|
@@ -19,7 +19,7 @@ import type { Node, Predicate } from './module/query/domain/filter/node.model';
|
|
|
19
19
|
import type { NumberExpr } from './module/query/domain/filter/numberExpr.model';
|
|
20
20
|
import type { Operators } from './module/query/domain/filter/operators.model';
|
|
21
21
|
import type { Scalar, Unwrap } from './module/query/domain/filter/scalar.model';
|
|
22
|
-
import type { EmbeddedObjectKeys, EmbeddedOf, ExprFor, LambdaNamespace, OwnKeys, PrimitiveArrayKeys, PrimitiveLambdaNamespace, Relation, ScalarFieldKeys, Scope, ToManyKeys, ToOneKeys } from './module/query/domain/filter/scope.model';
|
|
22
|
+
import type { ColumnExpr, EmbeddedObjectKeys, EmbeddedOf, ExprFor, InlineToOneKeys, LambdaNamespace, OwnKeys, PrimitiveArrayKeys, PrimitiveLambdaNamespace, Relation, ScalarFieldKeys, Scope, SelectColumn, SelectScope, ToManyKeys, ToOneKeys } from './module/query/domain/filter/scope.model';
|
|
23
23
|
import type { StringExpr } from './module/query/domain/filter/stringExpr.model';
|
|
24
24
|
import { InvalidFilterError } from './module/query/exception/invalidFilter.exception';
|
|
25
25
|
import { QueryBuilderException } from './module/query/exception/queryBuilder.exception';
|
|
@@ -27,4 +27,4 @@ import { ReservedNameError } from './module/query/exception/reservedName.excepti
|
|
|
27
27
|
import { and, maxdatetime, mindatetime, not, now, or, raw } from './module/query/service/filter/filter.facade';
|
|
28
28
|
import { odataItem, odataQuery } from './module/query/service/queryChain.service';
|
|
29
29
|
export { InvalidFilterError, QueryBuilderException, QueryBuilderExceptionCode, ReservedNameError, and, maxdatetime, mindatetime, not, now, odataItem, odataQuery, or, raw, };
|
|
30
|
-
export type { BooleanExpr, CastResult, Castable, Chain, Comparable, DateExpr, DateInput, EdmTarget, EmbeddedObjectKeys, EmbeddedOf, ExceptionDetail, ExpandChain, ExpandKey, ExpandNamespace, ExprFor, ItemChain, LambdaNamespace, Node, NumberExpr, Operators, OwnKeys, Predicate, PrimitiveArrayKeys, PrimitiveLambdaNamespace, QueryParams, Relation, Scalar, ScalarFieldKeys, Scope, StringExpr, ToManyKeys, ToOneExpandChain, ToOneKeys, Unwrap, };
|
|
30
|
+
export type { BooleanExpr, CastResult, Castable, Chain, ColumnExpr, Comparable, DateExpr, DateInput, EdmTarget, EmbeddedExpandNamespace, EmbeddedObjectKeys, EmbeddedOf, ExceptionDetail, ExpandChain, ExpandKey, ExpandNamespace, ExprFor, InlineToOneKeys, ItemChain, LambdaNamespace, Node, NumberExpr, Operators, OwnKeys, Predicate, PrimitiveArrayKeys, PrimitiveLambdaNamespace, QueryParams, Relation, Scalar, ScalarFieldKeys, Scope, SelectColumn, SelectScope, StringExpr, ToManyKeys, ToOneExpandChain, ToOneKeys, Unwrap, };
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAcH,mFAAsF;AAwDrF,0GAxDQ,+CAAyB,OAwDR;AApB1B,8FAAsF;AAkBrF,mGAlBQ,4CAAkB,OAkBR;AAjBnB,4FAAwF;AAkBvF,sGAlBQ,8CAAqB,OAkBR;AAjBtB,4FAAoF;AAmBnF,kGAnBQ,0CAAiB,OAmBR;AAlBlB,+EAQqD;AAWpD,oFAlBA,mBAAG,OAkBA;AACH,4FAlBA,2BAAW,OAkBA;AACX,4FAlBA,2BAAW,OAkBA;AACX,oFAlBA,mBAAG,OAkBA;AACH,oFAlBA,mBAAG,OAkBA;AAGH,mFApBA,kBAAE,OAoBA;AACF,oFApBA,mBAAG,OAoBA;AAlBJ,kFAGmD;AAYlD,0FAdA,8BAAS,OAcA;AACT,2FAdA,+BAAU,OAcA"}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import type { Predicate } from '../filter/node.model';
|
|
15
15
|
import type { Operators } from '../filter/operators.model';
|
|
16
|
-
import type { ColumnExpr, Relation, ScalarFieldKeys, Scope, SelectScope, ToManyKeys, ToOneKeys } from '../filter/scope.model';
|
|
16
|
+
import type { ColumnExpr, EmbeddedObjectKeys, InlineToOneKeys, PrimitiveArrayKeys, Relation, ScalarFieldKeys, Scope, SelectColumn, SelectScope, ToManyKeys, ToOneKeys } from '../filter/scope.model';
|
|
17
17
|
import type { StringExpr } from '../filter/stringExpr.model';
|
|
18
18
|
import type { ExpandChain, ToOneExpandChain } from './expandChain.model';
|
|
19
19
|
/** A flat `{ $option: value }` map, for a caller that serialises its own URL. */
|
|
@@ -22,17 +22,36 @@ export type QueryParams = Record<string, string>;
|
|
|
22
22
|
export type ExpandKey<T> = ToOneKeys<T> | ToManyKeys<T>;
|
|
23
23
|
/**
|
|
24
24
|
* `Self` is the chain the call returns, so `expand.a(...).expand.b(...)`
|
|
25
|
-
* chains at whatever level it is written.
|
|
25
|
+
* chains at whatever level it is written. An embedded object reads as an
|
|
26
|
+
* `EmbeddedExpandNamespace`, so `expand.address.supplier()` reaches the inline
|
|
27
|
+
* to-one inside it.
|
|
26
28
|
*/
|
|
27
29
|
export type ExpandNamespace<T, Self> = {
|
|
28
30
|
readonly [K in ExpandKey<T>]: (build?: (chain: K extends ToManyKeys<T> ? ExpandChain<Relation<T, K>> : ToOneExpandChain<Relation<T, K>>) => unknown) => Self;
|
|
31
|
+
} & {
|
|
32
|
+
readonly [K in Exclude<EmbeddedObjectKeys<T>, ExpandKey<T> | InlineToOneKeys<T>>]: EmbeddedExpandNamespace<NonNullable<T[K]>, Self>;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* The inline to-ones inside embedded object `E`, and the embedded objects
|
|
36
|
+
* nested in it. A call prints the joined path: `expand.address.supplier()`
|
|
37
|
+
* gives `$expand=address/supplier`. The call takes no callback, because the
|
|
38
|
+
* server rejects options on an expand path of more than one segment
|
|
39
|
+
* (test/e2e/rejections.spec.ts).
|
|
40
|
+
*/
|
|
41
|
+
export type EmbeddedExpandNamespace<E, Self> = {
|
|
42
|
+
readonly [K in InlineToOneKeys<E>]: () => Self;
|
|
43
|
+
} & {
|
|
44
|
+
readonly [K in Exclude<EmbeddedObjectKeys<E>, InlineToOneKeys<E>>]: EmbeddedExpandNamespace<NonNullable<E[K]>, Self>;
|
|
29
45
|
};
|
|
30
46
|
export interface Chain<T> {
|
|
31
47
|
readonly expand: ExpandNamespace<T, Chain<T>>;
|
|
32
|
-
/** Own columns, by name. */
|
|
33
|
-
select(...keys: ScalarFieldKeys<T>[]): Chain<T>;
|
|
34
|
-
/**
|
|
35
|
-
|
|
48
|
+
/** Own columns and primitive array columns, by name. */
|
|
49
|
+
select(...keys: (ScalarFieldKeys<T> | PrimitiveArrayKeys<T>)[]): Chain<T>;
|
|
50
|
+
/**
|
|
51
|
+
* Own columns, primitive array columns and embedded leaves:
|
|
52
|
+
* `select((v) => [v.id, v.tags, v.address.city])`.
|
|
53
|
+
*/
|
|
54
|
+
select(columns: (scope: SelectScope<T>) => SelectColumn | readonly SelectColumn[]): Chain<T>;
|
|
36
55
|
/** Repeated calls AND together. */
|
|
37
56
|
filter(build: (scope: Scope<T>, operators: Operators) => Predicate): Chain<T>;
|
|
38
57
|
/** `$search` + its mandatory `$searchColumns`, as one verb. */
|
|
@@ -18,14 +18,17 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import type { Predicate } from '../filter/node.model';
|
|
20
20
|
import type { Operators } from '../filter/operators.model';
|
|
21
|
-
import type {
|
|
21
|
+
import type { PrimitiveArrayKeys, ScalarFieldKeys, Scope, SelectColumn, SelectScope } from '../filter/scope.model';
|
|
22
22
|
import type { ExpandNamespace } from './chain.model';
|
|
23
23
|
export interface ExpandChain<T> {
|
|
24
24
|
readonly expand: ExpandNamespace<T, ExpandChain<T>>;
|
|
25
|
-
/** Own columns, by name. */
|
|
26
|
-
select(...keys: ScalarFieldKeys<T>[]): ExpandChain<T>;
|
|
27
|
-
/**
|
|
28
|
-
|
|
25
|
+
/** Own columns and primitive array columns, by name. */
|
|
26
|
+
select(...keys: (ScalarFieldKeys<T> | PrimitiveArrayKeys<T>)[]): ExpandChain<T>;
|
|
27
|
+
/**
|
|
28
|
+
* Own columns, primitive array columns and embedded leaves:
|
|
29
|
+
* `select((v) => [v.id, v.tags, v.address.city])`.
|
|
30
|
+
*/
|
|
31
|
+
select(columns: (scope: SelectScope<T>) => SelectColumn | readonly SelectColumn[]): ExpandChain<T>;
|
|
29
32
|
/**
|
|
30
33
|
* `$expand=rel($filter=…)`. The scope is the EXPANDED entity, so paths are
|
|
31
34
|
* written relative to it, not to the root. Repeated calls AND together.
|
|
@@ -38,10 +41,13 @@ export interface ExpandChain<T> {
|
|
|
38
41
|
}
|
|
39
42
|
export interface ToOneExpandChain<T> {
|
|
40
43
|
readonly expand: ExpandNamespace<T, ToOneExpandChain<T>>;
|
|
41
|
-
/** Own columns, by name. */
|
|
42
|
-
select(...keys: ScalarFieldKeys<T>[]): ToOneExpandChain<T>;
|
|
43
|
-
/**
|
|
44
|
-
|
|
44
|
+
/** Own columns and primitive array columns, by name. */
|
|
45
|
+
select(...keys: (ScalarFieldKeys<T> | PrimitiveArrayKeys<T>)[]): ToOneExpandChain<T>;
|
|
46
|
+
/**
|
|
47
|
+
* Own columns, primitive array columns and embedded leaves:
|
|
48
|
+
* `select((v) => [v.id, v.tags, v.address.city])`.
|
|
49
|
+
*/
|
|
50
|
+
select(columns: (scope: SelectScope<T>) => SelectColumn | readonly SelectColumn[]): ToOneExpandChain<T>;
|
|
45
51
|
/**
|
|
46
52
|
* `$expand=rel($filter=…)`. The scope is the EXPANDED entity, so paths are
|
|
47
53
|
* written relative to it, not to the root. Repeated calls AND together.
|
|
@@ -5,14 +5,17 @@
|
|
|
5
5
|
* `$count` and `$search` have nothing to act on. Only the shaping options are
|
|
6
6
|
* offered.
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
8
|
+
import type { PrimitiveArrayKeys, ScalarFieldKeys, SelectColumn, SelectScope } from '../filter/scope.model';
|
|
9
9
|
import type { ExpandNamespace, QueryParams } from './chain.model';
|
|
10
10
|
export interface ItemChain<T> {
|
|
11
11
|
readonly expand: ExpandNamespace<T, ItemChain<T>>;
|
|
12
|
-
/** Own columns, by name. */
|
|
13
|
-
select(...keys: ScalarFieldKeys<T>[]): ItemChain<T>;
|
|
14
|
-
/**
|
|
15
|
-
|
|
12
|
+
/** Own columns and primitive array columns, by name. */
|
|
13
|
+
select(...keys: (ScalarFieldKeys<T> | PrimitiveArrayKeys<T>)[]): ItemChain<T>;
|
|
14
|
+
/**
|
|
15
|
+
* Own columns, primitive array columns and embedded leaves:
|
|
16
|
+
* `select((v) => [v.id, v.tags, v.address.city])`.
|
|
17
|
+
*/
|
|
18
|
+
select(columns: (scope: SelectScope<T>) => SelectColumn | readonly SelectColumn[]): ItemChain<T>;
|
|
16
19
|
toQueryString(): string;
|
|
17
20
|
/**
|
|
18
21
|
* The same query as separate parts, with the transport escaping undone, for
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The machine-readable payload behind an error message. One entry of
|
|
3
|
-
* `QueryBuilderException.errors` is one of these
|
|
4
|
-
* the
|
|
3
|
+
* `QueryBuilderException.errors` is one of these. For InvalidFilterError,
|
|
4
|
+
* errors[0].reason is the message; ReservedNameError has a longer message and
|
|
5
|
+
* a fixed reason.
|
|
5
6
|
*
|
|
6
7
|
* Plain serializable data: an adapter can put the array straight into an HTTP
|
|
7
8
|
* response body.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* The machine-readable payload behind an error message. One entry of
|
|
4
|
-
* `QueryBuilderException.errors` is one of these
|
|
5
|
-
* the
|
|
4
|
+
* `QueryBuilderException.errors` is one of these. For InvalidFilterError,
|
|
5
|
+
* errors[0].reason is the message; ReservedNameError has a longer message and
|
|
6
|
+
* a fixed reason.
|
|
6
7
|
*
|
|
7
8
|
* Plain serializable data: an adapter can put the array straight into an HTTP
|
|
8
9
|
* response body.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exceptionDetail.model.js","sourceRoot":"","sources":["../../../../src/module/query/domain/exceptionDetail.model.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"exceptionDetail.model.js","sourceRoot":"","sources":["../../../../src/module/query/domain/exceptionDetail.model.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A temporal expression. A DTO types a timestamp column as an ISO `string`, so
|
|
3
3
|
* this type is reached through the explicit `.asDate()` opt-in rather than
|
|
4
|
-
* inferred — which keeps the
|
|
4
|
+
* inferred — which keeps the component functions off every text column.
|
|
5
5
|
*/
|
|
6
6
|
import type { Castable } from './castable.model';
|
|
7
7
|
import type { Comparable } from './comparable.model';
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The two shapes every filter fragment is one of.
|
|
3
3
|
*
|
|
4
|
-
* Nothing in this file has a runtime body
|
|
5
|
-
*
|
|
4
|
+
* Nothing in this file has a runtime body. PredicateNode in
|
|
5
|
+
* util/filter/predicate.util.ts implements Predicate, and ExpressionNode in
|
|
6
|
+
* service/filter/scope.service.ts carries the text of every other Node.
|
|
6
7
|
* A construct the server rejects is not typed here at all, so a 400 becomes a
|
|
7
8
|
* red squiggle.
|
|
8
9
|
*/
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* The two shapes every filter fragment is one of.
|
|
4
4
|
*
|
|
5
|
-
* Nothing in this file has a runtime body
|
|
6
|
-
*
|
|
5
|
+
* Nothing in this file has a runtime body. PredicateNode in
|
|
6
|
+
* util/filter/predicate.util.ts implements Predicate, and ExpressionNode in
|
|
7
|
+
* service/filter/scope.service.ts carries the text of every other Node.
|
|
7
8
|
* A construct the server rejects is not typed here at all, so a 400 becomes a
|
|
8
9
|
* red squiggle.
|
|
9
10
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.model.js","sourceRoot":"","sources":["../../../../../src/module/query/domain/filter/node.model.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"node.model.js","sourceRoot":"","sources":["../../../../../src/module/query/domain/filter/node.model.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG"}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* The eleven helper types below are mutually recursive (`Scope<T>` mentions
|
|
6
|
-
* `Scope<Relation>`), so they stay in one file rather than being split one per
|
|
7
|
-
* type: the split would only add import cycles between declaration files.
|
|
2
|
+
* The scopes that a filter, search, orderBy or select callback reads.
|
|
3
|
+
* `Scope<T>` and `LambdaNamespace<R>` refer to each other; the key types sit
|
|
4
|
+
* next to them because both scopes are built from them.
|
|
8
5
|
*
|
|
9
6
|
* The key sets are subtracted with `Exclude` rather than `Omit`. `Omit` makes
|
|
10
7
|
* TypeScript compute `keyof` of a type that mentions `Scope<T>` again, which it
|
|
@@ -63,6 +60,15 @@ export type PrimitiveArrayKeys<T> = Extract<{
|
|
|
63
60
|
export type EmbeddedObjectKeys<T> = Extract<{
|
|
64
61
|
[K in keyof T]-?: K extends '_embedded' ? never : NonNullable<T[K]> extends Scalar ? never : NonNullable<T[K]> extends readonly unknown[] ? never : NonNullable<T[K]> extends object ? K : never;
|
|
65
62
|
}[keyof T], string>;
|
|
63
|
+
/**
|
|
64
|
+
* Every embedded object property whose type is a row-backed DTO, which the
|
|
65
|
+
* type shows by its `_embedded` key: an inline to-one (`address.supplier`).
|
|
66
|
+
* A filter reads it like an embedded object; its columns reach the response
|
|
67
|
+
* through `$expand`, never through `$select`.
|
|
68
|
+
*/
|
|
69
|
+
export type InlineToOneKeys<T> = {
|
|
70
|
+
[K in EmbeddedObjectKeys<T>]-?: '_embedded' extends keyof NonNullable<T[K]> ? K : never;
|
|
71
|
+
}[EmbeddedObjectKeys<T>];
|
|
66
72
|
/** Every `_embedded` relation of a DTO that holds a single row. */
|
|
67
73
|
export type ToOneKeys<T> = Extract<{
|
|
68
74
|
[K in keyof EmbeddedOf<T>]-?: NonNullable<EmbeddedOf<T>[K]> extends readonly unknown[] ? never : K;
|
|
@@ -99,12 +105,20 @@ export type Scope<T> = {
|
|
|
99
105
|
*/
|
|
100
106
|
export type ColumnExpr = StringExpr<string> | NumberExpr<number | bigint> | DateExpr | BooleanExpr;
|
|
101
107
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
|
|
108
|
+
* One column, as a `select` callback returns it: a `ColumnExpr`, or a
|
|
109
|
+
* primitive array column, which `$select` takes but `$orderby` does not.
|
|
110
|
+
*/
|
|
111
|
+
export type SelectColumn = ColumnExpr | PrimitiveLambdaNamespace<Scalar>;
|
|
112
|
+
/**
|
|
113
|
+
* What a `select` callback reads: own columns, primitive array columns and
|
|
114
|
+
* embedded objects, never a relation. A relation column comes through
|
|
115
|
+
* `$expand`, so neither `owner/email` nor the inline to-one
|
|
116
|
+
* `address/supplier/name` is a `$select` path.
|
|
105
117
|
*/
|
|
106
118
|
export type SelectScope<T> = {
|
|
107
119
|
readonly [K in ScalarFieldKeys<T>]: ExprFor<T[K]>;
|
|
108
120
|
} & {
|
|
109
|
-
readonly [K in
|
|
121
|
+
readonly [K in PrimitiveArrayKeys<T>]: PrimitiveLambdaNamespace<Unwrap<NonNullable<T[K]>>>;
|
|
122
|
+
} & {
|
|
123
|
+
readonly [K in Exclude<EmbeddedObjectKeys<T>, InlineToOneKeys<T>>]: SelectScope<NonNullable<T[K]>>;
|
|
110
124
|
};
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* the predicates and the search parts it carries.
|
|
5
5
|
*
|
|
6
6
|
* One shape serves every level. The type layer is what decides which verbs a
|
|
7
|
-
* level offers
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* level offers. The emitter does not check the level: toQueryParts() prints
|
|
8
|
+
* every root field, and nestedParts() prints only $filter, $select, $expand,
|
|
9
|
+
* $top and $skip of an expanded level.
|
|
10
10
|
*
|
|
11
11
|
* It sits at the root of `domain/` because it is the contract of
|
|
12
12
|
* `src/module/query/`, not the product of one stage.
|
|
@@ -7,6 +7,10 @@ exports.InvalidFilterError = void 0;
|
|
|
7
7
|
* Every case the type layer can reject is rejected at compile time instead;
|
|
8
8
|
* this covers what only the runtime can see — an empty `in()` list, a NaN
|
|
9
9
|
* literal, a callback that returns a column instead of a predicate.
|
|
10
|
+
*
|
|
11
|
+
* Despite the name, this is the error of every runtime check that is not a
|
|
12
|
+
* reserved name: top() and skip() values and search(), orderBy() and select()
|
|
13
|
+
* columns included.
|
|
10
14
|
*/
|
|
11
15
|
const exceptionCode_model_1 = require("../domain/exceptionCode.model");
|
|
12
16
|
const queryBuilder_exception_1 = require("./queryBuilder.exception");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invalidFilter.exception.js","sourceRoot":"","sources":["../../../../src/module/query/exception/invalidFilter.exception.ts"],"names":[],"mappings":";;;AAAA
|
|
1
|
+
{"version":3,"file":"invalidFilter.exception.js","sourceRoot":"","sources":["../../../../src/module/query/exception/invalidFilter.exception.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;GAUG;AACH,uEAA0E;AAC1E,qEAAiE;AAEjE,MAAa,kBAAmB,SAAQ,8CAAqB;IAC5D,YAAY,MAAc,EAAE,OAAgB;QAC3C,KAAK,CAAC,+CAAyB,CAAC,cAAc,EAAE,MAAM,EAAE;YACvD,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE;SACxD,CAAC,CAAC;IACJ,CAAC;CACD;AAND,gDAMC"}
|
|
@@ -22,7 +22,10 @@ export declare abstract class QueryBuilderException extends Error {
|
|
|
22
22
|
readonly statusCode: number;
|
|
23
23
|
/** Stable machine-readable code, e.g. "RESERVED_NAME". */
|
|
24
24
|
readonly code: QueryBuilderExceptionCode;
|
|
25
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* Every detail behind this error. For InvalidFilterError, errors[0].reason
|
|
27
|
+
* is the message; ReservedNameError has a longer message and a fixed reason.
|
|
28
|
+
*/
|
|
26
29
|
readonly errors: ExceptionDetail[];
|
|
27
30
|
protected constructor(code: QueryBuilderExceptionCode, message: string, errors: ExceptionDetail[]);
|
|
28
31
|
}
|
|
@@ -23,7 +23,10 @@ class QueryBuilderException extends Error {
|
|
|
23
23
|
statusCode;
|
|
24
24
|
/** Stable machine-readable code, e.g. "RESERVED_NAME". */
|
|
25
25
|
code;
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Every detail behind this error. For InvalidFilterError, errors[0].reason
|
|
28
|
+
* is the message; ReservedNameError has a longer message and a fixed reason.
|
|
29
|
+
*/
|
|
27
30
|
errors;
|
|
28
31
|
constructor(code, message, errors) {
|
|
29
32
|
super(message);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryBuilder.exception.js","sourceRoot":"","sources":["../../../../src/module/query/exception/queryBuilder.exception.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAKH,MAAsB,qBAAsB,SAAQ,KAAK;IACxD,sDAAsD;IAC7C,MAAM,CAAS;IACxB,8DAA8D;IACrD,UAAU,CAAS;IAC5B,0DAA0D;IACjD,IAAI,CAA4B;IACzC
|
|
1
|
+
{"version":3,"file":"queryBuilder.exception.js","sourceRoot":"","sources":["../../../../src/module/query/exception/queryBuilder.exception.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAKH,MAAsB,qBAAsB,SAAQ,KAAK;IACxD,sDAAsD;IAC7C,MAAM,CAAS;IACxB,8DAA8D;IACrD,UAAU,CAAS;IAC5B,0DAA0D;IACjD,IAAI,CAA4B;IACzC;;;OAGG;IACM,MAAM,CAAoB;IAEnC,YACC,IAA+B,EAC/B,OAAe,EACf,MAAyB;QAEzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAClB,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;CACD;AAzBD,sDAyBC"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { QueryBuilderException } from './queryBuilder.exception';
|
|
2
|
+
/** The property names a builder `Proxy` refuses with a `ReservedNameError`. */
|
|
3
|
+
export declare const RESERVED_NAMES: ReadonlySet<string>;
|
|
2
4
|
export declare class ReservedNameError extends QueryBuilderException {
|
|
3
5
|
readonly reservedName: string;
|
|
4
6
|
constructor(reservedName: string);
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ReservedNameError = void 0;
|
|
3
|
+
exports.ReservedNameError = exports.RESERVED_NAMES = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* A name the builder cannot hand out, because JavaScript itself would call it.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* A filter scope member (ScopeService.createMember() in scope.service.ts) and
|
|
8
|
+
* chain.expand throw for every name in RESERVED_NAMES. JavaScript reads these
|
|
9
|
+
* names in await, JSON.stringify and string or number coercion.
|
|
10
10
|
*/
|
|
11
11
|
const exceptionCode_model_1 = require("../domain/exceptionCode.model");
|
|
12
12
|
const queryBuilder_exception_1 = require("./queryBuilder.exception");
|
|
13
|
+
/** The property names a builder `Proxy` refuses with a `ReservedNameError`. */
|
|
14
|
+
exports.RESERVED_NAMES = new Set([
|
|
15
|
+
'then',
|
|
16
|
+
'toJSON',
|
|
17
|
+
'toString',
|
|
18
|
+
'valueOf',
|
|
19
|
+
]);
|
|
13
20
|
class ReservedNameError extends queryBuilder_exception_1.QueryBuilderException {
|
|
14
21
|
reservedName;
|
|
15
22
|
constructor(reservedName) {
|
|
16
|
-
super(exceptionCode_model_1.QueryBuilderExceptionCode.RESERVED_NAME, `"${reservedName}" is reserved on
|
|
23
|
+
super(exceptionCode_model_1.QueryBuilderExceptionCode.RESERVED_NAME, `"${reservedName}" is reserved on the query builder. The builder is not a ` +
|
|
17
24
|
`promise and is not serialisable; call .toQueryString() instead.`, [
|
|
18
25
|
{
|
|
19
26
|
reason: 'the name is reserved on a builder scope',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reservedName.exception.js","sourceRoot":"","sources":["../../../../src/module/query/exception/reservedName.exception.ts"],"names":[],"mappings":";;;AAAA;;;;;;GAMG;AACH,uEAA0E;AAC1E,qEAAiE;AAEjE,MAAa,iBAAkB,SAAQ,8CAAqB;IACtC;IAArB,YAAqB,YAAoB;QACxC,KAAK,CACJ,+CAAyB,CAAC,aAAa,EACvC,IAAI,YAAY,
|
|
1
|
+
{"version":3,"file":"reservedName.exception.js","sourceRoot":"","sources":["../../../../src/module/query/exception/reservedName.exception.ts"],"names":[],"mappings":";;;AAAA;;;;;;GAMG;AACH,uEAA0E;AAC1E,qEAAiE;AAEjE,+EAA+E;AAClE,QAAA,cAAc,GAAwB,IAAI,GAAG,CAAC;IAC1D,MAAM;IACN,QAAQ;IACR,UAAU;IACV,SAAS;CACT,CAAC,CAAC;AAEH,MAAa,iBAAkB,SAAQ,8CAAqB;IACtC;IAArB,YAAqB,YAAoB;QACxC,KAAK,CACJ,+CAAyB,CAAC,aAAa,EACvC,IAAI,YAAY,2DAA2D;YAC1E,iEAAiE,EAClE;YACC;gBACC,MAAM,EAAE,yCAAyC;gBACjD,OAAO,EAAE,YAAY;aACrB;SACD,CACD,CAAC;QAXkB,iBAAY,GAAZ,YAAY,CAAQ;IAYzC,CAAC;CACD;AAdD,8CAcC"}
|
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
* golden-string test can be written against a hand-built state.
|
|
6
6
|
*
|
|
7
7
|
* `toQueryString()` and `toParams()` read the same ordered parts from
|
|
8
|
-
* `toQueryParts()`, so the
|
|
9
|
-
*
|
|
10
|
-
* one leaves in place.
|
|
8
|
+
* `toQueryParts()`, so for text the builder escapes, the string form and the
|
|
9
|
+
* map form say the same query. They differ only in the transport escaping
|
|
10
|
+
* each one leaves in place. raw() text goes into both forms as written, so a
|
|
11
|
+
* + or a percent escape in it means one thing in toQueryString() and another
|
|
12
|
+
* in toParams().
|
|
11
13
|
*/
|
|
12
14
|
import type { QueryState } from '../../domain/queryState.model';
|
|
13
15
|
export declare class EmitService {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.service.js","sourceRoot":"","sources":["../../../../../src/module/query/service/emit/emit.service.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"emit.service.js","sourceRoot":"","sources":["../../../../../src/module/query/service/emit/emit.service.ts"],"names":[],"mappings":";;;AAcA,+DAAmE;AACnE,qEAA2D;AAE3D,MAAa,WAAW;IACM;IAA7B,YAA6B,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAG,CAAC;IAEvD,aAAa;QACZ,OAAO,IAAI,CAAC,YAAY,EAAE;aACxB,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;aACxC,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACP,MAAM,WAAW,GAA2B,EAAE,CAAC;QAC/C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YAChD,WAAW,CAAC,GAAG,CAAC,GAAG,IAAA,gCAAkB,EAAC,KAAK,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,WAAW,CAAC;IACpB,CAAC;IAED;;;;OAIG;IACK,YAAY;QACnB,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;QAC5B,MAAM,KAAK,GAAuB,EAAE,CAAC;QACrC,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM;YAC5B,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACtD,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YAChD,KAAK,CAAC,IAAI,CAAC,CAAC,gBAAgB,EAAE,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACrE,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM;YAC3B,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtD,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM;YAC3B,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACtD,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM;YAC5B,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACxD,IAAI,UAAU,CAAC,GAAG,KAAK,SAAS;YAC/B,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS;YAChC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChD,IAAI,UAAU,CAAC,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;;OAGG;IACK,WAAW,CAAC,UAAsB;QACzC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM;YAC5B,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACtD,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM;YAC3B,KAAK,CAAC,IAAI,CAAC,WAAW,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtD,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM;YAC3B,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACtD,IAAI,UAAU,CAAC,GAAG,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC;QACvE,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1E,OAAO,KAAK,CAAC;IACd,CAAC;IAED,4EAA4E;IACpE,UAAU,CAAC,UAAsB;QACxC,OAAO,UAAU,CAAC,MAAM;aACtB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACd,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACjD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QACxE,CAAC,CAAC;aACD,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;IAED,+CAA+C;IACvC,UAAU,CAAC,UAAsB;QACxC,OAAO,IAAA,wBAAO,EAAC,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;IAChD,CAAC;CACD;AAjFD,kCAiFC"}
|
|
@@ -13,17 +13,19 @@ class FilterService {
|
|
|
13
13
|
return (0, predicate_util_1.combine)('or', predicates);
|
|
14
14
|
}
|
|
15
15
|
static not(predicate) {
|
|
16
|
+
if (!(predicate instanceof predicate_util_1.PredicateNode))
|
|
17
|
+
throw new invalidFilter_exception_1.InvalidFilterError('not() takes predicates, not a bare column', 'not');
|
|
16
18
|
// `not (…)` carries its own grouping, so it never needs wrapping again.
|
|
17
19
|
return new predicate_util_1.PredicateNode(`not (${predicate.text})`);
|
|
18
20
|
}
|
|
19
21
|
static now() {
|
|
20
|
-
return scope_service_1.ScopeService.createMember(new scope_service_1.ExpressionNode('now()'
|
|
22
|
+
return scope_service_1.ScopeService.createMember(new scope_service_1.ExpressionNode('now()'));
|
|
21
23
|
}
|
|
22
24
|
static maxdatetime() {
|
|
23
|
-
return scope_service_1.ScopeService.createMember(new scope_service_1.ExpressionNode('maxdatetime()'
|
|
25
|
+
return scope_service_1.ScopeService.createMember(new scope_service_1.ExpressionNode('maxdatetime()'));
|
|
24
26
|
}
|
|
25
27
|
static mindatetime() {
|
|
26
|
-
return scope_service_1.ScopeService.createMember(new scope_service_1.ExpressionNode('mindatetime()'
|
|
28
|
+
return scope_service_1.ScopeService.createMember(new scope_service_1.ExpressionNode('mindatetime()'));
|
|
27
29
|
}
|
|
28
30
|
static raw(odataExpression) {
|
|
29
31
|
return new predicate_util_1.PredicateNode(odataExpression, true);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.service.js","sourceRoot":"","sources":["../../../../../src/module/query/service/filter/filter.service.ts"],"names":[],"mappings":";;;AAgBA,qFAA6E;AAC7E,+DAAgE;AAChE,qEAA0E;AAC1E,mDAA+D;AAI/D,MAAa,aAAa;IACzB,MAAM,CAAC,GAAG,CAAC,GAAG,UAAuB;QACpC,OAAO,IAAA,wBAAO,EAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACnC,CAAC;IAED,MAAM,CAAC,EAAE,CAAC,GAAG,UAAuB;QACnC,OAAO,IAAA,wBAAO,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,SAAoB;QAC9B,wEAAwE;QACxE,OAAO,IAAI,8BAAa,CAAC,QAAQ,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,CAAC,GAAG;QACT,OAAO,4BAAY,CAAC,YAAY,CAAC,IAAI,8BAAc,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"filter.service.js","sourceRoot":"","sources":["../../../../../src/module/query/service/filter/filter.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
export declare class ExpressionNode {
|
|
2
2
|
readonly text: string;
|
|
3
|
-
/** lambda nesting level, for deterministic alias letters */
|
|
4
|
-
readonly depth: number;
|
|
5
3
|
/** true for `a add 1`: needs parentheses as an operand of `mul`. */
|
|
6
4
|
readonly arithmetic: boolean;
|
|
7
5
|
constructor(text: string,
|
|
8
|
-
/** lambda nesting level, for deterministic alias letters */
|
|
9
|
-
depth: number,
|
|
10
6
|
/** true for `a add 1`: needs parentheses as an operand of `mul`. */
|
|
11
7
|
arithmetic?: boolean);
|
|
12
8
|
}
|
|
@@ -14,9 +10,8 @@ export declare class ScopeService {
|
|
|
14
10
|
/** The only key that reads a node. A DTO key can never be a symbol. */
|
|
15
11
|
private static readonly NODE;
|
|
16
12
|
/**
|
|
17
|
-
* The filter scope of an entity: an empty path
|
|
18
|
-
*
|
|
19
|
-
* root.
|
|
13
|
+
* The filter scope of an entity: an empty path. An expanded entity is
|
|
14
|
+
* filtered relative to itself, so it takes the same empty root.
|
|
20
15
|
*/
|
|
21
16
|
static rootScope(): any;
|
|
22
17
|
/**
|
|
@@ -54,6 +49,12 @@ export declare class ScopeService {
|
|
|
54
49
|
private static binaryFunction;
|
|
55
50
|
private static arithmetic;
|
|
56
51
|
private static stringMatch;
|
|
52
|
+
/**
|
|
53
|
+
* The number of lambda bodies running at this moment. A lambda takes its
|
|
54
|
+
* alias from it, so a lambda inside another lambda body gets the next
|
|
55
|
+
* letter, also when it opens on a root path.
|
|
56
|
+
*/
|
|
57
|
+
private static openLambdas;
|
|
57
58
|
/**
|
|
58
59
|
* A distinct alias letter per lambda nesting level, so an inner lambda never
|
|
59
60
|
* shadows the outer one and `b/x ne a/y` stays expressible.
|
|
@@ -7,15 +7,11 @@ const escape_util_1 = require("../../util/filter/escape.util");
|
|
|
7
7
|
const predicate_util_1 = require("../../util/filter/predicate.util");
|
|
8
8
|
class ExpressionNode {
|
|
9
9
|
text;
|
|
10
|
-
depth;
|
|
11
10
|
arithmetic;
|
|
12
11
|
constructor(text,
|
|
13
|
-
/** lambda nesting level, for deterministic alias letters */
|
|
14
|
-
depth,
|
|
15
12
|
/** true for `a add 1`: needs parentheses as an operand of `mul`. */
|
|
16
13
|
arithmetic = false) {
|
|
17
14
|
this.text = text;
|
|
18
|
-
this.depth = depth;
|
|
19
15
|
this.arithmetic = arithmetic;
|
|
20
16
|
}
|
|
21
17
|
}
|
|
@@ -24,12 +20,11 @@ class ScopeService {
|
|
|
24
20
|
/** The only key that reads a node. A DTO key can never be a symbol. */
|
|
25
21
|
static NODE = Symbol('odata.node');
|
|
26
22
|
/**
|
|
27
|
-
* The filter scope of an entity: an empty path
|
|
28
|
-
*
|
|
29
|
-
* root.
|
|
23
|
+
* The filter scope of an entity: an empty path. An expanded entity is
|
|
24
|
+
* filtered relative to itself, so it takes the same empty root.
|
|
30
25
|
*/
|
|
31
26
|
static rootScope() {
|
|
32
|
-
return ScopeService.createMember(new ExpressionNode(''
|
|
27
|
+
return ScopeService.createMember(new ExpressionNode(''));
|
|
33
28
|
}
|
|
34
29
|
/**
|
|
35
30
|
* `createMember(node)` is a value; `createMember(node, parent, name)` is a
|
|
@@ -60,22 +55,18 @@ class ScopeService {
|
|
|
60
55
|
// reach `apply` as a call to a function named `toString`/`valueOf`
|
|
61
56
|
// that the OData function table does not know, a confusing error
|
|
62
57
|
// to land on.
|
|
63
|
-
if (property
|
|
64
|
-
property === 'toJSON' ||
|
|
65
|
-
property === 'toString' ||
|
|
66
|
-
property === 'valueOf')
|
|
58
|
+
if (reservedName_exception_1.RESERVED_NAMES.has(property))
|
|
67
59
|
throw new reservedName_exception_1.ReservedNameError(property);
|
|
68
|
-
return ScopeService.createMember(new ExpressionNode(node.text ? `${node.text}/${property}` : property
|
|
60
|
+
return ScopeService.createMember(new ExpressionNode(node.text ? `${node.text}/${property}` : property), node, property);
|
|
69
61
|
},
|
|
70
62
|
apply(_target, _thisArgument, callArguments) {
|
|
71
63
|
if (parent === undefined || name === undefined)
|
|
72
|
-
throw new invalidFilter_exception_1.InvalidFilterError(`"${node.text}" is a
|
|
64
|
+
throw new invalidFilter_exception_1.InvalidFilterError(`"${node.text}" is a value, not a function`, node.text);
|
|
73
65
|
const method = ScopeService.filterFunction(name);
|
|
74
66
|
if (method === undefined)
|
|
75
67
|
throw new invalidFilter_exception_1.InvalidFilterError(`${name}() is not an OData filter function served by this API`, name);
|
|
76
68
|
return method(parent, callArguments);
|
|
77
69
|
},
|
|
78
|
-
has: (_target, property) => typeof property === 'string',
|
|
79
70
|
});
|
|
80
71
|
}
|
|
81
72
|
/** The node behind a scope proxy, or `undefined` for a plain value. */
|
|
@@ -122,7 +113,18 @@ class ScopeService {
|
|
|
122
113
|
if (typeof value === 'number') {
|
|
123
114
|
if (!Number.isFinite(value))
|
|
124
115
|
throw new invalidFilter_exception_1.InvalidFilterError(`${value} is not an OData number literal`, String(value));
|
|
125
|
-
|
|
116
|
+
const text = String(value);
|
|
117
|
+
if (!text.includes('e'))
|
|
118
|
+
return text;
|
|
119
|
+
// The grammar has no exponent form, so 1e-7 and 1e21 print in full.
|
|
120
|
+
// Below 1e-100 the full form rounds to 0, a different value.
|
|
121
|
+
const fullText = value.toLocaleString('en-US', {
|
|
122
|
+
useGrouping: false,
|
|
123
|
+
maximumFractionDigits: 100,
|
|
124
|
+
});
|
|
125
|
+
if (Number(fullText) !== value)
|
|
126
|
+
throw new invalidFilter_exception_1.InvalidFilterError(`${value} is not an OData number literal`, text);
|
|
127
|
+
return fullText;
|
|
126
128
|
}
|
|
127
129
|
if (value instanceof Date) {
|
|
128
130
|
if (Number.isNaN(value.getTime()))
|
|
@@ -142,18 +144,24 @@ class ScopeService {
|
|
|
142
144
|
}
|
|
143
145
|
/** A one-argument SQL function: `name(self)`. */
|
|
144
146
|
static unaryFunction(name) {
|
|
145
|
-
return (self) => ScopeService.createMember(new ExpressionNode(`${name}(${self.text})
|
|
147
|
+
return (self) => ScopeService.createMember(new ExpressionNode(`${name}(${self.text})`));
|
|
146
148
|
}
|
|
147
149
|
/** A two-argument SQL function: `name(self,argument)`. */
|
|
148
150
|
static binaryFunction(name) {
|
|
149
|
-
return (self, callArguments) => ScopeService.createMember(new ExpressionNode(`${name}(${self.text},${ScopeService.literal(callArguments[0])})
|
|
151
|
+
return (self, callArguments) => ScopeService.createMember(new ExpressionNode(`${name}(${self.text},${ScopeService.literal(callArguments[0])})`));
|
|
150
152
|
}
|
|
151
153
|
static arithmetic(operator) {
|
|
152
|
-
return (self, callArguments) => ScopeService.createMember(new ExpressionNode(`${ScopeService.parenthesiseArithmetic(self)} ${operator} ${ScopeService.literal(callArguments[0])}`,
|
|
154
|
+
return (self, callArguments) => ScopeService.createMember(new ExpressionNode(`${ScopeService.parenthesiseArithmetic(self)} ${operator} ${ScopeService.literal(callArguments[0])}`, true));
|
|
153
155
|
}
|
|
154
156
|
static stringMatch(name) {
|
|
155
157
|
return (self, callArguments) => new predicate_util_1.PredicateNode(`${name}(${self.text},${ScopeService.literal(callArguments[0])})`);
|
|
156
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* The number of lambda bodies running at this moment. A lambda takes its
|
|
161
|
+
* alias from it, so a lambda inside another lambda body gets the next
|
|
162
|
+
* letter, also when it opens on a root path.
|
|
163
|
+
*/
|
|
164
|
+
static openLambdas = 0;
|
|
157
165
|
/**
|
|
158
166
|
* A distinct alias letter per lambda nesting level, so an inner lambda never
|
|
159
167
|
* shadows the outer one and `b/x ne a/y` stays expressible.
|
|
@@ -171,8 +179,15 @@ class ScopeService {
|
|
|
171
179
|
throw new invalidFilter_exception_1.InvalidFilterError('all() requires a predicate; the server rejects a bare all()', 'all');
|
|
172
180
|
return new predicate_util_1.PredicateNode(`${self.text}/any()`);
|
|
173
181
|
}
|
|
174
|
-
const alias = ScopeService.lambdaAlias(
|
|
175
|
-
|
|
182
|
+
const alias = ScopeService.lambdaAlias(ScopeService.openLambdas);
|
|
183
|
+
ScopeService.openLambdas += 1;
|
|
184
|
+
let inner;
|
|
185
|
+
try {
|
|
186
|
+
inner = build(ScopeService.createMember(new ExpressionNode(alias)));
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
ScopeService.openLambdas -= 1;
|
|
190
|
+
}
|
|
176
191
|
if (!(inner instanceof predicate_util_1.PredicateNode))
|
|
177
192
|
throw new invalidFilter_exception_1.InvalidFilterError(`${kind}() must return a predicate, not a bare column`, kind);
|
|
178
193
|
// The colon carries no space: the grammar requires `any(a:…)`.
|
|
@@ -195,7 +210,7 @@ class ScopeService {
|
|
|
195
210
|
if (ScopeService.nodeOf(member))
|
|
196
211
|
throw new invalidFilter_exception_1.InvalidFilterError('in() takes literal values only; the server rejects a column or an expression inside in (...)', 'in');
|
|
197
212
|
}
|
|
198
|
-
return new predicate_util_1.PredicateNode(`${self
|
|
213
|
+
return new predicate_util_1.PredicateNode(`${ScopeService.parenthesiseArithmetic(self)} in (${values
|
|
199
214
|
.map((value) => ScopeService.literal(value, true))
|
|
200
215
|
.join(',')})`);
|
|
201
216
|
},
|
|
@@ -211,7 +226,7 @@ class ScopeService {
|
|
|
211
226
|
concat: ScopeService.binaryFunction('concat'),
|
|
212
227
|
substring: (self, callArguments) => ScopeService.createMember(new ExpressionNode(callArguments[1] === undefined
|
|
213
228
|
? `substring(${self.text},${ScopeService.literal(callArguments[0])})`
|
|
214
|
-
: `substring(${self.text},${ScopeService.literal(callArguments[0])},${ScopeService.literal(callArguments[1])})
|
|
229
|
+
: `substring(${self.text},${ScopeService.literal(callArguments[0])},${ScopeService.literal(callArguments[1])})`)),
|
|
215
230
|
indexOf: ScopeService.binaryFunction('indexof'),
|
|
216
231
|
contains: ScopeService.stringMatch('contains'),
|
|
217
232
|
startsWith: ScopeService.stringMatch('startswith'),
|
|
@@ -240,7 +255,7 @@ class ScopeService {
|
|
|
240
255
|
floor: ScopeService.unaryFunction('floor'),
|
|
241
256
|
round: ScopeService.unaryFunction('round'),
|
|
242
257
|
/* type */
|
|
243
|
-
cast: (self, callArguments) => ScopeService.createMember(new ExpressionNode(`cast(${self.text},${callArguments[0]})
|
|
258
|
+
cast: (self, callArguments) => ScopeService.createMember(new ExpressionNode(`cast(${self.text},${callArguments[0]})`)),
|
|
244
259
|
/* lambdas */
|
|
245
260
|
any: ScopeService.lambda('any'),
|
|
246
261
|
all: ScopeService.lambda('all'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope.service.js","sourceRoot":"","sources":["../../../../../src/module/query/service/filter/scope.service.ts"],"names":[],"mappings":";;;AA0CA,qFAA6E;AAC7E,
|
|
1
|
+
{"version":3,"file":"scope.service.js","sourceRoot":"","sources":["../../../../../src/module/query/service/filter/scope.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,18 +27,27 @@ import type { QueryState } from '../domain/queryState.model';
|
|
|
27
27
|
export declare class QueryChainService {
|
|
28
28
|
readonly queryState: QueryState;
|
|
29
29
|
/**
|
|
30
|
-
* Returns a `Proxy` whose every string property is a
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* `
|
|
30
|
+
* Returns a `Proxy` whose every string property is a member that remembers
|
|
31
|
+
* its path. A call on a member adds the relation at that path; a read from
|
|
32
|
+
* it gives the member one segment further. The relation names exist only in
|
|
33
|
+
* the type system, so there is nothing to enumerate and no allowlist to
|
|
34
|
+
* check. Every name in `RESERVED_NAMES` (`then`, `toJSON`, `toString`,
|
|
35
|
+
* `valueOf`) throws `ReservedNameError`, so the object never passes for a promise, a JSON
|
|
36
|
+
* value or a primitive, and a coercion adds no relation.
|
|
36
37
|
*
|
|
37
38
|
* `chain.expand.parent((parent) => parent.select('name'))` gives
|
|
38
|
-
* `$expand=parent($select=name)
|
|
39
|
-
*
|
|
39
|
+
* `$expand=parent($select=name)`, and `chain.expand.address.supplier()`
|
|
40
|
+
* gives `$expand=address/supplier`. See docs/maintainer/architecture.md,
|
|
41
|
+
* How `Proxy` works here.
|
|
40
42
|
*/
|
|
41
43
|
get expand(): unknown;
|
|
44
|
+
/**
|
|
45
|
+
* The `Proxy` behind `expand` and behind each member read from it. The root
|
|
46
|
+
* target is a plain object, so `chain.expand` itself is not callable; every
|
|
47
|
+
* other target is the call that adds the relation at `path`. The traps are
|
|
48
|
+
* arrow functions, so `this` is the `QueryChainService` and not the handler.
|
|
49
|
+
*/
|
|
50
|
+
private expandPath;
|
|
42
51
|
select(...keys: string[] | [(scope: unknown) => unknown]): this;
|
|
43
52
|
filter(build: (scope: unknown, operators: Operators) => Predicate): this;
|
|
44
53
|
search(term: string, columns: (scope: unknown) => Node | readonly Node[]): this;
|
|
@@ -13,37 +13,48 @@ class QueryChainService {
|
|
|
13
13
|
filters: [],
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
16
|
-
* Returns a `Proxy` whose every string property is a
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* `
|
|
16
|
+
* Returns a `Proxy` whose every string property is a member that remembers
|
|
17
|
+
* its path. A call on a member adds the relation at that path; a read from
|
|
18
|
+
* it gives the member one segment further. The relation names exist only in
|
|
19
|
+
* the type system, so there is nothing to enumerate and no allowlist to
|
|
20
|
+
* check. Every name in `RESERVED_NAMES` (`then`, `toJSON`, `toString`,
|
|
21
|
+
* `valueOf`) throws `ReservedNameError`, so the object never passes for a promise, a JSON
|
|
22
|
+
* value or a primitive, and a coercion adds no relation.
|
|
22
23
|
*
|
|
23
24
|
* `chain.expand.parent((parent) => parent.select('name'))` gives
|
|
24
|
-
* `$expand=parent($select=name)
|
|
25
|
-
*
|
|
25
|
+
* `$expand=parent($select=name)`, and `chain.expand.address.supplier()`
|
|
26
|
+
* gives `$expand=address/supplier`. See docs/maintainer/architecture.md,
|
|
27
|
+
* How `Proxy` works here.
|
|
26
28
|
*/
|
|
27
29
|
get expand() {
|
|
28
|
-
return
|
|
30
|
+
return this.expandPath(Object.create(null), '');
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The `Proxy` behind `expand` and behind each member read from it. The root
|
|
34
|
+
* target is a plain object, so `chain.expand` itself is not callable; every
|
|
35
|
+
* other target is the call that adds the relation at `path`. The traps are
|
|
36
|
+
* arrow functions, so `this` is the `QueryChainService` and not the handler.
|
|
37
|
+
*/
|
|
38
|
+
expandPath(target, path) {
|
|
39
|
+
return new Proxy(target, {
|
|
29
40
|
get: (_target, property) => {
|
|
30
41
|
if (typeof property !== 'string')
|
|
31
42
|
return undefined;
|
|
32
|
-
if (property
|
|
43
|
+
if (reservedName_exception_1.RESERVED_NAMES.has(property))
|
|
33
44
|
throw new reservedName_exception_1.ReservedNameError(property);
|
|
34
45
|
if (property === 'constructor')
|
|
35
46
|
return undefined;
|
|
36
|
-
|
|
47
|
+
const name = path ? `${path}/${property}` : property;
|
|
48
|
+
return this.expandPath((build) => {
|
|
37
49
|
const child = new QueryChainService();
|
|
38
50
|
build?.(child);
|
|
39
51
|
this.queryState.expand.push({
|
|
40
|
-
name
|
|
52
|
+
name,
|
|
41
53
|
queryState: child.queryState,
|
|
42
54
|
});
|
|
43
55
|
return this;
|
|
44
|
-
};
|
|
56
|
+
}, name);
|
|
45
57
|
},
|
|
46
|
-
has: (_target, property) => typeof property === 'string',
|
|
47
58
|
});
|
|
48
59
|
}
|
|
49
60
|
select(...keys) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryChain.service.js","sourceRoot":"","sources":["../../../../src/module/query/service/queryChain.service.ts"],"names":[],"mappings":";;;AA0BA,kFAA0E;AAC1E,
|
|
1
|
+
{"version":3,"file":"queryChain.service.js","sourceRoot":"","sources":["../../../../src/module/query/service/queryChain.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,6 +27,8 @@ const operand = (predicate) => predicate instanceof PredicateNode && predicate.c
|
|
|
27
27
|
const combine = (operator, parts) => {
|
|
28
28
|
if (parts.length === 0)
|
|
29
29
|
throw new invalidFilter_exception_1.InvalidFilterError(`${operator}() needs at least one predicate`, operator);
|
|
30
|
+
if (parts.some((part) => !(part instanceof PredicateNode)))
|
|
31
|
+
throw new invalidFilter_exception_1.InvalidFilterError(`${operator}() takes predicates, not a bare column`, operator);
|
|
30
32
|
if (parts.length === 1)
|
|
31
33
|
return parts[0];
|
|
32
34
|
return new PredicateNode(parts.map(operand).join(` ${operator} `), true);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"predicate.util.js","sourceRoot":"","sources":["../../../../../src/module/query/util/filter/predicate.util.ts"],"names":[],"mappings":";;;AASA,qFAA6E;AAE7E,MAAa,aAAa;IAGf;IAEA;IAJD,WAAW,GAAG,IAAa,CAAC;IACrC,YACU,IAAY;IACrB,sEAAsE;IAC7D,YAAqB,KAAK;QAF1B,SAAI,GAAJ,IAAI,CAAQ;QAEZ,cAAS,GAAT,SAAS,CAAiB;IACjC,CAAC;IACJ,GAAG,CAAC,GAAG,MAAmB;QACzB,OAAO,IAAA,eAAO,EAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,EAAE,CAAC,GAAG,MAAmB;QACxB,OAAO,IAAA,eAAO,EAAC,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;IACzC,CAAC;CACD;AAbD,sCAaC;AAED,wEAAwE;AACxE,MAAM,OAAO,GAAG,CAAC,SAAoB,EAAU,EAAE,CAChD,SAAS,YAAY,aAAa,IAAI,SAAS,CAAC,SAAS;IACxD,CAAC,CAAC,IAAI,SAAS,CAAC,IAAI,GAAG;IACvB,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC;AAEZ,MAAM,OAAO,GAAG,CACtB,QAAsB,EACtB,KAAkB,EACN,EAAE;IACd,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QACrB,MAAM,IAAI,4CAAkB,CAC3B,GAAG,QAAQ,iCAAiC,EAC5C,QAAQ,CACR,CAAC;IACH,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,IAAI,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;AAC1E,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"predicate.util.js","sourceRoot":"","sources":["../../../../../src/module/query/util/filter/predicate.util.ts"],"names":[],"mappings":";;;AASA,qFAA6E;AAE7E,MAAa,aAAa;IAGf;IAEA;IAJD,WAAW,GAAG,IAAa,CAAC;IACrC,YACU,IAAY;IACrB,sEAAsE;IAC7D,YAAqB,KAAK;QAF1B,SAAI,GAAJ,IAAI,CAAQ;QAEZ,cAAS,GAAT,SAAS,CAAiB;IACjC,CAAC;IACJ,GAAG,CAAC,GAAG,MAAmB;QACzB,OAAO,IAAA,eAAO,EAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,EAAE,CAAC,GAAG,MAAmB;QACxB,OAAO,IAAA,eAAO,EAAC,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;IACzC,CAAC;CACD;AAbD,sCAaC;AAED,wEAAwE;AACxE,MAAM,OAAO,GAAG,CAAC,SAAoB,EAAU,EAAE,CAChD,SAAS,YAAY,aAAa,IAAI,SAAS,CAAC,SAAS;IACxD,CAAC,CAAC,IAAI,SAAS,CAAC,IAAI,GAAG;IACvB,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC;AAEZ,MAAM,OAAO,GAAG,CACtB,QAAsB,EACtB,KAAkB,EACN,EAAE;IACd,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QACrB,MAAM,IAAI,4CAAkB,CAC3B,GAAG,QAAQ,iCAAiC,EAC5C,QAAQ,CACR,CAAC;IACH,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,YAAY,aAAa,CAAC,CAAC;QACzD,MAAM,IAAI,4CAAkB,CAC3B,GAAG,QAAQ,wCAAwC,EACnD,QAAQ,CACR,CAAC;IACH,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,IAAI,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;AAC1E,CAAC,CAAC;AAhBW,QAAA,OAAO,WAgBlB"}
|
package/package.json
CHANGED