@aeriajs/core 0.0.138 → 0.0.140
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/collection/preload.js +1 -1
- package/dist/collection/preload.mjs +1 -1
- package/dist/collection/reference.d.ts +13 -7
- package/dist/collection/reference.js +252 -226
- package/dist/collection/reference.mjs +244 -215
- package/dist/collection/traverseDocument.d.ts +1 -1
- package/dist/collection/traverseDocument.js +3 -0
- package/dist/collection/traverseDocument.mjs +3 -0
- package/dist/functions/get.js +12 -11
- package/dist/functions/get.mjs +14 -14
- package/dist/functions/getAll.js +13 -12
- package/dist/functions/getAll.mjs +15 -15
- package/dist/functions/insert.js +1 -1
- package/dist/functions/insert.mjs +1 -1
- package/package.json +10 -9
|
@@ -2,96 +2,34 @@
|
|
|
2
2
|
import { throwIfError, getReferenceProperty } from "@aeriajs/common";
|
|
3
3
|
import { getCollectionAsset } from "../assets.mjs";
|
|
4
4
|
import { prepareCollectionName } from "../database.mjs";
|
|
5
|
+
const getTempName = (path) => {
|
|
6
|
+
return `_${path.join("_")}`;
|
|
7
|
+
};
|
|
5
8
|
const referenceMemo = {};
|
|
6
9
|
const lookupMemo = {};
|
|
7
|
-
const
|
|
8
|
-
const hasAny = (propName) => {
|
|
9
|
-
return propName.includes(".") || projection.includes(propName);
|
|
10
|
-
};
|
|
11
|
-
return pipeline.filter((stage) => {
|
|
12
|
-
if (stage.$lookup) {
|
|
13
|
-
return hasAny(stage.$lookup.as);
|
|
14
|
-
}
|
|
15
|
-
if (stage.$unwind) {
|
|
16
|
-
return hasAny(stage.$unwind.path.slice(1));
|
|
17
|
-
}
|
|
18
|
-
return true;
|
|
19
|
-
});
|
|
20
|
-
};
|
|
21
|
-
const buildGroupStages = (referenceMap, properties) => {
|
|
22
|
-
const $group = Object.keys(properties).reduce((a, propName) => {
|
|
23
|
-
const refMap = referenceMap[propName] || {};
|
|
24
|
-
const groupType = !refMap.referencedCollection && refMap.isArray ? "push" : "first";
|
|
25
|
-
return {
|
|
26
|
-
...a,
|
|
27
|
-
[propName]: {
|
|
28
|
-
[`$${groupType}`]: `$${propName}`
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
}, {
|
|
32
|
-
_id: "$_id"
|
|
33
|
-
});
|
|
34
|
-
return {
|
|
35
|
-
$group
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
const buildArrayCleanupStages = (referenceMap) => {
|
|
39
|
-
const $set = Object.entries(referenceMap).reduce((a, [refName, refMap]) => {
|
|
40
|
-
if (!refMap.isArray || refMap.referencedCollection) {
|
|
41
|
-
return a;
|
|
42
|
-
}
|
|
43
|
-
return {
|
|
44
|
-
...a,
|
|
45
|
-
[refName]: {
|
|
46
|
-
$filter: {
|
|
47
|
-
input: `$${refName}`,
|
|
48
|
-
as: `${refName}_elem`,
|
|
49
|
-
cond: {
|
|
50
|
-
$ne: [
|
|
51
|
-
`$$${refName}_elem`,
|
|
52
|
-
{}
|
|
53
|
-
]
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
}, {});
|
|
59
|
-
return Object.keys($set).length > 0 ? {
|
|
60
|
-
$set
|
|
61
|
-
} : null;
|
|
62
|
-
};
|
|
63
|
-
export const getReferences = async (properties, options) => {
|
|
10
|
+
export const getReferences = async (properties, options = {}) => {
|
|
64
11
|
const {
|
|
65
12
|
depth = 0,
|
|
13
|
+
maxDepth = 3,
|
|
66
14
|
memoize
|
|
67
|
-
} = options
|
|
15
|
+
} = options;
|
|
68
16
|
if (memoize) {
|
|
69
17
|
if (referenceMemo[memoize]) {
|
|
70
18
|
return referenceMemo[memoize];
|
|
71
19
|
}
|
|
72
20
|
}
|
|
73
|
-
const
|
|
21
|
+
const refMap = {};
|
|
74
22
|
for (const [propName, property] of Object.entries(properties)) {
|
|
75
23
|
const refProperty = getReferenceProperty(property);
|
|
76
24
|
const reference = {};
|
|
77
|
-
if (depth ===
|
|
25
|
+
if (depth === maxDepth || refProperty && refProperty.populate && refProperty.populate.length === 0) {
|
|
78
26
|
continue;
|
|
79
27
|
}
|
|
80
|
-
if (
|
|
81
|
-
const entrypoint = "items" in property ? property.items : property;
|
|
82
|
-
if ("properties" in entrypoint) {
|
|
83
|
-
const deepReferences = await getReferences(entrypoint.properties, {
|
|
84
|
-
memoize: `${memoize}.${propName}`
|
|
85
|
-
});
|
|
86
|
-
if (Object.keys(deepReferences).length > 0) {
|
|
87
|
-
reference.deepReferences ??= {};
|
|
88
|
-
reference.deepReferences = deepReferences;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
} else {
|
|
28
|
+
if (refProperty) {
|
|
92
29
|
const description = throwIfError(await getCollectionAsset(refProperty.$ref, "description"));
|
|
93
30
|
const deepReferences = await getReferences(description.properties, {
|
|
94
31
|
depth: depth + 1,
|
|
32
|
+
maxDepth: refProperty.populateDepth || maxDepth,
|
|
95
33
|
memoize: `${memoize}.${propName}`
|
|
96
34
|
});
|
|
97
35
|
if (Object.keys(deepReferences).length > 0) {
|
|
@@ -99,6 +37,17 @@ export const getReferences = async (properties, options) => {
|
|
|
99
37
|
}
|
|
100
38
|
const indexes = refProperty.indexes ? refProperty.indexes : description.indexes || [];
|
|
101
39
|
reference.populatedProperties = (refProperty.populate || []).concat(indexes.filter((index) => typeof index === "string"));
|
|
40
|
+
} else {
|
|
41
|
+
const entrypoint = "items" in property ? property.items : property;
|
|
42
|
+
if ("properties" in entrypoint) {
|
|
43
|
+
const deepReferences = await getReferences(entrypoint.properties, {
|
|
44
|
+
memoize: `${memoize}.${propName}`
|
|
45
|
+
});
|
|
46
|
+
if (Object.keys(deepReferences).length > 0) {
|
|
47
|
+
reference.deepReferences ??= {};
|
|
48
|
+
reference.deepReferences = deepReferences;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
102
51
|
}
|
|
103
52
|
if (!refProperty?.$ref && !reference.deepReferences) {
|
|
104
53
|
continue;
|
|
@@ -106,6 +55,9 @@ export const getReferences = async (properties, options) => {
|
|
|
106
55
|
if ("items" in property) {
|
|
107
56
|
reference.isArray = true;
|
|
108
57
|
}
|
|
58
|
+
if (depth > 0) {
|
|
59
|
+
reference.isRecursive = true;
|
|
60
|
+
}
|
|
109
61
|
if (refProperty) {
|
|
110
62
|
if (refProperty.$ref) {
|
|
111
63
|
reference.referencedCollection = refProperty.$ref;
|
|
@@ -114,178 +66,255 @@ export const getReferences = async (properties, options) => {
|
|
|
114
66
|
reference.isInline = true;
|
|
115
67
|
}
|
|
116
68
|
}
|
|
117
|
-
|
|
69
|
+
refMap[propName] = reference;
|
|
118
70
|
}
|
|
119
71
|
if (memoize) {
|
|
120
|
-
referenceMemo[memoize] =
|
|
72
|
+
referenceMemo[memoize] = refMap;
|
|
121
73
|
}
|
|
122
|
-
return
|
|
74
|
+
return refMap;
|
|
123
75
|
};
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
from: prepareCollectionName(reference.referencedCollection),
|
|
141
|
-
foreignField: "_id",
|
|
142
|
-
localField: withParent(propName),
|
|
143
|
-
as: withParent(propName)
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
} else {
|
|
147
|
-
const subPipeline = [];
|
|
148
|
-
if (reference.deepReferences) {
|
|
149
|
-
const subProperties = throwIfError(await getCollectionAsset(reference.referencedCollection, "description")).properties;
|
|
150
|
-
subPipeline.push(...await buildLookupPipeline(reference.deepReferences, {
|
|
151
|
-
project: reference.populatedProperties,
|
|
152
|
-
properties: subProperties
|
|
153
|
-
}));
|
|
154
|
-
}
|
|
155
|
-
if (reference.populatedProperties.length > 0) {
|
|
156
|
-
subPipeline.push({
|
|
157
|
-
$project: Object.fromEntries(reference.populatedProperties.map((index) => [
|
|
158
|
-
index,
|
|
159
|
-
1
|
|
160
|
-
]))
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
stages.push({
|
|
164
|
-
$lookup: {
|
|
165
|
-
from: prepareCollectionName(reference.referencedCollection),
|
|
166
|
-
let: {
|
|
167
|
-
"ids": !reference.isArray ? `$${withParent(propName)}` : {
|
|
168
|
-
$ifNull: [
|
|
169
|
-
`$${withParent(propName)}`,
|
|
170
|
-
[]
|
|
76
|
+
export const recurseSetStage = (reference, path, parentElem, options = {
|
|
77
|
+
noCond: false
|
|
78
|
+
}) => {
|
|
79
|
+
const refName = path.at(-1);
|
|
80
|
+
let indexOfArray;
|
|
81
|
+
if (reference.isRecursive && !reference.isArrayElement) {
|
|
82
|
+
indexOfArray = {
|
|
83
|
+
$indexOfArray: [
|
|
84
|
+
`$${getTempName(path)}._id`,
|
|
85
|
+
{
|
|
86
|
+
$arrayElemAt: [
|
|
87
|
+
`$${getTempName(path.slice(0, -1))}.${refName}`,
|
|
88
|
+
{
|
|
89
|
+
$indexOfArray: [
|
|
90
|
+
`$${getTempName(path.slice(0, -1))}._id`,
|
|
91
|
+
parentElem
|
|
171
92
|
]
|
|
172
93
|
}
|
|
173
|
-
},
|
|
174
|
-
as: withParent(propName),
|
|
175
|
-
pipeline: [
|
|
176
|
-
{
|
|
177
|
-
$match: {
|
|
178
|
-
$expr: {
|
|
179
|
-
[reference.isArray ? "$in" : "$eq"]: [
|
|
180
|
-
"$_id",
|
|
181
|
-
"$$ids"
|
|
182
|
-
]
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
},
|
|
186
|
-
...subPipeline
|
|
187
94
|
]
|
|
188
95
|
}
|
|
189
|
-
|
|
96
|
+
]
|
|
97
|
+
};
|
|
98
|
+
} else {
|
|
99
|
+
indexOfArray = {
|
|
100
|
+
$indexOfArray: [
|
|
101
|
+
`$${getTempName(path)}._id`,
|
|
102
|
+
parentElem
|
|
103
|
+
]
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
if (reference.isArray) {
|
|
107
|
+
const newElemName = `${refName}__elem`;
|
|
108
|
+
let mapIn;
|
|
109
|
+
if (reference.referencedCollection) {
|
|
110
|
+
mapIn = recurseSetStage({
|
|
111
|
+
...reference,
|
|
112
|
+
isArray: false,
|
|
113
|
+
isArrayElement: true
|
|
114
|
+
}, path, `$$${newElemName}`);
|
|
115
|
+
} else {
|
|
116
|
+
mapIn = {
|
|
117
|
+
$mergeObjects: [
|
|
118
|
+
`$$${newElemName}`,
|
|
119
|
+
recurseSetStage({
|
|
120
|
+
...reference,
|
|
121
|
+
isArray: false,
|
|
122
|
+
isArrayElement: true
|
|
123
|
+
}, path, `$$${newElemName}`)
|
|
124
|
+
]
|
|
125
|
+
};
|
|
190
126
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
127
|
+
let mapInput = parentElem;
|
|
128
|
+
if (reference.isRecursive) {
|
|
129
|
+
mapInput = {
|
|
130
|
+
$arrayElemAt: [
|
|
131
|
+
`$${getTempName(path.slice(0, -1))}.${refName}`,
|
|
132
|
+
indexOfArray
|
|
133
|
+
]
|
|
134
|
+
};
|
|
198
135
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
136
|
+
return {
|
|
137
|
+
$filter: {
|
|
138
|
+
input: {
|
|
139
|
+
$map: {
|
|
140
|
+
input: mapInput,
|
|
141
|
+
as: newElemName,
|
|
142
|
+
in: mapIn
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
as: "elem",
|
|
146
|
+
cond: {
|
|
147
|
+
$ne: [
|
|
148
|
+
"$$elem",
|
|
149
|
+
null
|
|
150
|
+
]
|
|
151
|
+
}
|
|
210
152
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
});
|
|
218
|
-
stages.push(...result);
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
if (reference.deepReferences) {
|
|
156
|
+
const stages = [];
|
|
157
|
+
for (const [subRefName, subReference] of Object.entries(reference.deepReferences)) {
|
|
158
|
+
if (!subReference) {
|
|
219
159
|
continue;
|
|
220
160
|
}
|
|
221
|
-
|
|
222
|
-
if (
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
} else if ("items" in refProperties) {
|
|
230
|
-
if (!("properties" in refProperties.items)) {
|
|
231
|
-
throw new Error();
|
|
232
|
-
}
|
|
233
|
-
const { stages: refStages } = await buildLookupStages(refMap, refName, {
|
|
234
|
-
depth: depth + 1,
|
|
235
|
-
parent: withParent(propName),
|
|
236
|
-
properties: refProperties.items.properties
|
|
237
|
-
});
|
|
238
|
-
stages.push(...refStages);
|
|
161
|
+
let newElem;
|
|
162
|
+
if (reference.isRecursive) {
|
|
163
|
+
newElem = {
|
|
164
|
+
$arrayElemAt: [
|
|
165
|
+
`$${getTempName(path.slice(0, -1))}.${refName}`,
|
|
166
|
+
indexOfArray
|
|
167
|
+
]
|
|
168
|
+
};
|
|
239
169
|
} else {
|
|
240
|
-
|
|
170
|
+
newElem = reference.referencedCollection ? parentElem : `${parentElem}.${subRefName}`;
|
|
241
171
|
}
|
|
172
|
+
const result = recurseSetStage(subReference, path.concat(subRefName), newElem);
|
|
173
|
+
stages.push([
|
|
174
|
+
subRefName,
|
|
175
|
+
result
|
|
176
|
+
]);
|
|
177
|
+
}
|
|
178
|
+
if (reference.referencedCollection) {
|
|
179
|
+
return {
|
|
180
|
+
$cond: [
|
|
181
|
+
{
|
|
182
|
+
$ne: [
|
|
183
|
+
indexOfArray,
|
|
184
|
+
-1
|
|
185
|
+
]
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
$mergeObjects: [
|
|
189
|
+
recurseSetStage({
|
|
190
|
+
...reference,
|
|
191
|
+
deepReferences: void 0
|
|
192
|
+
}, path, parentElem, {
|
|
193
|
+
noCond: true
|
|
194
|
+
}),
|
|
195
|
+
Object.fromEntries(stages)
|
|
196
|
+
]
|
|
197
|
+
},
|
|
198
|
+
null
|
|
199
|
+
]
|
|
200
|
+
};
|
|
242
201
|
}
|
|
202
|
+
return Object.fromEntries(stages);
|
|
203
|
+
}
|
|
204
|
+
const arrayElemAt = {
|
|
205
|
+
$arrayElemAt: [
|
|
206
|
+
`$${getTempName(path)}`,
|
|
207
|
+
indexOfArray
|
|
208
|
+
]
|
|
209
|
+
};
|
|
210
|
+
if (options.noCond) {
|
|
211
|
+
return arrayElemAt;
|
|
243
212
|
}
|
|
244
213
|
return {
|
|
245
|
-
|
|
246
|
-
|
|
214
|
+
$cond: [
|
|
215
|
+
{
|
|
216
|
+
$ne: [
|
|
217
|
+
indexOfArray,
|
|
218
|
+
-1
|
|
219
|
+
]
|
|
220
|
+
},
|
|
221
|
+
arrayElemAt,
|
|
222
|
+
null
|
|
223
|
+
]
|
|
247
224
|
};
|
|
248
225
|
};
|
|
249
|
-
export const buildLookupPipeline =
|
|
226
|
+
export const buildLookupPipeline = (refMap, options = {}) => {
|
|
250
227
|
const {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
228
|
+
rootPipeline = [],
|
|
229
|
+
path = [],
|
|
230
|
+
tempNames = [],
|
|
231
|
+
project,
|
|
232
|
+
memoize: memoizeId
|
|
254
233
|
} = options;
|
|
255
|
-
const memoize = `${memoizeId}-${project.sort().join("-")}
|
|
256
|
-
if (
|
|
257
|
-
|
|
258
|
-
|
|
234
|
+
const memoize = project ? `${memoizeId}-${project.sort().join("-")}` : memoizeId;
|
|
235
|
+
if (memoize) {
|
|
236
|
+
if (lookupMemo[memoize]) {
|
|
237
|
+
return lookupMemo[memoize];
|
|
238
|
+
}
|
|
259
239
|
}
|
|
260
|
-
let hasDeepReferences = false;
|
|
261
240
|
const pipeline = [];
|
|
262
|
-
|
|
241
|
+
const setProperties = [];
|
|
242
|
+
for (const [refName, reference] of Object.entries(refMap)) {
|
|
263
243
|
if (!reference) {
|
|
264
244
|
continue;
|
|
265
245
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
246
|
+
if (project) {
|
|
247
|
+
if (!project.includes(refName)) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
if (reference.deepReferences) {
|
|
252
|
+
buildLookupPipeline(reference.deepReferences, {
|
|
253
|
+
rootPipeline,
|
|
254
|
+
tempNames,
|
|
255
|
+
path: path.concat(refName)
|
|
256
|
+
});
|
|
257
|
+
const result = recurseSetStage(reference, path.concat(refName), `$${refName}`);
|
|
258
|
+
setProperties.push([
|
|
259
|
+
refName,
|
|
260
|
+
result
|
|
261
|
+
]);
|
|
262
|
+
}
|
|
263
|
+
if (reference.referencedCollection) {
|
|
264
|
+
const tempName = getTempName(path.concat(refName));
|
|
265
|
+
const lookupPipeline = [];
|
|
266
|
+
tempNames.unshift(tempName);
|
|
267
|
+
if (reference.populatedProperties && reference.populatedProperties.length > 0) {
|
|
268
|
+
const lookupPopulate = reference.populatedProperties;
|
|
269
|
+
if (reference.deepReferences) {
|
|
270
|
+
lookupPopulate.push(...Object.keys(reference.deepReferences));
|
|
271
|
+
}
|
|
272
|
+
lookupPipeline.push({
|
|
273
|
+
$project: Object.fromEntries(reference.populatedProperties.map((index) => [
|
|
274
|
+
index,
|
|
275
|
+
1
|
|
276
|
+
]))
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
const localField = reference.isRecursive ? `${getTempName(path)}.${refName}` : path.concat(refName).join(".");
|
|
280
|
+
rootPipeline.unshift({
|
|
281
|
+
$lookup: {
|
|
282
|
+
from: prepareCollectionName(reference.referencedCollection),
|
|
283
|
+
foreignField: "_id",
|
|
284
|
+
localField,
|
|
285
|
+
as: tempName,
|
|
286
|
+
pipeline: lookupPipeline
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
if (!reference.deepReferences) {
|
|
290
|
+
const result = recurseSetStage(reference, path.concat(refName), `$${refName}`);
|
|
291
|
+
setProperties.push([
|
|
292
|
+
refName,
|
|
293
|
+
result
|
|
294
|
+
]);
|
|
295
|
+
}
|
|
278
296
|
}
|
|
279
297
|
}
|
|
280
|
-
if (
|
|
281
|
-
|
|
298
|
+
if (path.length === 0) {
|
|
299
|
+
if (setProperties.length > 0) {
|
|
300
|
+
pipeline.push({
|
|
301
|
+
$set: Object.fromEntries(setProperties)
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
if (tempNames.length > 0) {
|
|
305
|
+
pipeline.push({
|
|
306
|
+
$unset: tempNames
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
const finalPipeline = rootPipeline.concat(pipeline);
|
|
310
|
+
if (memoize) {
|
|
311
|
+
lookupMemo[memoize] = finalPipeline;
|
|
312
|
+
}
|
|
313
|
+
return finalPipeline;
|
|
282
314
|
}
|
|
283
|
-
return
|
|
315
|
+
return pipeline;
|
|
284
316
|
};
|
|
285
|
-
export const getLookupPipeline = (description,
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
});
|
|
289
|
-
const references = getReferences(description.properties);
|
|
290
|
-
return buildLookupPipeline(references, options);
|
|
317
|
+
export const getLookupPipeline = async (description, options) => {
|
|
318
|
+
const refMap = await getReferences(description.properties);
|
|
319
|
+
return buildLookupPipeline(refMap, options);
|
|
291
320
|
};
|
|
@@ -29,7 +29,7 @@ type PhaseContext = {
|
|
|
29
29
|
options: TraverseOptions & TraverseNormalized;
|
|
30
30
|
isArray?: boolean;
|
|
31
31
|
};
|
|
32
|
-
export declare const traverseDocument: <const TWhat extends Record<string, unknown
|
|
32
|
+
export declare const traverseDocument: <const TWhat extends Record<string, unknown> | null>(what: TWhat, description: Description, _options: TraverseOptions) => Promise<{
|
|
33
33
|
readonly _tag: "Result";
|
|
34
34
|
readonly error: undefined;
|
|
35
35
|
readonly result: any;
|
|
@@ -368,6 +368,9 @@ const recurse = async (target, ctx) => {
|
|
|
368
368
|
const traverseDocument = async (what, description, _options) => {
|
|
369
369
|
const options = Object.assign({}, _options);
|
|
370
370
|
const functions = [];
|
|
371
|
+
if (!what) {
|
|
372
|
+
return types_1.Result.result(what);
|
|
373
|
+
}
|
|
371
374
|
if (!options.validate && Object.keys(what).length === 0) {
|
|
372
375
|
return types_1.Result.result({});
|
|
373
376
|
}
|
|
@@ -326,6 +326,9 @@ const recurse = async (target, ctx) => {
|
|
|
326
326
|
export const traverseDocument = async (what, description, _options) => {
|
|
327
327
|
const options = Object.assign({}, _options);
|
|
328
328
|
const functions = [];
|
|
329
|
+
if (!what) {
|
|
330
|
+
return Result.result(what);
|
|
331
|
+
}
|
|
329
332
|
if (!options.validate && Object.keys(what).length === 0) {
|
|
330
333
|
return Result.result({});
|
|
331
334
|
}
|
package/dist/functions/get.js
CHANGED
|
@@ -6,14 +6,14 @@ const types_1 = require("@aeriajs/types");
|
|
|
6
6
|
const common_1 = require("@aeriajs/common");
|
|
7
7
|
const index_js_1 = require("../collection/index.js");
|
|
8
8
|
const internalGet = async (payload, context) => {
|
|
9
|
-
const { filters = {}, project
|
|
9
|
+
const { filters = {}, project, } = payload;
|
|
10
10
|
if (Object.keys(filters).length === 0) {
|
|
11
11
|
return context.error(types_1.HTTPStatus.BadRequest, {
|
|
12
12
|
code: types_1.ACError.MalformedInput,
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
15
|
const pipeline = [];
|
|
16
|
-
const
|
|
16
|
+
const refMap = await (0, index_js_1.getReferences)(context.description.properties, {
|
|
17
17
|
memoize: context.description.$id,
|
|
18
18
|
});
|
|
19
19
|
pipeline.push({
|
|
@@ -22,18 +22,19 @@ const internalGet = async (payload, context) => {
|
|
|
22
22
|
allowOperators: true,
|
|
23
23
|
})),
|
|
24
24
|
});
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
if (project) {
|
|
26
|
+
const projection = (0, index_js_1.normalizeProjection)(project, context.description);
|
|
27
|
+
if (projection) {
|
|
28
|
+
pipeline.push({
|
|
29
|
+
$project: projection,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
30
32
|
}
|
|
31
|
-
pipeline.push(...
|
|
33
|
+
pipeline.push(...(0, index_js_1.buildLookupPipeline)(refMap, {
|
|
32
34
|
memoize: context.description.$id,
|
|
33
35
|
project: payload.populate
|
|
34
36
|
? payload.populate
|
|
35
37
|
: project,
|
|
36
|
-
properties: context.description.properties,
|
|
37
38
|
}));
|
|
38
39
|
const doc = await context.collection.model.aggregate(pipeline).next();
|
|
39
40
|
if (!doc) {
|
|
@@ -41,12 +42,12 @@ const internalGet = async (payload, context) => {
|
|
|
41
42
|
code: types_1.ACError.ResourceNotFound,
|
|
42
43
|
});
|
|
43
44
|
}
|
|
44
|
-
const result = (0,
|
|
45
|
+
const result = (0, common_1.throwIfError)(await (0, index_js_1.traverseDocument)(doc, context.description, {
|
|
45
46
|
getters: true,
|
|
46
47
|
fromProperties: true,
|
|
47
48
|
recurseReferences: true,
|
|
48
49
|
recurseDeep: true,
|
|
49
|
-
}))
|
|
50
|
+
}));
|
|
50
51
|
return types_1.Result.result(result);
|
|
51
52
|
};
|
|
52
53
|
const get = async (payload, context, options = {}) => {
|
package/dist/functions/get.mjs
CHANGED
|
@@ -6,13 +6,12 @@ import {
|
|
|
6
6
|
traverseDocument,
|
|
7
7
|
normalizeProjection,
|
|
8
8
|
getReferences,
|
|
9
|
-
buildLookupPipeline
|
|
10
|
-
fill
|
|
9
|
+
buildLookupPipeline
|
|
11
10
|
} from "../collection/index.mjs";
|
|
12
11
|
const internalGet = async (payload, context) => {
|
|
13
12
|
const {
|
|
14
13
|
filters = {},
|
|
15
|
-
project
|
|
14
|
+
project
|
|
16
15
|
} = payload;
|
|
17
16
|
if (Object.keys(filters).length === 0) {
|
|
18
17
|
return context.error(HTTPStatus.BadRequest, {
|
|
@@ -20,7 +19,7 @@ const internalGet = async (payload, context) => {
|
|
|
20
19
|
});
|
|
21
20
|
}
|
|
22
21
|
const pipeline = [];
|
|
23
|
-
const
|
|
22
|
+
const refMap = await getReferences(context.description.properties, {
|
|
24
23
|
memoize: context.description.$id
|
|
25
24
|
});
|
|
26
25
|
pipeline.push({
|
|
@@ -29,16 +28,17 @@ const internalGet = async (payload, context) => {
|
|
|
29
28
|
allowOperators: true
|
|
30
29
|
}))
|
|
31
30
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
if (project) {
|
|
32
|
+
const projection = normalizeProjection(project, context.description);
|
|
33
|
+
if (projection) {
|
|
34
|
+
pipeline.push({
|
|
35
|
+
$project: projection
|
|
36
|
+
});
|
|
37
|
+
}
|
|
37
38
|
}
|
|
38
|
-
pipeline.push(...
|
|
39
|
+
pipeline.push(...buildLookupPipeline(refMap, {
|
|
39
40
|
memoize: context.description.$id,
|
|
40
|
-
project: payload.populate ? payload.populate : project
|
|
41
|
-
properties: context.description.properties
|
|
41
|
+
project: payload.populate ? payload.populate : project
|
|
42
42
|
}));
|
|
43
43
|
const doc = await context.collection.model.aggregate(pipeline).next();
|
|
44
44
|
if (!doc) {
|
|
@@ -46,12 +46,12 @@ const internalGet = async (payload, context) => {
|
|
|
46
46
|
code: ACError.ResourceNotFound
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
|
-
const result =
|
|
49
|
+
const result = throwIfError(await traverseDocument(doc, context.description, {
|
|
50
50
|
getters: true,
|
|
51
51
|
fromProperties: true,
|
|
52
52
|
recurseReferences: true,
|
|
53
53
|
recurseDeep: true
|
|
54
|
-
}))
|
|
54
|
+
}));
|
|
55
55
|
return Result.result(result);
|
|
56
56
|
};
|
|
57
57
|
export const get = async (payload, context, options = {}) => {
|