@fibery/query-utils 1.1.0 → 1.1.2
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/lib/src/query.d.ts +5 -6
- package/lib/src/query.js +11 -9
- package/lib/src/select.d.ts +13 -85
- package/lib/src/select.js +47 -35
- package/package.json +5 -5
- package/lib/src/types.d.ts +0 -34
- package/lib/src/types.js +0 -2
package/lib/src/query.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { Expression, OrderBy } from "@fibery/expression-utils/src/types";
|
|
1
|
+
import { Expression, FieldExpression, FiberyObject, OrderBy } from "@fibery/expression-utils/src/types";
|
|
2
2
|
import { FieldObject, TypeObject } from "@fibery/schema";
|
|
3
3
|
import { $TSFixMe } from "./tsfixme";
|
|
4
|
-
import { FiberyObject } from "./types";
|
|
5
4
|
export declare const extractReferenceField: (expression: Expression) => string;
|
|
6
5
|
export declare const getRangeValue: (object: FiberyObject, expression: Expression) => any;
|
|
7
6
|
export declare const extractSingleFieldFromExpression: (expression: Expression) => string;
|
|
@@ -10,7 +9,7 @@ export declare function extractFieldObjectFromExpression({ expression, typeObjec
|
|
|
10
9
|
typeObject: TypeObject;
|
|
11
10
|
}): FieldObject | null;
|
|
12
11
|
export declare const warnAboutNonProcessedKeys: (location: string, rest: Record<string, unknown>) => void;
|
|
13
|
-
export declare const getValueByFieldExpression: (object: $TSFixMe, path:
|
|
12
|
+
export declare const getValueByFieldExpression: (object: $TSFixMe, path: FieldExpression) => any;
|
|
14
13
|
export declare const parseMultiFieldValue: ({ multiFieldValue, multiFieldObject, }: {
|
|
15
14
|
multiFieldValue?: Record<string, unknown> | null;
|
|
16
15
|
multiFieldObject: FieldObject;
|
|
@@ -27,17 +26,17 @@ export declare const calculateOrderByForRequest: ({ orderByFromMeta, typeObject,
|
|
|
27
26
|
}) => OrderBy | undefined;
|
|
28
27
|
export declare const calculateOrderByRankOrName: ({ typeObject }: {
|
|
29
28
|
typeObject: TypeObject;
|
|
30
|
-
}) => OrderBy | (string |
|
|
29
|
+
}) => OrderBy | (string | "__NOTHING_INTERESTING__TitleField__"[])[][] | undefined;
|
|
31
30
|
export declare const calculateSortObjectsFn: ({ typeObject }: {
|
|
32
31
|
typeObject: TypeObject;
|
|
33
32
|
}) => {
|
|
34
33
|
<T>(value: T): T;
|
|
35
34
|
(): undefined;
|
|
36
35
|
} | ((objects: $TSFixMe) => any[]);
|
|
37
|
-
export declare const extractSingleField: (expression:
|
|
36
|
+
export declare const extractSingleField: (expression: FieldExpression) => string;
|
|
38
37
|
export declare const getQuerySelectForExpression: ({ typeObject, expression, selectsByTypeLookup, }: {
|
|
39
38
|
typeObject: TypeObject;
|
|
40
|
-
expression:
|
|
39
|
+
expression: FieldExpression;
|
|
41
40
|
selectsByTypeLookup?: Record<string, $TSFixMe>;
|
|
42
41
|
}) => any;
|
|
43
42
|
export declare const getOrderBySelect: (orderBy: OrderBy | undefined | null, typeObject: TypeObject) => any;
|
package/lib/src/query.js
CHANGED
|
@@ -8,7 +8,10 @@ exports.extractFieldObjectFromExpression = extractFieldObjectFromExpression;
|
|
|
8
8
|
const utils_1 = require("@fibery/expression-utils/src/utils");
|
|
9
9
|
const trace_1 = require("@fibery/helpers/utils/trace");
|
|
10
10
|
const array_1 = require("@fibery/helpers/utils/array");
|
|
11
|
-
const
|
|
11
|
+
const identity_1 = __importDefault(require("lodash/identity"));
|
|
12
|
+
const isEqual_1 = __importDefault(require("lodash/isEqual"));
|
|
13
|
+
const last_1 = __importDefault(require("lodash/last"));
|
|
14
|
+
const sortBy_1 = __importDefault(require("lodash/sortBy"));
|
|
12
15
|
const memoize_one_1 = __importDefault(require("memoize-one"));
|
|
13
16
|
const errors_1 = require("./errors");
|
|
14
17
|
const select_1 = require("./select");
|
|
@@ -67,7 +70,6 @@ const warnAboutNonProcessedKeys = (location, rest) => {
|
|
|
67
70
|
};
|
|
68
71
|
exports.warnAboutNonProcessedKeys = warnAboutNonProcessedKeys;
|
|
69
72
|
const getValueByFieldExpression = (object, path) => {
|
|
70
|
-
// TODO: review types. According to Expression it might be nested array but looks like we ignore it everywhere
|
|
71
73
|
return path.reduce((memo, key) => {
|
|
72
74
|
if (memo === undefined) {
|
|
73
75
|
return undefined;
|
|
@@ -113,7 +115,7 @@ const calculateOrderByForRequest = ({ orderByFromMeta, typeObject, }) => {
|
|
|
113
115
|
else {
|
|
114
116
|
// When installing an app, we create a view with meta with explicit sorting by rank.
|
|
115
117
|
// Let's not add defaultOrderBy in this case, it will be just a duplicate.
|
|
116
|
-
if (defaultOrderBy && !
|
|
118
|
+
if (defaultOrderBy && !(0, isEqual_1.default)(orderByFromMeta, defaultOrderBy)) {
|
|
117
119
|
return orderByFromMeta.concat(defaultOrderBy);
|
|
118
120
|
}
|
|
119
121
|
else {
|
|
@@ -135,14 +137,14 @@ const calculateOrderByRankOrName = ({ typeObject }) => {
|
|
|
135
137
|
};
|
|
136
138
|
exports.calculateOrderByRankOrName = calculateOrderByRankOrName;
|
|
137
139
|
const makeSortByRankFn = (0, memoize_one_1.default)((rankField) => {
|
|
138
|
-
return (objects) =>
|
|
140
|
+
return (objects) => (0, sortBy_1.default)(objects, (object) => object[rankField]);
|
|
139
141
|
});
|
|
140
142
|
const calculateSortObjectsFn = ({ typeObject }) => {
|
|
141
|
-
return typeObject.rankFieldObject === null ?
|
|
143
|
+
return typeObject.rankFieldObject === null ? identity_1.default : makeSortByRankFn(typeObject.rankField);
|
|
142
144
|
};
|
|
143
145
|
exports.calculateSortObjectsFn = calculateSortObjectsFn;
|
|
144
146
|
const extractSingleField = (expression) => {
|
|
145
|
-
(0, trace_1.assert)(
|
|
147
|
+
(0, trace_1.assert)((0, last_1.default)(expression) === "fibery/id", "not supported:", { expression });
|
|
146
148
|
return (0, array_1.single)(expression.slice(0, -1));
|
|
147
149
|
};
|
|
148
150
|
exports.extractSingleField = extractSingleField;
|
|
@@ -178,15 +180,15 @@ const getOrderBySelect = (orderBy, typeObject) => {
|
|
|
178
180
|
if (!orderBy) {
|
|
179
181
|
return {};
|
|
180
182
|
}
|
|
181
|
-
(0, trace_1.assert)(orderBy.every(
|
|
183
|
+
(0, trace_1.assert)(orderBy.every(Array.isArray), `Order By should be an array of ordering expressions`);
|
|
182
184
|
const selects = orderBy
|
|
183
185
|
.map((ordering) => {
|
|
184
186
|
const orderingExpression = ordering[0];
|
|
185
187
|
return (0, exports.getQuerySelectForExpression)({
|
|
186
188
|
typeObject,
|
|
187
|
-
expression: (0, utils_1.isDateRangeFunctionExpression)(orderingExpression)
|
|
189
|
+
expression: ((0, utils_1.isDateRangeFunctionExpression)(orderingExpression)
|
|
188
190
|
? orderingExpression[1]
|
|
189
|
-
: orderingExpression,
|
|
191
|
+
: orderingExpression),
|
|
190
192
|
});
|
|
191
193
|
})
|
|
192
194
|
// always include rank, as it is used for card creation, see `calculateNewCardRank`.
|
package/lib/src/select.d.ts
CHANGED
|
@@ -1,107 +1,35 @@
|
|
|
1
|
-
import { Expression } from "@fibery/expression-utils/src/types";
|
|
2
|
-
import _ from "lodash";
|
|
1
|
+
import { Expression, FiberyObject, Query, Select } from "@fibery/expression-utils/src/types";
|
|
3
2
|
import { Schema } from "@fibery/schema";
|
|
4
|
-
import { FiberyObject, Query, Select } from "./types";
|
|
5
3
|
import { $TSFixMe } from "./tsfixme";
|
|
6
4
|
export declare const isDynamicSelectLhs: (field: string) => boolean;
|
|
7
5
|
export declare const isDynamicSelectRhs: (rhs: Expression) => boolean;
|
|
8
6
|
export declare const isSelectForMultiFieldKey = "_isSelectForMultiField_";
|
|
9
7
|
export declare function normalizeSelectInPath(path: Expression, value: $TSFixMe): $TSFixMe;
|
|
10
|
-
export declare const normalizeSelect: (denormalizedSelect:
|
|
8
|
+
export declare const normalizeSelect: (denormalizedSelect: Select) => Select;
|
|
11
9
|
export declare function denormalizeSelectInPath(path: Expression, value: $TSFixMe): $TSFixMe;
|
|
12
10
|
export declare const denormalizeSelect: (normalizedSelect: $TSFixMe) => any;
|
|
13
11
|
export declare function mergeDenormalizedSelects(denormalizedSelects: $TSFixMe[]): any;
|
|
12
|
+
export type PickedHole = {
|
|
13
|
+
path: Array<string | number>;
|
|
14
|
+
normalizedSelect: Select;
|
|
15
|
+
};
|
|
16
|
+
export type PickedFieldsResult = {
|
|
17
|
+
object: Record<string, unknown>;
|
|
18
|
+
holes: PickedHole[];
|
|
19
|
+
};
|
|
14
20
|
export declare const annotateNormalizedSelect: (normalizedSelect: Select) => ({
|
|
15
21
|
lhs: {
|
|
16
22
|
value: string;
|
|
17
23
|
isDynamicSelect: boolean;
|
|
18
24
|
};
|
|
19
25
|
rhs: {
|
|
20
|
-
value:
|
|
26
|
+
value: Expression | Record<string, Expression>;
|
|
21
27
|
isDynamicSelect: boolean;
|
|
22
28
|
isQueryExpression: boolean;
|
|
23
29
|
isPlainObject: boolean;
|
|
24
30
|
};
|
|
25
31
|
} | null)[];
|
|
26
|
-
export declare const pickSelectedFields: (objects: FiberyObject[], normalizedSelect: Select) =>
|
|
27
|
-
|
|
28
|
-
holes: unknown[];
|
|
29
|
-
}[];
|
|
30
|
-
export declare const toSelectMapClause: (simpleFields: string[]) => _.Dictionary<string | number | ((separator?: string) => string) | (() => ArrayIterator<string>) | {
|
|
31
|
-
[x: number]: boolean | undefined;
|
|
32
|
-
length?: boolean | undefined;
|
|
33
|
-
toString?: boolean | undefined;
|
|
34
|
-
toLocaleString?: boolean | undefined;
|
|
35
|
-
pop?: boolean | undefined;
|
|
36
|
-
push?: boolean | undefined;
|
|
37
|
-
concat?: boolean | undefined;
|
|
38
|
-
join?: boolean | undefined;
|
|
39
|
-
reverse?: boolean | undefined;
|
|
40
|
-
shift?: boolean | undefined;
|
|
41
|
-
slice?: boolean | undefined;
|
|
42
|
-
sort?: boolean | undefined;
|
|
43
|
-
splice?: boolean | undefined;
|
|
44
|
-
unshift?: boolean | undefined;
|
|
45
|
-
indexOf?: boolean | undefined;
|
|
46
|
-
lastIndexOf?: boolean | undefined;
|
|
47
|
-
every?: boolean | undefined;
|
|
48
|
-
some?: boolean | undefined;
|
|
49
|
-
forEach?: boolean | undefined;
|
|
50
|
-
map?: boolean | undefined;
|
|
51
|
-
filter?: boolean | undefined;
|
|
52
|
-
reduce?: boolean | undefined;
|
|
53
|
-
reduceRight?: boolean | undefined;
|
|
54
|
-
find?: boolean | undefined;
|
|
55
|
-
findIndex?: boolean | undefined;
|
|
56
|
-
fill?: boolean | undefined;
|
|
57
|
-
copyWithin?: boolean | undefined;
|
|
58
|
-
entries?: boolean | undefined;
|
|
59
|
-
keys?: boolean | undefined;
|
|
60
|
-
values?: boolean | undefined;
|
|
61
|
-
includes?: boolean | undefined;
|
|
62
|
-
flatMap?: boolean | undefined;
|
|
63
|
-
flat?: boolean | undefined;
|
|
64
|
-
at?: boolean | undefined;
|
|
65
|
-
findLast?: boolean | undefined;
|
|
66
|
-
findLastIndex?: boolean | undefined;
|
|
67
|
-
toReversed?: boolean | undefined;
|
|
68
|
-
toSorted?: boolean | undefined;
|
|
69
|
-
toSpliced?: boolean | undefined;
|
|
70
|
-
with?: boolean | undefined;
|
|
71
|
-
[Symbol.iterator]?: boolean | undefined;
|
|
72
|
-
readonly [Symbol.unscopables]?: boolean | undefined;
|
|
73
|
-
} | (() => string) | {
|
|
74
|
-
(): string;
|
|
75
|
-
(locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string;
|
|
76
|
-
} | (() => string | undefined) | ((...items: string[]) => number) | {
|
|
77
|
-
(...items: ConcatArray<string>[]): string[];
|
|
78
|
-
(...items: (string | ConcatArray<string>)[]): string[];
|
|
79
|
-
} | (() => string[]) | (() => string | undefined) | ((start?: number, end?: number) => string[]) | ((compareFn?: ((a: string, b: string) => number) | undefined) => string[]) | {
|
|
80
|
-
(start: number, deleteCount?: number): string[];
|
|
81
|
-
(start: number, deleteCount: number, ...items: string[]): string[];
|
|
82
|
-
} | ((...items: string[]) => number) | ((searchElement: string, fromIndex?: number) => number) | ((searchElement: string, fromIndex?: number) => number) | {
|
|
83
|
-
<S extends string>(predicate: (value: string, index: number, array: string[]) => value is S, thisArg?: any): this is S[];
|
|
84
|
-
(predicate: (value: string, index: number, array: string[]) => unknown, thisArg?: any): boolean;
|
|
85
|
-
} | ((predicate: (value: string, index: number, array: string[]) => unknown, thisArg?: any) => boolean) | ((callbackfn: (value: string, index: number, array: string[]) => void, thisArg?: any) => void) | (<U>(callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[]) | {
|
|
86
|
-
<S extends string>(predicate: (value: string, index: number, array: string[]) => value is S, thisArg?: any): S[];
|
|
87
|
-
(predicate: (value: string, index: number, array: string[]) => unknown, thisArg?: any): string[];
|
|
88
|
-
} | {
|
|
89
|
-
(callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string;
|
|
90
|
-
(callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string;
|
|
91
|
-
<U>(callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U;
|
|
92
|
-
} | {
|
|
93
|
-
(callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string;
|
|
94
|
-
(callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string;
|
|
95
|
-
<U>(callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U;
|
|
96
|
-
} | {
|
|
97
|
-
<S extends string>(predicate: (value: string, index: number, obj: string[]) => value is S, thisArg?: any): S | undefined;
|
|
98
|
-
(predicate: (value: string, index: number, obj: string[]) => unknown, thisArg?: any): string | undefined;
|
|
99
|
-
} | ((predicate: (value: string, index: number, obj: string[]) => unknown, thisArg?: any) => number) | ((value: string, start?: number, end?: number) => string[]) | ((target: number, start: number, end?: number) => string[]) | (() => ArrayIterator<[number, string]>) | (() => ArrayIterator<number>) | (() => ArrayIterator<string>) | ((searchElement: string, fromIndex?: number) => boolean) | (<U, This = undefined>(callback: (this: This, value: string, index: number, array: string[]) => U | readonly U[], thisArg?: This | undefined) => U[]) | (<A, D extends number = 1>(this: A, depth?: D | undefined) => FlatArray<A, D>[]) | ((index: number) => string | undefined) | {
|
|
100
|
-
<S extends string>(predicate: (value: string, index: number, array: string[]) => value is S, thisArg?: any): S | undefined;
|
|
101
|
-
(predicate: (value: string, index: number, array: string[]) => unknown, thisArg?: any): string | undefined;
|
|
102
|
-
} | ((predicate: (value: string, index: number, array: string[]) => unknown, thisArg?: any) => number) | (() => string[]) | ((compareFn?: ((a: string, b: string) => number) | undefined) => string[]) | {
|
|
103
|
-
(start: number, deleteCount: number, ...items: string[]): string[];
|
|
104
|
-
(start: number, deleteCount?: number): string[];
|
|
105
|
-
} | ((index: number, value: string) => string[])>;
|
|
32
|
+
export declare const pickSelectedFields: (objects: FiberyObject[], normalizedSelect: Select) => PickedFieldsResult[];
|
|
33
|
+
export declare function toSelectMapClause(simpleFields: string[]): Select;
|
|
106
34
|
export declare function calculateSelectedTypes(schema: Schema, query: Query): Set<string>;
|
|
107
35
|
export declare function calculateSelectedTypesFromQueries(schema: Schema, queries: Query[]): Set<string>;
|
package/lib/src/select.js
CHANGED
|
@@ -3,15 +3,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.pickSelectedFields = exports.annotateNormalizedSelect = exports.denormalizeSelect = exports.normalizeSelect = exports.isSelectForMultiFieldKey = exports.isDynamicSelectRhs = exports.isDynamicSelectLhs = void 0;
|
|
7
7
|
exports.normalizeSelectInPath = normalizeSelectInPath;
|
|
8
8
|
exports.denormalizeSelectInPath = denormalizeSelectInPath;
|
|
9
9
|
exports.mergeDenormalizedSelects = mergeDenormalizedSelects;
|
|
10
|
+
exports.toSelectMapClause = toSelectMapClause;
|
|
10
11
|
exports.calculateSelectedTypes = calculateSelectedTypes;
|
|
11
12
|
exports.calculateSelectedTypesFromQueries = calculateSelectedTypesFromQueries;
|
|
12
13
|
const utils_1 = require("@fibery/expression-utils/src/utils");
|
|
13
14
|
const trace_1 = require("@fibery/helpers/utils/trace");
|
|
14
|
-
const
|
|
15
|
+
const flatMap_1 = __importDefault(require("lodash/flatMap"));
|
|
16
|
+
const flatten_1 = __importDefault(require("lodash/flatten"));
|
|
17
|
+
const identity_1 = __importDefault(require("lodash/identity"));
|
|
18
|
+
const isEqual_1 = __importDefault(require("lodash/isEqual"));
|
|
19
|
+
const isNumber_1 = __importDefault(require("lodash/isNumber"));
|
|
20
|
+
const isPlainObject_1 = __importDefault(require("lodash/isPlainObject"));
|
|
21
|
+
const isString_1 = __importDefault(require("lodash/isString"));
|
|
22
|
+
const keyBy_1 = __importDefault(require("lodash/keyBy"));
|
|
23
|
+
const last_1 = __importDefault(require("lodash/last"));
|
|
24
|
+
const mapValues_1 = __importDefault(require("lodash/mapValues"));
|
|
25
|
+
const omit_1 = __importDefault(require("lodash/omit"));
|
|
15
26
|
const errors_1 = require("./errors");
|
|
16
27
|
const implicitSubQueryFromTag = null;
|
|
17
28
|
const isDynamicSelectLhs = (field) => field.startsWith("?");
|
|
@@ -23,12 +34,12 @@ exports.isDynamicSelectRhs = isDynamicSelectRhs;
|
|
|
23
34
|
// It is removed during de-normalization and should be ignored in various utils methods.
|
|
24
35
|
exports.isSelectForMultiFieldKey = "_isSelectForMultiField_";
|
|
25
36
|
function normalizeSelectInPath(path, value) {
|
|
26
|
-
if (!
|
|
37
|
+
if (!Array.isArray(path)) {
|
|
27
38
|
throw new Error("path must be array");
|
|
28
39
|
}
|
|
29
|
-
if (
|
|
40
|
+
if ((0, isPlainObject_1.default)(value)) {
|
|
30
41
|
if ((0, utils_1.isQueryExpression)(value)) {
|
|
31
|
-
if (
|
|
42
|
+
if ((0, isEqual_1.default)((0, flatten_1.default)(value["q/from"]), path)) {
|
|
32
43
|
return {
|
|
33
44
|
...value,
|
|
34
45
|
"q/select": (0, exports.normalizeSelect)(value["q/select"]),
|
|
@@ -43,13 +54,13 @@ function normalizeSelectInPath(path, value) {
|
|
|
43
54
|
}
|
|
44
55
|
}
|
|
45
56
|
let hasMultiFieldAccess = false;
|
|
46
|
-
const normalized =
|
|
57
|
+
const normalized = (0, mapValues_1.default)(value, (value, key) => {
|
|
47
58
|
if (key === exports.isSelectForMultiFieldKey) {
|
|
48
59
|
return value;
|
|
49
60
|
}
|
|
50
61
|
if ((0, utils_1.isMultiFieldExpression)(value)) {
|
|
51
62
|
hasMultiFieldAccess = true;
|
|
52
|
-
return normalizeSelectInPath(path.concat([key]),
|
|
63
|
+
return normalizeSelectInPath(path.concat([key]), (0, flatten_1.default)(value));
|
|
53
64
|
}
|
|
54
65
|
else {
|
|
55
66
|
return normalizeSelectInPath(path.concat([key]), value);
|
|
@@ -62,12 +73,12 @@ function normalizeSelectInPath(path, value) {
|
|
|
62
73
|
return normalized;
|
|
63
74
|
}
|
|
64
75
|
}
|
|
65
|
-
if (
|
|
66
|
-
if (path.length > 0 && (0, exports.isDynamicSelectLhs)(
|
|
76
|
+
if (Array.isArray(value)) {
|
|
77
|
+
if (path.length > 0 && (0, exports.isDynamicSelectLhs)((0, last_1.default)(path)) && (0, exports.isDynamicSelectRhs)(value)) {
|
|
67
78
|
return value;
|
|
68
79
|
}
|
|
69
|
-
if (
|
|
70
|
-
return
|
|
80
|
+
if ((0, isEqual_1.default)(value, path)) {
|
|
81
|
+
return (0, last_1.default)(value);
|
|
71
82
|
}
|
|
72
83
|
else {
|
|
73
84
|
throw new Error(`strict array select invariant: ${JSON.stringify({
|
|
@@ -76,23 +87,24 @@ function normalizeSelectInPath(path, value) {
|
|
|
76
87
|
})}`);
|
|
77
88
|
}
|
|
78
89
|
}
|
|
79
|
-
if (
|
|
90
|
+
if ((0, isString_1.default)(value)) {
|
|
80
91
|
return value;
|
|
81
92
|
}
|
|
82
93
|
throw new Error(`denormalizedSelect invariant: ${JSON.stringify({ path, value })}`);
|
|
83
94
|
}
|
|
95
|
+
// TODO introduce normalizedSelect type (it's stricter)
|
|
84
96
|
const normalizeSelect = (denormalizedSelect) => {
|
|
85
|
-
if (!
|
|
97
|
+
if (!(0, isPlainObject_1.default)(denormalizedSelect)) {
|
|
86
98
|
throw new Error("denormalizedSelect must be an object");
|
|
87
99
|
}
|
|
88
100
|
return normalizeSelectInPath([], denormalizedSelect);
|
|
89
101
|
};
|
|
90
102
|
exports.normalizeSelect = normalizeSelect;
|
|
91
103
|
function denormalizeSelectInPath(path, value) {
|
|
92
|
-
if (!
|
|
104
|
+
if (!Array.isArray(path)) {
|
|
93
105
|
throw new Error("path must be array");
|
|
94
106
|
}
|
|
95
|
-
if (
|
|
107
|
+
if ((0, isPlainObject_1.default)(value)) {
|
|
96
108
|
if ((0, utils_1.isQueryExpression)(value)) {
|
|
97
109
|
if (value["q/from"] === implicitSubQueryFromTag) {
|
|
98
110
|
return {
|
|
@@ -109,7 +121,7 @@ function denormalizeSelectInPath(path, value) {
|
|
|
109
121
|
throw new Error(`strict array select invariant: ${details}`);
|
|
110
122
|
}
|
|
111
123
|
}
|
|
112
|
-
const denormalized =
|
|
124
|
+
const denormalized = (0, mapValues_1.default)(value, (val, key) => {
|
|
113
125
|
if (key === exports.isSelectForMultiFieldKey) {
|
|
114
126
|
return key;
|
|
115
127
|
}
|
|
@@ -120,13 +132,13 @@ function denormalizeSelectInPath(path, value) {
|
|
|
120
132
|
return denormalizeSelectInPath(path.concat([key]), val);
|
|
121
133
|
}
|
|
122
134
|
});
|
|
123
|
-
return
|
|
135
|
+
return (0, omit_1.default)(denormalized, exports.isSelectForMultiFieldKey);
|
|
124
136
|
}
|
|
125
|
-
if (path.length > 0 && (0, exports.isDynamicSelectLhs)(
|
|
137
|
+
if (path.length > 0 && (0, exports.isDynamicSelectLhs)((0, last_1.default)(path)) && (0, exports.isDynamicSelectRhs)(value)) {
|
|
126
138
|
return value;
|
|
127
139
|
}
|
|
128
|
-
if (
|
|
129
|
-
if (
|
|
140
|
+
if ((0, isString_1.default)(value)) {
|
|
141
|
+
if ((0, last_1.default)(path) === value) {
|
|
130
142
|
return path;
|
|
131
143
|
}
|
|
132
144
|
else {
|
|
@@ -142,16 +154,16 @@ function mergeNormalizedSelects(normalizedSelects) {
|
|
|
142
154
|
Object.entries(normalizedSelect).forEach(([key, value]) => {
|
|
143
155
|
if (key in result) {
|
|
144
156
|
if (value !== result[key]) {
|
|
145
|
-
if (
|
|
157
|
+
if ((0, isPlainObject_1.default)(value) && (0, isPlainObject_1.default)(result[key])) {
|
|
146
158
|
result[key] = mergeNormalizedSelects([value, result[key]]);
|
|
147
159
|
}
|
|
148
160
|
else if (key === "q/limit" && (value === "q/no-limit" || result[key] === "q/no-limit")) {
|
|
149
161
|
result[key] = "q/no-limit";
|
|
150
162
|
}
|
|
151
|
-
else if (key === "q/limit" &&
|
|
163
|
+
else if (key === "q/limit" && (0, isNumber_1.default)(value) && (0, isNumber_1.default)(result[key])) {
|
|
152
164
|
result[key] = value > result[key] ? value : result[key];
|
|
153
165
|
}
|
|
154
|
-
else if (!
|
|
166
|
+
else if (!Array.isArray(value) || !(0, isEqual_1.default)(value, result[key])) {
|
|
155
167
|
throw new Error(`merge selects invariant. ${JSON.stringify(value)} ${JSON.stringify(result[key])}`);
|
|
156
168
|
}
|
|
157
169
|
}
|
|
@@ -169,17 +181,18 @@ function mergeDenormalizedSelects(denormalizedSelects) {
|
|
|
169
181
|
return (0, exports.denormalizeSelect)(normalizedSelect);
|
|
170
182
|
}
|
|
171
183
|
const addHole = function (holesByPath, path, lhs, rhs) {
|
|
172
|
-
|
|
173
|
-
|
|
184
|
+
const key = path.join("/");
|
|
185
|
+
if (!holesByPath[key]) {
|
|
186
|
+
holesByPath[key] = { path, normalizedSelect: {} };
|
|
174
187
|
}
|
|
175
|
-
holesByPath[
|
|
188
|
+
holesByPath[key].normalizedSelect[lhs] = rhs;
|
|
176
189
|
};
|
|
177
190
|
const annotateNormalizedSelect = (normalizedSelect) => Object.entries(normalizedSelect)
|
|
178
191
|
.map(([lhs, rhs]) => {
|
|
179
192
|
if (lhs === exports.isSelectForMultiFieldKey) {
|
|
180
193
|
return null;
|
|
181
194
|
}
|
|
182
|
-
const rhsIsPlainObject =
|
|
195
|
+
const rhsIsPlainObject = (0, isPlainObject_1.default)(rhs);
|
|
183
196
|
return {
|
|
184
197
|
lhs: {
|
|
185
198
|
value: lhs,
|
|
@@ -248,11 +261,10 @@ const pickSelectedFields = (objects, normalizedSelect) => {
|
|
|
248
261
|
});
|
|
249
262
|
};
|
|
250
263
|
exports.pickSelectedFields = pickSelectedFields;
|
|
251
|
-
|
|
252
|
-
(0, trace_1.assert)(
|
|
253
|
-
return
|
|
254
|
-
}
|
|
255
|
-
exports.toSelectMapClause = toSelectMapClause;
|
|
264
|
+
function toSelectMapClause(simpleFields) {
|
|
265
|
+
(0, trace_1.assert)(Array.isArray(simpleFields), "toSelectMapClause works with arrays");
|
|
266
|
+
return (0, keyBy_1.default)(simpleFields, identity_1.default);
|
|
267
|
+
}
|
|
256
268
|
function collectSelectTypes(typeObject, normalizedSelect, resultSet) {
|
|
257
269
|
for (const [field, rhs] of Object.entries(normalizedSelect)) {
|
|
258
270
|
if ((0, exports.isDynamicSelectLhs)(field) || field === exports.isSelectForMultiFieldKey) {
|
|
@@ -275,8 +287,8 @@ function collectSelectTypes(typeObject, normalizedSelect, resultSet) {
|
|
|
275
287
|
}
|
|
276
288
|
else {
|
|
277
289
|
resultSet.add(fieldTypeObject.name);
|
|
278
|
-
if (
|
|
279
|
-
if (Object.hasOwn(rhs, "q/from") &&
|
|
290
|
+
if ((0, isPlainObject_1.default)(rhs)) {
|
|
291
|
+
if (Object.hasOwn(rhs, "q/from") && (0, isPlainObject_1.default)(rhs["q/select"])) {
|
|
280
292
|
collectSelectTypes(fieldTypeObject, rhs["q/select"], resultSet);
|
|
281
293
|
}
|
|
282
294
|
else {
|
|
@@ -296,5 +308,5 @@ function calculateSelectedTypes(schema, query) {
|
|
|
296
308
|
return resultSet;
|
|
297
309
|
}
|
|
298
310
|
function calculateSelectedTypesFromQueries(schema, queries) {
|
|
299
|
-
return new Set(
|
|
311
|
+
return new Set((0, flatMap_1.default)(queries, (query) => [...calculateSelectedTypes(schema, query)]));
|
|
300
312
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fibery/query-utils",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Construct, normalize and denormalize Fibery core queries",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"memoize-one": "6.0.0",
|
|
28
28
|
"moment": "2.29.4",
|
|
29
29
|
"uuid": "11.1.0",
|
|
30
|
-
"@fibery/expression-utils": "9.6.
|
|
30
|
+
"@fibery/expression-utils": "9.6.2",
|
|
31
31
|
"@fibery/helpers": "1.4.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
"jest-junit": "16.0.0",
|
|
39
39
|
"typescript": "5.9.3",
|
|
40
40
|
"@fibery/babel-preset": "7.4.1",
|
|
41
|
-
"@fibery/eslint-config": "
|
|
42
|
-
"@fibery/schema": "10.2.
|
|
41
|
+
"@fibery/eslint-config": "9.0.0",
|
|
42
|
+
"@fibery/schema": "10.2.13"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"@fibery/schema": "10.2.
|
|
45
|
+
"@fibery/schema": "10.2.13"
|
|
46
46
|
},
|
|
47
47
|
"jest": {
|
|
48
48
|
"testEnvironment": "node",
|
package/lib/src/types.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { $TSFixMe } from "./tsfixme";
|
|
2
|
-
export type Ref = {
|
|
3
|
-
"fibery/id": string;
|
|
4
|
-
};
|
|
5
|
-
type NestedArray<T> = Array<T | NestedArray<T>>;
|
|
6
|
-
export type Expression = NestedArray<string>;
|
|
7
|
-
type SelectPart = Record<string, Expression>;
|
|
8
|
-
export type Select = SelectPart | Record<string, SelectPart>;
|
|
9
|
-
export type OrderBy = Array<[Expression, string]>;
|
|
10
|
-
export type Query = {
|
|
11
|
-
"q/from": string;
|
|
12
|
-
"q/select"?: Select;
|
|
13
|
-
"q/offset"?: number;
|
|
14
|
-
"q/order-by"?: OrderBy;
|
|
15
|
-
"q/limit"?: number | "q/no-limit";
|
|
16
|
-
"q/where"?: NestedArray<unknown>;
|
|
17
|
-
};
|
|
18
|
-
export type QueryLimit = number | "q/no-limit";
|
|
19
|
-
export type SubQuery = {
|
|
20
|
-
"q/from": Expression;
|
|
21
|
-
"q/select"?: Select;
|
|
22
|
-
"q/offset"?: number;
|
|
23
|
-
"q/order-by"?: OrderBy;
|
|
24
|
-
"q/limit"?: QueryLimit;
|
|
25
|
-
"q/where"?: NestedArray<unknown>;
|
|
26
|
-
};
|
|
27
|
-
export type Params = Record<string, Expression | null>;
|
|
28
|
-
export interface Request {
|
|
29
|
-
query: Query;
|
|
30
|
-
params: Params;
|
|
31
|
-
}
|
|
32
|
-
export type Response = Record<string, $TSFixMe>[];
|
|
33
|
-
export type FiberyObject = Record<string, unknown>;
|
|
34
|
-
export {};
|
package/lib/src/types.js
DELETED