velocious 1.0.407 → 1.0.408
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/build/src/frontend-model-controller.d.ts +18 -0
- package/build/src/frontend-model-controller.d.ts.map +1 -1
- package/build/src/frontend-model-controller.js +38 -4
- package/build/src/frontend-models/base.d.ts +29 -0
- package/build/src/frontend-models/base.d.ts.map +1 -1
- package/build/src/frontend-models/base.js +37 -1
- package/build/src/frontend-models/preloader.d.ts +66 -0
- package/build/src/frontend-models/preloader.d.ts.map +1 -0
- package/build/src/frontend-models/preloader.js +139 -0
- package/build/src/frontend-models/query.d.ts +24 -1
- package/build/src/frontend-models/query.d.ts.map +1 -1
- package/build/src/frontend-models/query.js +31 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preloads relationships onto already-loaded frontend model instances.
|
|
3
|
+
*
|
|
4
|
+
* Unlike the backend ORM preloader (which queries relationship tables
|
|
5
|
+
* directly), the frontend re-fetches the parent records through their
|
|
6
|
+
* `index` endpoint with the preload/select params, then copies the resulting
|
|
7
|
+
* top-level preloaded relationships onto the existing instances. Relationships
|
|
8
|
+
* that are already preloaded with the required columns present are skipped,
|
|
9
|
+
* so repeated calls reuse the relationship cache instead of issuing duplicate
|
|
10
|
+
* requests.
|
|
11
|
+
*/
|
|
12
|
+
export default class FrontendModelPreloader {
|
|
13
|
+
/**
|
|
14
|
+
* @param {Array<import("./base.js").default>} models - Frontend model instances to preload onto.
|
|
15
|
+
* @param {import("./query.js").default<any> | import("../database/query/index.js").NestedPreloadRecord | string | Array<string | import("../database/query/index.js").NestedPreloadRecord>} queryOrSpec - A query built via `Model.preload(...).select(...)`, or a raw preload spec.
|
|
16
|
+
* @param {{force?: boolean}} [options] - Options.
|
|
17
|
+
* @returns {Promise<void>} - Resolves when preloading completes.
|
|
18
|
+
*/
|
|
19
|
+
static preload(models: Array<import("./base.js").default>, queryOrSpec: import("./query.js").default<any> | import("../database/query/index.js").NestedPreloadRecord | string | Array<string | import("../database/query/index.js").NestedPreloadRecord>, { force }?: {
|
|
20
|
+
force?: boolean;
|
|
21
|
+
}): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* @param {object} args - Options object.
|
|
24
|
+
* @param {typeof import("./base.js").default} args.modelClass - Model class the preload graph is rooted at.
|
|
25
|
+
* @param {import("./base.js").default} args.model - Model instance.
|
|
26
|
+
* @param {import("../database/query/index.js").NestedPreloadRecord} args.preload - Preload sub-graph to satisfy.
|
|
27
|
+
* @param {import("./query.js").default<any>} args.query - Source query carrying select/selectsExtra.
|
|
28
|
+
* @param {boolean} args.force - Whether to reload regardless of cached state.
|
|
29
|
+
* @returns {boolean} - Whether the model needs a reload request.
|
|
30
|
+
*/
|
|
31
|
+
static _modelNeedsReload({ modelClass, model, preload, query, force }: {
|
|
32
|
+
modelClass: typeof import("./base.js").default;
|
|
33
|
+
model: import("./base.js").default;
|
|
34
|
+
preload: import("../database/query/index.js").NestedPreloadRecord;
|
|
35
|
+
query: import("./query.js").default<any>;
|
|
36
|
+
force: boolean;
|
|
37
|
+
}): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* A relationship is satisfied when it is already preloaded, every required
|
|
40
|
+
* `select` attribute is present on each loaded target, and any nested preload
|
|
41
|
+
* sub-graph is recursively satisfied on those targets. `selectsExtra` can
|
|
42
|
+
* never be proven satisfied from the cache (the backend serializes the
|
|
43
|
+
* client-unknown default attributes plus the extras), so it always reloads.
|
|
44
|
+
* With no select and no nested preload, being preloaded is enough.
|
|
45
|
+
* @param {object} args - Options object.
|
|
46
|
+
* @param {typeof import("./base.js").default} args.modelClass - Model class owning the relationship.
|
|
47
|
+
* @param {import("./base.js").default} args.model - Model instance.
|
|
48
|
+
* @param {string} args.relationshipName - Relationship name.
|
|
49
|
+
* @param {import("../database/query/index.js").NestedPreloadRecord[string]} args.subPreload - Preload value for this relationship (`true` or a nested record).
|
|
50
|
+
* @param {import("./query.js").default<any>} args.query - Source query carrying select/selectsExtra.
|
|
51
|
+
* @returns {boolean} - Whether the relationship is already satisfied.
|
|
52
|
+
*/
|
|
53
|
+
static _relationshipSatisfied({ modelClass, model, relationshipName, subPreload, query }: {
|
|
54
|
+
modelClass: typeof import("./base.js").default;
|
|
55
|
+
model: import("./base.js").default;
|
|
56
|
+
relationshipName: string;
|
|
57
|
+
subPreload: import("../database/query/index.js").NestedPreloadRecord[string];
|
|
58
|
+
query: import("./query.js").default<any>;
|
|
59
|
+
}): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* @param {import("../database/query/index.js").NestedPreloadRecord[string]} subPreload - Preload value for a relationship.
|
|
62
|
+
* @returns {import("../database/query/index.js").NestedPreloadRecord | null} - Nested preload record, or null when there is no deeper graph.
|
|
63
|
+
*/
|
|
64
|
+
static _nestedPreloadRecord(subPreload: import("../database/query/index.js").NestedPreloadRecord[string]): import("../database/query/index.js").NestedPreloadRecord | null;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=preloader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preloader.d.ts","sourceRoot":"","sources":["../../../src/frontend-models/preloader.js"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH;IACE;;;;;OAKG;IACH,uBALW,KAAK,CAAC,OAAO,WAAW,EAAE,OAAO,CAAC,eAClC,OAAO,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,4BAA4B,EAAE,mBAAmB,GAAG,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,OAAO,4BAA4B,EAAE,mBAAmB,CAAC,cAChL;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAC,GACf,OAAO,CAAC,IAAI,CAAC,CAuDzB;IAED;;;;;;;;OAQG;IACH,uEAPG;QAAiD,UAAU,EAAnD,cAAc,WAAW,EAAE,OAAO;QACA,KAAK,EAAvC,OAAO,WAAW,EAAE,OAAO;QACoC,OAAO,EAAtE,OAAO,4BAA4B,EAAE,mBAAmB;QAChB,KAAK,EAA7C,OAAO,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC;QACnB,KAAK,EAAnB,OAAO;KACf,GAAU,OAAO,CAUnB;IAED;;;;;;;;;;;;;;OAcG;IACH,0FAPG;QAAiD,UAAU,EAAnD,cAAc,WAAW,EAAE,OAAO;QACA,KAAK,EAAvC,OAAO,WAAW,EAAE,OAAO;QACd,gBAAgB,EAA7B,MAAM;QACiE,UAAU,EAAjF,OAAO,4BAA4B,EAAE,mBAAmB,CAAC,MAAM,CAAC;QACxB,KAAK,EAA7C,OAAO,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC;KACzC,GAAU,OAAO,CAsCnB;IAED;;;OAGG;IACH,wCAHW,OAAO,4BAA4B,EAAE,mBAAmB,CAAC,MAAM,CAAC,GAC9D,OAAO,4BAA4B,EAAE,mBAAmB,GAAG,IAAI,CAO3E;CACF"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/**
|
|
3
|
+
* Preloads relationships onto already-loaded frontend model instances.
|
|
4
|
+
*
|
|
5
|
+
* Unlike the backend ORM preloader (which queries relationship tables
|
|
6
|
+
* directly), the frontend re-fetches the parent records through their
|
|
7
|
+
* `index` endpoint with the preload/select params, then copies the resulting
|
|
8
|
+
* top-level preloaded relationships onto the existing instances. Relationships
|
|
9
|
+
* that are already preloaded with the required columns present are skipped,
|
|
10
|
+
* so repeated calls reuse the relationship cache instead of issuing duplicate
|
|
11
|
+
* requests.
|
|
12
|
+
*/
|
|
13
|
+
export default class FrontendModelPreloader {
|
|
14
|
+
/**
|
|
15
|
+
* @param {Array<import("./base.js").default>} models - Frontend model instances to preload onto.
|
|
16
|
+
* @param {import("./query.js").default<any> | import("../database/query/index.js").NestedPreloadRecord | string | Array<string | import("../database/query/index.js").NestedPreloadRecord>} queryOrSpec - A query built via `Model.preload(...).select(...)`, or a raw preload spec.
|
|
17
|
+
* @param {{force?: boolean}} [options] - Options.
|
|
18
|
+
* @returns {Promise<void>} - Resolves when preloading completes.
|
|
19
|
+
*/
|
|
20
|
+
static async preload(models, queryOrSpec, { force = false } = {}) {
|
|
21
|
+
if (!models || models.length === 0)
|
|
22
|
+
return;
|
|
23
|
+
const modelClass = /** @type {typeof import("./base.js").default} */ (models[0].constructor);
|
|
24
|
+
const isQuery = Boolean(queryOrSpec) && typeof queryOrSpec === "object" && "_preload" in queryOrSpec;
|
|
25
|
+
const query = isQuery
|
|
26
|
+
? /** @type {import("./query.js").default<any>} */ (queryOrSpec)
|
|
27
|
+
: modelClass.preload(/** @type {any} */ (queryOrSpec));
|
|
28
|
+
const topLevelRelationships = Object.keys(query._preload);
|
|
29
|
+
if (topLevelRelationships.length === 0)
|
|
30
|
+
return;
|
|
31
|
+
const modelsToLoad = models.filter((model) => this._modelNeedsReload({ modelClass, model, preload: query._preload, query, force }));
|
|
32
|
+
if (modelsToLoad.length === 0)
|
|
33
|
+
return;
|
|
34
|
+
const primaryKey = modelClass.primaryKey();
|
|
35
|
+
const ids = modelsToLoad.map((model) => model.primaryKeyValue());
|
|
36
|
+
// Rebuild a fresh query carrying only the projection-relevant state so a
|
|
37
|
+
// user-supplied limit/sort/where on the source query doesn't leak in.
|
|
38
|
+
const reloadQuery = modelClass.preload(query._preload);
|
|
39
|
+
reloadQuery._select = query._select;
|
|
40
|
+
reloadQuery._selectsExtra = query._selectsExtra;
|
|
41
|
+
reloadQuery._withCount = query._withCount;
|
|
42
|
+
reloadQuery._abilities = query._abilities;
|
|
43
|
+
reloadQuery._queryData = query._queryData;
|
|
44
|
+
reloadQuery.where({ [primaryKey]: ids });
|
|
45
|
+
const reloaded = await reloadQuery.toArray();
|
|
46
|
+
/** @type {Map<string, import("./base.js").default>} */
|
|
47
|
+
const reloadedById = new Map();
|
|
48
|
+
for (const reloadedModel of reloaded) {
|
|
49
|
+
reloadedById.set(String(reloadedModel.primaryKeyValue()), reloadedModel);
|
|
50
|
+
}
|
|
51
|
+
for (const model of modelsToLoad) {
|
|
52
|
+
const reloadedModel = reloadedById.get(String(model.primaryKeyValue()));
|
|
53
|
+
// The record may have been deleted/filtered between the original load and
|
|
54
|
+
// this preload — skip it rather than crashing on a missing reload.
|
|
55
|
+
if (!reloadedModel)
|
|
56
|
+
continue;
|
|
57
|
+
for (const relationshipName of topLevelRelationships) {
|
|
58
|
+
const value = reloadedModel.getRelationshipByName(relationshipName).loaded();
|
|
59
|
+
model.getRelationshipByName(relationshipName).setLoaded(value);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* @param {object} args - Options object.
|
|
65
|
+
* @param {typeof import("./base.js").default} args.modelClass - Model class the preload graph is rooted at.
|
|
66
|
+
* @param {import("./base.js").default} args.model - Model instance.
|
|
67
|
+
* @param {import("../database/query/index.js").NestedPreloadRecord} args.preload - Preload sub-graph to satisfy.
|
|
68
|
+
* @param {import("./query.js").default<any>} args.query - Source query carrying select/selectsExtra.
|
|
69
|
+
* @param {boolean} args.force - Whether to reload regardless of cached state.
|
|
70
|
+
* @returns {boolean} - Whether the model needs a reload request.
|
|
71
|
+
*/
|
|
72
|
+
static _modelNeedsReload({ modelClass, model, preload, query, force }) {
|
|
73
|
+
if (force)
|
|
74
|
+
return true;
|
|
75
|
+
for (const relationshipName of Object.keys(preload)) {
|
|
76
|
+
if (!this._relationshipSatisfied({ modelClass, model, relationshipName, subPreload: preload[relationshipName], query }))
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* A relationship is satisfied when it is already preloaded, every required
|
|
83
|
+
* `select` attribute is present on each loaded target, and any nested preload
|
|
84
|
+
* sub-graph is recursively satisfied on those targets. `selectsExtra` can
|
|
85
|
+
* never be proven satisfied from the cache (the backend serializes the
|
|
86
|
+
* client-unknown default attributes plus the extras), so it always reloads.
|
|
87
|
+
* With no select and no nested preload, being preloaded is enough.
|
|
88
|
+
* @param {object} args - Options object.
|
|
89
|
+
* @param {typeof import("./base.js").default} args.modelClass - Model class owning the relationship.
|
|
90
|
+
* @param {import("./base.js").default} args.model - Model instance.
|
|
91
|
+
* @param {string} args.relationshipName - Relationship name.
|
|
92
|
+
* @param {import("../database/query/index.js").NestedPreloadRecord[string]} args.subPreload - Preload value for this relationship (`true` or a nested record).
|
|
93
|
+
* @param {import("./query.js").default<any>} args.query - Source query carrying select/selectsExtra.
|
|
94
|
+
* @returns {boolean} - Whether the relationship is already satisfied.
|
|
95
|
+
*/
|
|
96
|
+
static _relationshipSatisfied({ modelClass, model, relationshipName, subPreload, query }) {
|
|
97
|
+
const relationship = model.getRelationshipByName(relationshipName);
|
|
98
|
+
if (!relationship.getPreloaded())
|
|
99
|
+
return false;
|
|
100
|
+
const targetModelClass = modelClass.relationshipModelClass(relationshipName);
|
|
101
|
+
const loaded = relationship.loaded();
|
|
102
|
+
const targets = loaded == null ? [] : (Array.isArray(loaded) ? loaded : [loaded]);
|
|
103
|
+
if (targetModelClass) {
|
|
104
|
+
const targetModelName = targetModelClass.getModelName();
|
|
105
|
+
// `selectsExtra` serializes the default attributes (unknown to the client)
|
|
106
|
+
// plus the extras, so a cached target can't be proven complete.
|
|
107
|
+
if (query._selectsExtra[targetModelName])
|
|
108
|
+
return false;
|
|
109
|
+
const required = query._select[targetModelName] || [];
|
|
110
|
+
for (const target of targets) {
|
|
111
|
+
for (const attributeName of required) {
|
|
112
|
+
if (!target.hasLoadedAttribute(attributeName))
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const nestedPreload = this._nestedPreloadRecord(subPreload);
|
|
118
|
+
if (nestedPreload && targetModelClass) {
|
|
119
|
+
for (const target of targets) {
|
|
120
|
+
if (this._modelNeedsReload({ modelClass: targetModelClass, model: target, preload: nestedPreload, query, force: false })) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* @param {import("../database/query/index.js").NestedPreloadRecord[string]} subPreload - Preload value for a relationship.
|
|
129
|
+
* @returns {import("../database/query/index.js").NestedPreloadRecord | null} - Nested preload record, or null when there is no deeper graph.
|
|
130
|
+
*/
|
|
131
|
+
static _nestedPreloadRecord(subPreload) {
|
|
132
|
+
if (!subPreload || typeof subPreload !== "object")
|
|
133
|
+
return null;
|
|
134
|
+
if (Object.keys(subPreload).length === 0)
|
|
135
|
+
return null;
|
|
136
|
+
return /** @type {import("../database/query/index.js").NestedPreloadRecord} */ (subPreload);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlbG9hZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Zyb250ZW5kLW1vZGVscy9wcmVsb2FkZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFNLENBQUMsT0FBTyxPQUFPLHNCQUFzQjtJQUN6Qzs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxXQUFXLEVBQUUsRUFBQyxLQUFLLEdBQUcsS0FBSyxFQUFDLEdBQUcsRUFBRTtRQUM1RCxJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUFFLE9BQU07UUFFMUMsTUFBTSxVQUFVLEdBQUcsaURBQWlELENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUE7UUFDNUYsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLE9BQU8sV0FBVyxLQUFLLFFBQVEsSUFBSSxVQUFVLElBQUksV0FBVyxDQUFBO1FBQ3BHLE1BQU0sS0FBSyxHQUFHLE9BQU87WUFDbkIsQ0FBQyxDQUFDLGdEQUFnRCxDQUFDLENBQUMsV0FBVyxDQUFDO1lBQ2hFLENBQUMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQTtRQUV4RCxNQUFNLHFCQUFxQixHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRXpELElBQUkscUJBQXFCLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFNO1FBRTlDLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsT0FB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QU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUM3QixJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFDLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQ3ZILE9BQU8sS0FBSyxDQUFBO2dCQUNkLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFBO0lBQ2IsQ0FBQztJQUVEOzs7T0FHRztJQUNILE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVO1FBQ3BDLElBQUksQ0FBQyxVQUFVLElBQUksT0FBTyxVQUFVLEtBQUssUUFBUTtZQUFFLE9BQU8sSUFBSSxDQUFBO1FBQzlELElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUFFLE9BQU8sSUFBSSxDQUFBO1FBRXJELE9BQU8sdUVBQXVFLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUM3RixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuLyoqXG4gKiBQcmVsb2FkcyByZWxhdGlvbnNoaXBzIG9udG8gYWxyZWFkeS1sb2FkZWQgZnJvbnRlbmQgbW9kZWwgaW5zdGFuY2VzLlxuICpcbiAqIFVubGlrZSB0aGUgYmFja2VuZCBPUk0gcHJlbG9hZGVyICh3aGljaCBxdWVyaWVzIHJlbGF0aW9uc2hpcCB0YWJsZXNcbiAqIGRpcmVjdGx5KSwgdGhlIGZyb250ZW5kIHJlLWZldGNoZXMgdGhlIHBhcmVudCByZWNvcmRzIHRocm91Z2ggdGhlaXJcbiAqIGBpbmRleGAgZW5kcG9pbnQgd2l0aCB0aGUgcHJlbG9hZC9zZWxlY3QgcGFyYW1zLCB0aGVuIGNvcGllcyB0aGUgcmVzdWx0aW5nXG4gKiB0b3AtbGV2ZWwgcHJlbG9hZGVkIHJlbGF0aW9uc2hpcHMgb250byB0aGUgZXhpc3RpbmcgaW5zdGFuY2VzLiBSZWxhdGlvbnNoaXBzXG4gKiB0aGF0IGFyZSBhbHJlYWR5IHByZWxvYWRlZCB3aXRoIHRoZSByZXF1aXJlZCBjb2x1bW5zIHByZXNlbnQgYXJlIHNraXBwZWQsXG4gKiBzbyByZXBlYXRlZCBjYWxscyByZXVzZSB0aGUgcmVsYXRpb25zaGlwIGNhY2hlIGluc3RlYWQgb2YgaXNzdWluZyBkdXBsaWNhdGVcbiAqIHJlcXVlc3RzLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGcm9udGVuZE1vZGVsUHJlbG9hZGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi9iYXNlLmpzXCIpLmRlZmF1bHQ+fSBtb2RlbHMgLSBGcm9udGVuZCBtb2RlbCBpbnN0YW5jZXMgdG8gcHJlbG9hZCBvbnRvLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcXVlcnkuanNcIikuZGVmYXVsdDxhbnk+IHwgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcXVlcnkvaW5kZXguanNcIikuTmVzdGVkUHJlbG9hZFJlY29yZCB8IHN0cmluZyB8IEFycmF5PHN0cmluZyB8IGltcG9ydChcIi4uL2RhdGFiYXNlL3F1ZXJ5L2luZGV4LmpzXCIpLk5lc3RlZFByZWxvYWRSZWNvcmQ+fSBxdWVyeU9yU3BlYyAtIEEgcXVlcnkgYnVpbHQgdmlhIGBNb2RlbC5wcmVsb2FkKC4uLikuc2VsZWN0KC4uLilgLCBvciBhIHJhdyBwcmVsb2FkIHNwZWMuXG4gICAqIEBwYXJhbSB7e2ZvcmNlPzogYm9vbGVhbn19IFtvcHRpb25zXSAtIE9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gcHJlbG9hZGluZyBjb21wbGV0ZXMuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcHJlbG9hZChtb2RlbHMsIHF1ZXJ5T3JTcGVjLCB7Zm9yY2UgPSBmYWxzZX0gPSB7fSkge1xuICAgIGlmICghbW9kZWxzIHx8IG1vZGVscy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gICAgY29uc3QgbW9kZWxDbGFzcyA9IC8qKiBAdHlwZSB7dHlwZW9mIGltcG9ydChcIi4vYmFzZS5qc1wiKS5kZWZhdWx0fSAqLyAobW9kZWxzWzBdLmNvbnN0cnVjdG9yKVxuICAgIGNvbnN0IGlzUXVlcnkgPSBCb29sZWFuKHF1ZXJ5T3JTcGVjKSAmJiB0eXBlb2YgcXVlcnlPclNwZWMgPT09IFwib2JqZWN0XCIgJiYgXCJfcHJlbG9hZFwiIGluIHF1ZXJ5T3JTcGVjXG4gICAgY29uc3QgcXVlcnkgPSBpc1F1ZXJ5XG4gICAgICA/IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9xdWVyeS5qc1wiKS5kZWZhdWx0PGFueT59ICovIChxdWVyeU9yU3BlYylcbiAgICAgIDogbW9kZWxDbGFzcy5wcmVsb2FkKC8qKiBAdHlwZSB7YW55fSAqLyAocXVlcnlPclNwZWMpKVxuXG4gICAgY29uc3QgdG9wTGV2ZWxSZWxhdGlvbnNoaXBzID0gT2JqZWN0LmtleXMocXVlcnkuX3ByZWxvYWQpXG5cbiAgICBpZiAodG9wTGV2ZWxSZWxhdGlvbnNoaXBzLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgICBjb25zdCBtb2RlbHNUb0xvYWQgPSBtb2RlbHMuZmlsdGVyKChtb2RlbCkgPT4gdGhpcy5fbW9kZWxOZWVkc1JlbG9hZCh7bW9kZWxDbGFzcywgbW9kZWwsIHByZWxvYWQ6IHF1ZXJ5Ll9wcmVsb2FkLCBxdWVyeSwgZm9yY2V9KSlcblxuICAgIGlmIChtb2RlbHNUb0xvYWQubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAgIGNvbnN0IHByaW1hcnlLZXkgPSBtb2RlbENsYXNzLnByaW1hcnlLZXkoKVxuICAgIGNvbnN0IGlkcyA9IG1vZGVsc1RvTG9hZC5tYXAoKG1vZGVsKSA9PiBtb2RlbC5wcmltYXJ5S2V5VmFsdWUoKSlcblxuICAgIC8vIFJlYnVpbGQgYSBmcmVzaCBxdWVyeSBjYXJyeWluZyBvbmx5IHRoZSBwcm9qZWN0aW9uLXJlbGV2YW50IHN0YXRlIHNvIGFcbiAgICAvLyB1c2VyLXN1cHBsaWVkIGxpbWl0L3NvcnQvd2hlcmUgb24gdGhlIHNvdXJjZSBxdWVyeSBkb2Vzbid0IGxlYWsgaW4uXG4gICAgY29uc3QgcmVsb2FkUXVlcnkgPSBtb2RlbENsYXNzLnByZWxvYWQocXVlcnkuX3ByZWxvYWQpXG5cbiAgICByZWxvYWRRdWVyeS5fc2VsZWN0ID0gcXVlcnkuX3NlbGVjdFxuICAgIHJlbG9hZFF1ZXJ5Ll9zZWxlY3RzRXh0cmEgPSBxdWVyeS5fc2VsZWN0c0V4dHJhXG4gICAgcmVsb2FkUXVlcnkuX3dpdGhDb3VudCA9IHF1ZXJ5Ll93aXRoQ291bnRcbiAgICByZWxvYWRRdWVyeS5fYWJpbGl0aWVzID0gcXVlcnkuX2FiaWxpdGllc1xuICAgIHJlbG9hZFF1ZXJ5Ll9xdWVyeURhdGEgPSBxdWVyeS5fcXVlcnlEYXRhXG4gICAgcmVsb2FkUXVlcnkud2hlcmUoe1twcmltYXJ5S2V5XTogaWRzfSlcblxuICAgIGNvbnN0IHJlbG9hZGVkID0gYXdhaXQgcmVsb2FkUXVlcnkudG9BcnJheSgpXG5cbiAgICAvKiogQHR5cGUge01hcDxzdHJpbmcsIGltcG9ydChcIi4vYmFzZS5qc1wiKS5kZWZhdWx0Pn0gKi9cbiAgICBjb25zdCByZWxvYWRlZEJ5SWQgPSBuZXcgTWFwKClcblxuICAgIGZvciAoY29uc3QgcmVsb2FkZWRNb2RlbCBvZiByZWxvYWRlZCkge1xuICAgICAgcmVsb2FkZWRCeUlkLnNldChTdHJpbmcocmVsb2FkZWRNb2RlbC5wcmltYXJ5S2V5VmFsdWUoKSksIHJlbG9hZGVkTW9kZWwpXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBtb2RlbCBvZiBtb2RlbHNUb0xvYWQpIHtcbiAgICAgIGNvbnN0IHJlbG9hZGVkTW9kZWwgPSByZWxvYWRlZEJ5SWQuZ2V0KFN0cmluZyhtb2RlbC5wcmltYXJ5S2V5VmFsdWUoKSkpXG5cbiAgICAgIC8vIFRoZSByZWNvcmQgbWF5IGhhdmUgYmVlbiBkZWxldGVkL2ZpbHRlcmVkIGJldHdlZW4gdGhlIG9yaWdpbmFsIGxvYWQgYW5kXG4gICAgICAvLyB0aGlzIHByZWxvYWQg4oCUIHNraXAgaXQgcmF0aGVyIHRoYW4gY3Jhc2hpbmcgb24gYSBtaXNzaW5nIHJlbG9hZC5cbiAgICAgIGlmICghcmVsb2FkZWRNb2RlbCkgY29udGludWVcblxuICAgICAgZm9yIChjb25zdCByZWxhdGlvbnNoaXBOYW1lIG9mIHRvcExldmVsUmVsYXRpb25zaGlwcykge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHJlbG9hZGVkTW9kZWwuZ2V0UmVsYXRpb25zaGlwQnlOYW1lKHJlbGF0aW9uc2hpcE5hbWUpLmxvYWRlZCgpXG5cbiAgICAgICAgbW9kZWwuZ2V0UmVsYXRpb25zaGlwQnlOYW1lKHJlbGF0aW9uc2hpcE5hbWUpLnNldExvYWRlZCh2YWx1ZSlcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi9iYXNlLmpzXCIpLmRlZmF1bHR9IGFyZ3MubW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzIHRoZSBwcmVsb2FkIGdyYXBoIGlzIHJvb3RlZCBhdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Jhc2UuanNcIikuZGVmYXVsdH0gYXJncy5tb2RlbCAtIE1vZGVsIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3F1ZXJ5L2luZGV4LmpzXCIpLk5lc3RlZFByZWxvYWRSZWNvcmR9IGFyZ3MucHJlbG9hZCAtIFByZWxvYWQgc3ViLWdyYXBoIHRvIHNhdGlzZnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9xdWVyeS5qc1wiKS5kZWZhdWx0PGFueT59IGFyZ3MucXVlcnkgLSBTb3VyY2UgcXVlcnkgY2Fycnlpbmcgc2VsZWN0L3NlbGVjdHNFeHRyYS5cbiAgICogQHBhcmFtIHtib29sZWFufSBhcmdzLmZvcmNlIC0gV2hldGhlciB0byByZWxvYWQgcmVnYXJkbGVzcyBvZiBjYWNoZWQgc3RhdGUuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIG1vZGVsIG5lZWRzIGEgcmVsb2FkIHJlcXVlc3QuXG4gICAqL1xuICBzdGF0aWMgX21vZGVsTmVlZHNSZWxvYWQoe21vZGVsQ2xhc3MsIG1vZGVsLCBwcmVsb2FkLCBxdWVyeSwgZm9yY2V9KSB7XG4gICAgaWYgKGZvcmNlKSByZXR1cm4gdHJ1ZVxuXG4gICAgZm9yIChjb25zdCByZWxhdGlvbnNoaXBOYW1lIG9mIE9iamVjdC5rZXlzKHByZWxvYWQpKSB7XG4gICAgICBpZiAoIXRoaXMuX3JlbGF0aW9uc2hpcFNhdGlzZmllZCh7bW9kZWxDbGFzcywgbW9kZWwsIHJlbGF0aW9uc2hpcE5hbWUsIHN1YlByZWxvYWQ6IHByZWxvYWRbcmVsYXRpb25zaGlwTmFtZV0sIHF1ZXJ5fSkpIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQSByZWxhdGlvbnNoaXAgaXMgc2F0aXNmaWVkIHdoZW4gaXQgaXMgYWxyZWFkeSBwcmVsb2FkZWQsIGV2ZXJ5IHJlcXVpcmVkXG4gICAqIGBzZWxlY3RgIGF0dHJpYnV0ZSBpcyBwcmVzZW50IG9uIGVhY2ggbG9hZGVkIHRhcmdldCwgYW5kIGFueSBuZXN0ZWQgcHJlbG9hZFxuICAgKiBzdWItZ3JhcGggaXMgcmVjdXJzaXZlbHkgc2F0aXNmaWVkIG9uIHRob3NlIHRhcmdldHMuIGBzZWxlY3RzRXh0cmFgIGNhblxuICAgKiBuZXZlciBiZSBwcm92ZW4gc2F0aXNmaWVkIGZyb20gdGhlIGNhY2hlICh0aGUgYmFja2VuZCBzZXJpYWxpemVzIHRoZVxuICAgKiBjbGllbnQtdW5rbm93biBkZWZhdWx0IGF0dHJpYnV0ZXMgcGx1cyB0aGUgZXh0cmFzKSwgc28gaXQgYWx3YXlzIHJlbG9hZHMuXG4gICAqIFdpdGggbm8gc2VsZWN0IGFuZCBubyBuZXN0ZWQgcHJlbG9hZCwgYmVpbmcgcHJlbG9hZGVkIGlzIGVub3VnaC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi9iYXNlLmpzXCIpLmRlZmF1bHR9IGFyZ3MubW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzIG93bmluZyB0aGUgcmVsYXRpb25zaGlwLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vYmFzZS5qc1wiKS5kZWZhdWx0fSBhcmdzLm1vZGVsIC0gTW9kZWwgaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLnJlbGF0aW9uc2hpcE5hbWUgLSBSZWxhdGlvbnNoaXAgbmFtZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9xdWVyeS9pbmRleC5qc1wiKS5OZXN0ZWRQcmVsb2FkUmVjb3JkW3N0cmluZ119IGFyZ3Muc3ViUHJlbG9hZCAtIFByZWxvYWQgdmFsdWUgZm9yIHRoaXMgcmVsYXRpb25zaGlwIChgdHJ1ZWAgb3IgYSBuZXN0ZWQgcmVjb3JkKS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLmRlZmF1bHQ8YW55Pn0gYXJncy5xdWVyeSAtIFNvdXJjZSBxdWVyeSBjYXJyeWluZyBzZWxlY3Qvc2VsZWN0c0V4dHJhLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSByZWxhdGlvbnNoaXAgaXMgYWxyZWFkeSBzYXRpc2ZpZWQuXG4gICAqL1xuICBzdGF0aWMgX3JlbGF0aW9uc2hpcFNhdGlzZmllZCh7bW9kZWxDbGFzcywgbW9kZWwsIHJlbGF0aW9uc2hpcE5hbWUsIHN1YlByZWxvYWQsIHF1ZXJ5fSkge1xuICAgIGNvbnN0IHJlbGF0aW9uc2hpcCA9IG1vZGVsLmdldFJlbGF0aW9uc2hpcEJ5TmFtZShyZWxhdGlvbnNoaXBOYW1lKVxuXG4gICAgaWYgKCFyZWxhdGlvbnNoaXAuZ2V0UHJlbG9hZGVkKCkpIHJldHVybiBmYWxzZVxuXG4gICAgY29uc3QgdGFyZ2V0TW9kZWxDbGFzcyA9IG1vZGVsQ2xhc3MucmVsYXRpb25zaGlwTW9kZWxDbGFzcyhyZWxhdGlvbnNoaXBOYW1lKVxuICAgIGNvbnN0IGxvYWRlZCA9IHJlbGF0aW9uc2hpcC5sb2FkZWQoKVxuICAgIGNvbnN0IHRhcmdldHMgPSBsb2FkZWQgPT0gbnVsbCA/IFtdIDogKEFycmF5LmlzQXJyYXkobG9hZGVkKSA/IGxvYWRlZCA6IFtsb2FkZWRdKVxuXG4gICAgaWYgKHRhcmdldE1vZGVsQ2xhc3MpIHtcbiAgICAgIGNvbnN0IHRhcmdldE1vZGVsTmFtZSA9IHRhcmdldE1vZGVsQ2xhc3MuZ2V0TW9kZWxOYW1lKClcblxuICAgICAgLy8gYHNlbGVjdHNFeHRyYWAgc2VyaWFsaXplcyB0aGUgZGVmYXVsdCBhdHRyaWJ1dGVzICh1bmtub3duIHRvIHRoZSBjbGllbnQpXG4gICAgICAvLyBwbHVzIHRoZSBleHRyYXMsIHNvIGEgY2FjaGVkIHRhcmdldCBjYW4ndCBiZSBwcm92ZW4gY29tcGxldGUuXG4gICAgICBpZiAocXVlcnkuX3NlbGVjdHNFeHRyYVt0YXJnZXRNb2RlbE5hbWVdKSByZXR1cm4gZmFsc2VcblxuICAgICAgY29uc3QgcmVxdWlyZWQgPSBxdWVyeS5fc2VsZWN0W3RhcmdldE1vZGVsTmFtZV0gfHwgW11cblxuICAgICAgZm9yIChjb25zdCB0YXJnZXQgb2YgdGFyZ2V0cykge1xuICAgICAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZU5hbWUgb2YgcmVxdWlyZWQpIHtcbiAgICAgICAgICBpZiAoIXRhcmdldC5oYXNMb2FkZWRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSkpIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbmVzdGVkUHJlbG9hZCA9IHRoaXMuX25lc3RlZFByZWxvYWRSZWNvcmQoc3ViUHJlbG9hZClcblxuICAgIGlmIChuZXN0ZWRQcmVsb2FkICYmIHRhcmdldE1vZGVsQ2xhc3MpIHtcbiAgICAgIGZvciAoY29uc3QgdGFyZ2V0IG9mIHRhcmdldHMpIHtcbiAgICAgICAgaWYgKHRoaXMuX21vZGVsTmVlZHNSZWxvYWQoe21vZGVsQ2xhc3M6IHRhcmdldE1vZGVsQ2xhc3MsIG1vZGVsOiB0YXJnZXQsIHByZWxvYWQ6IG5lc3RlZFByZWxvYWQsIHF1ZXJ5LCBmb3JjZTogZmFsc2V9KSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3F1ZXJ5L2luZGV4LmpzXCIpLk5lc3RlZFByZWxvYWRSZWNvcmRbc3RyaW5nXX0gc3ViUHJlbG9hZCAtIFByZWxvYWQgdmFsdWUgZm9yIGEgcmVsYXRpb25zaGlwLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZGF0YWJhc2UvcXVlcnkvaW5kZXguanNcIikuTmVzdGVkUHJlbG9hZFJlY29yZCB8IG51bGx9IC0gTmVzdGVkIHByZWxvYWQgcmVjb3JkLCBvciBudWxsIHdoZW4gdGhlcmUgaXMgbm8gZGVlcGVyIGdyYXBoLlxuICAgKi9cbiAgc3RhdGljIF9uZXN0ZWRQcmVsb2FkUmVjb3JkKHN1YlByZWxvYWQpIHtcbiAgICBpZiAoIXN1YlByZWxvYWQgfHwgdHlwZW9mIHN1YlByZWxvYWQgIT09IFwib2JqZWN0XCIpIHJldHVybiBudWxsXG4gICAgaWYgKE9iamVjdC5rZXlzKHN1YlByZWxvYWQpLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGxcblxuICAgIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RhdGFiYXNlL3F1ZXJ5L2luZGV4LmpzXCIpLk5lc3RlZFByZWxvYWRSZWNvcmR9ICovIChzdWJQcmVsb2FkKVxuICB9XG59XG4iXX0=
|
|
@@ -28,7 +28,10 @@ export default class FrontendModelQuery<T extends typeof import("./base.js").def
|
|
|
28
28
|
_preload: import("../database/query/index.js").NestedPreloadRecord;
|
|
29
29
|
_joins: {};
|
|
30
30
|
_where: {};
|
|
31
|
-
|
|
31
|
+
/** @type {Record<string, string[]>} */
|
|
32
|
+
_select: Record<string, string[]>;
|
|
33
|
+
/** @type {Record<string, string[]>} */
|
|
34
|
+
_selectsExtra: Record<string, string[]>;
|
|
32
35
|
_distinct: boolean;
|
|
33
36
|
_limit: number | null;
|
|
34
37
|
_offset: number | null;
|
|
@@ -152,6 +155,14 @@ export default class FrontendModelQuery<T extends typeof import("./base.js").def
|
|
|
152
155
|
* @returns {this} - Query with merged selected attributes.
|
|
153
156
|
*/
|
|
154
157
|
select(select: Record<string, string[] | string> | string | string[]): this;
|
|
158
|
+
/**
|
|
159
|
+
* Like `select(...)`, but keeps the default serialized attributes and loads
|
|
160
|
+
* the given extras in addition (for example attributes declared
|
|
161
|
+
* `selectedByDefault: false`). Keyed by model name, with root-model shorthand.
|
|
162
|
+
* @param {Record<string, string[] | string> | string | string[]} select - Extra attributes to load, keyed by model name or root-model shorthand.
|
|
163
|
+
* @returns {this} - Query with merged extra selected attributes.
|
|
164
|
+
*/
|
|
165
|
+
selectsExtra(select: Record<string, string[] | string> | string | string[]): this;
|
|
155
166
|
/**
|
|
156
167
|
* @param {Record<string, any> | Array<Record<string, any>>} joins - Relationship descriptor joins.
|
|
157
168
|
* @returns {this} - Query with merged joins.
|
|
@@ -232,6 +243,10 @@ export default class FrontendModelQuery<T extends typeof import("./base.js").def
|
|
|
232
243
|
* @returns {Record<string, any>} - Payload select hash when present.
|
|
233
244
|
*/
|
|
234
245
|
selectPayload(requiredAttributes?: string[]): Record<string, any>;
|
|
246
|
+
/**
|
|
247
|
+
* @returns {Record<string, any>} - Payload selectsExtra hash when present.
|
|
248
|
+
*/
|
|
249
|
+
selectsExtraPayload(): Record<string, any>;
|
|
235
250
|
/**
|
|
236
251
|
* @returns {Record<string, any>} - Payload searches array when present.
|
|
237
252
|
*/
|
|
@@ -350,6 +365,10 @@ export type FrontendModelProjectionOptions = {
|
|
|
350
365
|
* - Model-aware attribute select map or root-model shorthand.
|
|
351
366
|
*/
|
|
352
367
|
select?: string | string[] | Record<string, string | string[]> | undefined;
|
|
368
|
+
/**
|
|
369
|
+
* - Extra attributes to load in addition to the defaults, keyed by model name or root-model shorthand.
|
|
370
|
+
*/
|
|
371
|
+
selectsExtra?: string | string[] | Record<string, string | string[]> | undefined;
|
|
353
372
|
/**
|
|
354
373
|
* - Relationship preload tree.
|
|
355
374
|
*/
|
|
@@ -375,6 +394,10 @@ export type FrontendModelProjectionPayload = {
|
|
|
375
394
|
* - Normalized select map.
|
|
376
395
|
*/
|
|
377
396
|
select?: Record<string, string[]> | undefined;
|
|
397
|
+
/**
|
|
398
|
+
* - Normalized extra select map.
|
|
399
|
+
*/
|
|
400
|
+
selectsExtra?: Record<string, string[]> | undefined;
|
|
378
401
|
/**
|
|
379
402
|
* - Normalized preload tree.
|
|
380
403
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/frontend-models/query.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/frontend-models/query.js"],"names":[],"mappings":"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"}
|