vanta-api 1.2.5 → 1.2.7
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/package.json +1 -1
- package/src/api-features.js +21 -17
package/package.json
CHANGED
package/src/api-features.js
CHANGED
|
@@ -92,7 +92,6 @@ export class ApiFeatures {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
populate(input = "") {
|
|
95
|
-
// Build list from input and query.populate
|
|
96
95
|
let list = [];
|
|
97
96
|
const raw = Array.isArray(input) ? input : [input];
|
|
98
97
|
if (this.query.populate) raw.push(...this.query.populate.split(","));
|
|
@@ -102,14 +101,12 @@ export class ApiFeatures {
|
|
|
102
101
|
else if (item?.path) list.push(item);
|
|
103
102
|
});
|
|
104
103
|
|
|
105
|
-
// Deduplicate
|
|
106
104
|
const map = new Map();
|
|
107
105
|
list.forEach((opt) => {
|
|
108
106
|
const key = typeof opt === "string" ? opt : opt.path;
|
|
109
107
|
map.set(key, opt);
|
|
110
108
|
});
|
|
111
109
|
|
|
112
|
-
// Enforce role-based populate
|
|
113
110
|
const allowed =
|
|
114
111
|
securityConfig.accessLevels[this.userRole]?.allowedPopulate || [];
|
|
115
112
|
const final = [];
|
|
@@ -117,27 +114,31 @@ export class ApiFeatures {
|
|
|
117
114
|
if (allowed.includes("*") || allowed.includes(key)) final.push(opt);
|
|
118
115
|
});
|
|
119
116
|
|
|
120
|
-
// Apply lookups
|
|
121
117
|
for (const opt of final) {
|
|
122
118
|
const field = typeof opt === "string" ? opt : opt.path;
|
|
123
119
|
const proj =
|
|
124
120
|
typeof opt === "object" && opt.select
|
|
125
|
-
? opt.select.split(" ").reduce(
|
|
126
|
-
a
|
|
127
|
-
|
|
128
|
-
|
|
121
|
+
? opt.select.split(" ").reduce(
|
|
122
|
+
(a, f) => {
|
|
123
|
+
a[f] = 1;
|
|
124
|
+
return a;
|
|
125
|
+
},
|
|
126
|
+
{ _id: 1 }
|
|
127
|
+
)
|
|
129
128
|
: {};
|
|
130
129
|
|
|
131
|
-
const { collection } = this._getCollectionInfo(field);
|
|
130
|
+
const { collection, isArray } = this._getCollectionInfo(field);
|
|
131
|
+
|
|
132
|
+
const matchStage = isArray
|
|
133
|
+
? { $match: { $expr: { $in: ["$_id", "$$id"] } } }
|
|
134
|
+
: { $match: { $expr: { $eq: ["$_id", "$$id"] } } };
|
|
135
|
+
|
|
132
136
|
const lookup =
|
|
133
137
|
proj && Object.keys(proj).length
|
|
134
138
|
? {
|
|
135
139
|
from: collection,
|
|
136
140
|
let: { id: `$${field}` },
|
|
137
|
-
pipeline: [
|
|
138
|
-
{ $match: { $expr: { $eq: ["$_id", "$$id"] } } },
|
|
139
|
-
{ $project: proj },
|
|
140
|
-
],
|
|
141
|
+
pipeline: [matchStage, { $project: proj }],
|
|
141
142
|
as: field,
|
|
142
143
|
}
|
|
143
144
|
: {
|
|
@@ -148,9 +149,12 @@ export class ApiFeatures {
|
|
|
148
149
|
};
|
|
149
150
|
|
|
150
151
|
this.pipeline.push({ $lookup: lookup });
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
|
|
153
|
+
if (!isArray) {
|
|
154
|
+
this.pipeline.push({
|
|
155
|
+
$unwind: { path: `$${field}`, preserveNullAndEmptyArrays: true },
|
|
156
|
+
});
|
|
157
|
+
}
|
|
154
158
|
}
|
|
155
159
|
|
|
156
160
|
return this;
|
|
@@ -285,7 +289,7 @@ export class ApiFeatures {
|
|
|
285
289
|
resultObj[keyObj] = false;
|
|
286
290
|
return;
|
|
287
291
|
}
|
|
288
|
-
|
|
292
|
+
|
|
289
293
|
if (typeof val === "string" && /^[0-9]+$/.test(val)) {
|
|
290
294
|
resultObj[keyObj] = parseInt(val, 10);
|
|
291
295
|
return;
|