@web-ts-toolkit/access-router 0.52.0 → 0.53.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/README.md +175 -14
- package/advanced.d.mts +1 -4
- package/advanced.d.ts +1 -4
- package/advanced.js +81 -5
- package/advanced.mjs +81 -5
- package/index.d.mts +7 -4
- package/index.d.ts +7 -4
- package/index.js +840 -658
- package/index.mjs +436 -254
- package/llms.txt +4 -1
- package/package.json +3 -3
- package/{parsers-BnmChTfF.d.mts → parsers-ZSrF7SNu.d.mts} +71 -26
- package/{parsers-BnmChTfF.d.ts → parsers-ZSrF7SNu.d.ts} +71 -26
- package/processors.js +86 -47
- package/processors.mjs +49 -10
package/index.js
CHANGED
|
@@ -68,7 +68,38 @@ function assertPublicAdmission(input, kind = "envelope") {
|
|
|
68
68
|
for (const key of ["filter", "match", "data"]) add(record2[key], "data", key);
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
+
function assertHydrationDefaults(defaults) {
|
|
72
|
+
if (defaults && typeof defaults === "object") {
|
|
73
|
+
const record2 = defaults;
|
|
74
|
+
if ("hydration" in record2)
|
|
75
|
+
throw new TypeError("defaults.hydration is unsupported; use model hydration configuration");
|
|
76
|
+
for (const bucket of [
|
|
77
|
+
"publicListOptions",
|
|
78
|
+
"publicReadOptions",
|
|
79
|
+
"findOptions",
|
|
80
|
+
"findOneOptions",
|
|
81
|
+
"findByIdOptions",
|
|
82
|
+
"createOptions",
|
|
83
|
+
"updateOneOptions",
|
|
84
|
+
"updateByIdOptions",
|
|
85
|
+
"upsertOptions",
|
|
86
|
+
"existsOptions",
|
|
87
|
+
"publicCreateOptions",
|
|
88
|
+
"publicUpdateOptions"
|
|
89
|
+
]) {
|
|
90
|
+
const options = record2[bucket];
|
|
91
|
+
if (!options || typeof options !== "object" && typeof options !== "function") continue;
|
|
92
|
+
for (const key of ["lean", "hydration"]) {
|
|
93
|
+
if (!(key in options)) continue;
|
|
94
|
+
const method = bucket.slice(0, -"Options".length);
|
|
95
|
+
const migration = ["publicList", "publicRead", "find", "findOne", "findById"].includes(method) ? `use model hydration.${method} ('lean' or 'hydrated')` : "this method has a fixed fetch mode";
|
|
96
|
+
throw new TypeError(`defaults.${bucket}.${key} is unsupported; ${migration}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
71
101
|
function assertPublicDefaults(defaults) {
|
|
102
|
+
assertHydrationDefaults(defaults);
|
|
72
103
|
assertPublicAdmission(defaults);
|
|
73
104
|
if (defaults && typeof defaults === "object") {
|
|
74
105
|
for (const value of Object.values(defaults)) assertPublicAdmission(value);
|
|
@@ -134,21 +165,43 @@ var init_public_admission = __esm({
|
|
|
134
165
|
"includePermissions",
|
|
135
166
|
"includeFieldPermissions",
|
|
136
167
|
"includeCount",
|
|
137
|
-
"populateAccess"
|
|
138
|
-
"lean"
|
|
139
|
-
];
|
|
140
|
-
readOptions = [
|
|
141
|
-
"skim",
|
|
142
|
-
"includePermissions",
|
|
143
|
-
"includeFieldPermissions",
|
|
144
|
-
"tryList",
|
|
145
|
-
"populateAccess",
|
|
146
|
-
"lean"
|
|
168
|
+
"populateAccess"
|
|
147
169
|
];
|
|
170
|
+
readOptions = ["skim", "includePermissions", "includeFieldPermissions", "tryList", "populateAccess"];
|
|
148
171
|
requestAuthorization = Object.freeze({ outputFields: Object.freeze({ mode: "request" }) });
|
|
149
172
|
}
|
|
150
173
|
});
|
|
151
174
|
|
|
175
|
+
// src/options/hydration.ts
|
|
176
|
+
function normalizeHydration(value, path = "hydration") {
|
|
177
|
+
if (value === void 0) return void 0;
|
|
178
|
+
if (value === null || typeof value !== "object" || ![Object.prototype, null].includes(Object.getPrototypeOf(value)))
|
|
179
|
+
throw new TypeError(`${path} must be a plain record of model hydration modes`);
|
|
180
|
+
const result2 = {};
|
|
181
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
182
|
+
if (typeof key !== "string" || !methods.includes(key))
|
|
183
|
+
throw new TypeError(`${path}.${String(key)} is not a supported hydration method`);
|
|
184
|
+
const mode = value[key];
|
|
185
|
+
if (mode !== void 0 && mode !== "lean" && mode !== "hydrated")
|
|
186
|
+
throw new TypeError(`${path}.${key} must be 'lean', 'hydrated', or undefined`);
|
|
187
|
+
result2[key] = mode;
|
|
188
|
+
}
|
|
189
|
+
return Object.freeze(result2);
|
|
190
|
+
}
|
|
191
|
+
function normalizeHydrationUpdate(current, key, value) {
|
|
192
|
+
if (key === "hydration") return normalizeHydration(value);
|
|
193
|
+
const method = key.slice("hydration.".length);
|
|
194
|
+
if (!methods.includes(method))
|
|
195
|
+
throw new TypeError(`${key} is not a supported hydration method`);
|
|
196
|
+
return normalizeHydration({ ...normalizeHydration(current), [method]: value });
|
|
197
|
+
}
|
|
198
|
+
var methods;
|
|
199
|
+
var init_hydration = __esm({
|
|
200
|
+
"src/options/hydration.ts"() {
|
|
201
|
+
methods = ["publicList", "publicRead", "find", "findOne", "findById"];
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
|
|
152
205
|
// src/helpers/collection.ts
|
|
153
206
|
var import_sift, import_utils2, filterCollection, findElement, findElementById;
|
|
154
207
|
var init_collection = __esm({
|
|
@@ -278,6 +331,50 @@ var init_concurrency = __esm({
|
|
|
278
331
|
}
|
|
279
332
|
});
|
|
280
333
|
|
|
334
|
+
// src/output/permissions-alias.ts
|
|
335
|
+
function attachPermissionsAlias(output, field) {
|
|
336
|
+
if ("permissions" in output) return;
|
|
337
|
+
const metadata = (0, import_utils3.get)(output, field);
|
|
338
|
+
if (metadata === void 0) return;
|
|
339
|
+
Object.defineProperty(output, "permissions", {
|
|
340
|
+
value: metadata,
|
|
341
|
+
enumerable: false,
|
|
342
|
+
writable: true,
|
|
343
|
+
configurable: true
|
|
344
|
+
});
|
|
345
|
+
aliases.set(output, field);
|
|
346
|
+
}
|
|
347
|
+
function removeGeneratedPermissionsAlias(output) {
|
|
348
|
+
const field = aliases.get(output);
|
|
349
|
+
if (field && Object.getOwnPropertyDescriptor(output, "permissions")?.value === (0, import_utils3.get)(output, field)) {
|
|
350
|
+
delete output.permissions;
|
|
351
|
+
}
|
|
352
|
+
aliases.delete(output);
|
|
353
|
+
}
|
|
354
|
+
function copyPermissionsAlias(source, target) {
|
|
355
|
+
if (source && typeof source === "object" && target && typeof target === "object") {
|
|
356
|
+
const field = aliases.get(source);
|
|
357
|
+
if (field && Object.getOwnPropertyDescriptor(source, "permissions")?.value === (0, import_utils3.get)(source, field))
|
|
358
|
+
attachPermissionsAlias(target, field);
|
|
359
|
+
}
|
|
360
|
+
return target;
|
|
361
|
+
}
|
|
362
|
+
function copyPermissionsAliasGraph(source, target, seen = /* @__PURE__ */ new WeakSet()) {
|
|
363
|
+
if (!source || !target || typeof source !== "object" || typeof target !== "object" || seen.has(target)) return;
|
|
364
|
+
seen.add(target);
|
|
365
|
+
copyPermissionsAlias(source, target);
|
|
366
|
+
for (const key of Object.keys(target)) {
|
|
367
|
+
copyPermissionsAliasGraph(source[key], target[key], seen);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
var import_utils3, aliases;
|
|
371
|
+
var init_permissions_alias = __esm({
|
|
372
|
+
"src/output/permissions-alias.ts"() {
|
|
373
|
+
import_utils3 = require("@web-ts-toolkit/utils");
|
|
374
|
+
aliases = /* @__PURE__ */ new WeakMap();
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
|
|
281
378
|
// src/helpers/query.ts
|
|
282
379
|
function genPagination({
|
|
283
380
|
skip,
|
|
@@ -312,9 +409,9 @@ function parseSelectParam(select) {
|
|
|
312
409
|
return fields.length > 0 ? fields : void 0;
|
|
313
410
|
}
|
|
314
411
|
function normalizeSelect(select) {
|
|
315
|
-
if (Array.isArray(select)) return (0,
|
|
316
|
-
if ((0,
|
|
317
|
-
return (0,
|
|
412
|
+
if (Array.isArray(select)) return (0, import_utils4.flattenDeep)(select.map(normalizeSelect));
|
|
413
|
+
if ((0, import_utils4.isPlainObject)(select)) {
|
|
414
|
+
return (0, import_utils4.reduce)(
|
|
318
415
|
select,
|
|
319
416
|
(ret, val, key) => {
|
|
320
417
|
if (val === 1) ret.push(key);
|
|
@@ -324,17 +421,17 @@ function normalizeSelect(select) {
|
|
|
324
421
|
[]
|
|
325
422
|
);
|
|
326
423
|
}
|
|
327
|
-
if ((0,
|
|
424
|
+
if ((0, import_utils4.isString)(select))
|
|
328
425
|
return String(select).split(/[\s,]+/).map((v) => v.trim()).filter(Boolean);
|
|
329
426
|
return [];
|
|
330
427
|
}
|
|
331
|
-
var
|
|
428
|
+
var import_utils4, DEFAULT_LIST_HARD_LIMIT, normalizeSafeInteger;
|
|
332
429
|
var init_query = __esm({
|
|
333
430
|
"src/helpers/query.ts"() {
|
|
334
|
-
|
|
431
|
+
import_utils4 = require("@web-ts-toolkit/utils");
|
|
335
432
|
DEFAULT_LIST_HARD_LIMIT = 1e3;
|
|
336
433
|
normalizeSafeInteger = (value, min) => {
|
|
337
|
-
if ((0,
|
|
434
|
+
if ((0, import_utils4.isNil)(value)) return null;
|
|
338
435
|
const parsed = Number(value);
|
|
339
436
|
if (!Number.isSafeInteger(parsed) || parsed < min) return null;
|
|
340
437
|
return parsed;
|
|
@@ -348,57 +445,49 @@ function isDocument(doc) {
|
|
|
348
445
|
}
|
|
349
446
|
function getDocValue(doc, path, defaultValue) {
|
|
350
447
|
if (isDocument(doc)) {
|
|
351
|
-
return (0,
|
|
352
|
-
} else if ((0,
|
|
353
|
-
return (0,
|
|
448
|
+
return (0, import_utils5.get)(doc._doc, path, defaultValue);
|
|
449
|
+
} else if ((0, import_utils5.isPlainObject)(doc)) {
|
|
450
|
+
return (0, import_utils5.get)(doc, path, defaultValue);
|
|
354
451
|
}
|
|
355
452
|
}
|
|
356
453
|
function setDocValue(doc, path, value) {
|
|
357
454
|
if (isDocument(doc)) {
|
|
358
|
-
(0,
|
|
359
|
-
} else if ((0,
|
|
360
|
-
(0,
|
|
455
|
+
(0, import_utils5.set)(doc._doc, path, value);
|
|
456
|
+
} else if ((0, import_utils5.isPlainObject)(doc)) {
|
|
457
|
+
(0, import_utils5.set)(doc, path, value);
|
|
361
458
|
}
|
|
362
459
|
}
|
|
363
460
|
function getDocPermissions(modelName, doc) {
|
|
364
461
|
const docPermissionField = getModelOption(modelName, "documentPermissionField");
|
|
365
462
|
const permissions = getDocValue(doc, docPermissionField, {});
|
|
366
|
-
return (0,
|
|
367
|
-
}
|
|
368
|
-
function stripUnexposedDocPermissions(modelName, doc) {
|
|
369
|
-
const exposed = getModelOption(modelName, "exposedDocPermissionKeys");
|
|
370
|
-
if (exposed === void 0) return;
|
|
371
|
-
const docPermissionField = getModelOption(modelName, "documentPermissionField");
|
|
372
|
-
const current = getDocValue(doc, docPermissionField, void 0);
|
|
373
|
-
if (!(0, import_utils4.isPlainObject)(current)) return;
|
|
374
|
-
const keep = /* @__PURE__ */ new Set(["_view", "_edit", ...exposed]);
|
|
375
|
-
setDocValue(doc, docPermissionField, Object.fromEntries(Object.entries(current).filter(([key]) => keep.has(key))));
|
|
463
|
+
return (0, import_utils5.isPlainObject)(permissions) ? permissions : {};
|
|
376
464
|
}
|
|
377
465
|
function toObject(doc) {
|
|
378
466
|
return isDocument(doc) ? doc.toObject() : doc;
|
|
379
467
|
}
|
|
380
468
|
function pickDocFields(doc, fields = []) {
|
|
381
469
|
if (isDocument(doc)) {
|
|
382
|
-
doc._doc = (0,
|
|
470
|
+
doc._doc = (0, import_utils5.pick)(doc._doc, fields);
|
|
383
471
|
return doc;
|
|
384
472
|
} else {
|
|
385
|
-
return (0,
|
|
473
|
+
return (0, import_utils5.pick)(doc, fields);
|
|
386
474
|
}
|
|
387
475
|
}
|
|
388
476
|
async function populateDoc(doc, target) {
|
|
389
477
|
let p = doc.populate(target);
|
|
390
|
-
if ((0,
|
|
478
|
+
if ((0, import_utils6.isPromise)(p)) return p;
|
|
391
479
|
return "execPopulate" in p && p.execPopulate?.();
|
|
392
480
|
}
|
|
393
|
-
var import_mongoose,
|
|
481
|
+
var import_mongoose, import_utils5, import_utils6, isMongooseDocument, cloneIsolatedLeaf, deepIsolateValue, isolateDocForOutput, retainedAssociations, retainRawAssociation, getRetainedAssociations, normalizeSubPopulate, genSubPopulate;
|
|
394
482
|
var init_document = __esm({
|
|
395
483
|
"src/helpers/document.ts"() {
|
|
396
484
|
import_mongoose = require("mongoose");
|
|
485
|
+
init_permissions_alias();
|
|
397
486
|
init_public_admission();
|
|
398
|
-
|
|
487
|
+
import_utils5 = require("@web-ts-toolkit/utils");
|
|
399
488
|
init_options();
|
|
400
489
|
init_query();
|
|
401
|
-
|
|
490
|
+
import_utils6 = require("@web-ts-toolkit/utils");
|
|
402
491
|
isMongooseDocument = (doc) => isDocument(doc);
|
|
403
492
|
cloneIsolatedLeaf = (value) => {
|
|
404
493
|
if (value === null || value === void 0) return value;
|
|
@@ -486,7 +575,7 @@ var init_document = __esm({
|
|
|
486
575
|
for (const [key, entry] of value) out.set(deepIsolateValue(key, seen), deepIsolateValue(entry, seen));
|
|
487
576
|
return out;
|
|
488
577
|
}
|
|
489
|
-
if ((0,
|
|
578
|
+
if ((0, import_utils5.isPlainObject)(value)) {
|
|
490
579
|
if (seen.has(value)) return seen.get(value);
|
|
491
580
|
const out = {};
|
|
492
581
|
seen.set(value, out);
|
|
@@ -498,6 +587,7 @@ var init_document = __esm({
|
|
|
498
587
|
configurable: true
|
|
499
588
|
});
|
|
500
589
|
}
|
|
590
|
+
copyPermissionsAlias(value, out);
|
|
501
591
|
return out;
|
|
502
592
|
}
|
|
503
593
|
return value;
|
|
@@ -532,13 +622,13 @@ var init_document = __esm({
|
|
|
532
622
|
const entry = retainedAssociations.get(output);
|
|
533
623
|
return entry ? { ...entry } : void 0;
|
|
534
624
|
};
|
|
535
|
-
normalizeSubPopulate = (populate) => (0,
|
|
625
|
+
normalizeSubPopulate = (populate) => (0, import_utils6.isArray)(populate) ? populate.map((item) => (0, import_utils6.isString)(item) ? { path: item } : item) : (0, import_utils6.isString)(populate) ? { path: populate } : populate ?? [];
|
|
536
626
|
genSubPopulate = (sub, popul) => {
|
|
537
627
|
assertPublicAdmission(popul, "populate");
|
|
538
628
|
if (!popul) return [];
|
|
539
|
-
let populate = (0,
|
|
629
|
+
let populate = (0, import_utils6.isArray)(popul) ? popul : [popul];
|
|
540
630
|
populate = populate.map((p) => {
|
|
541
|
-
const ret = (0,
|
|
631
|
+
const ret = (0, import_utils6.isString)(p) ? { path: `${sub}.${p}` } : {
|
|
542
632
|
path: `${sub}.${p.path}`,
|
|
543
633
|
select: normalizeSelect(p.select)
|
|
544
634
|
};
|
|
@@ -718,14 +808,14 @@ var init_sort_policy = __esm({
|
|
|
718
808
|
});
|
|
719
809
|
|
|
720
810
|
// src/lib.ts
|
|
721
|
-
var import_mongoose2,
|
|
811
|
+
var import_mongoose2, import_utils7, isSchema, isObjectIdType, isReference, isDocument2;
|
|
722
812
|
var init_lib = __esm({
|
|
723
813
|
"src/lib.ts"() {
|
|
724
814
|
import_mongoose2 = require("mongoose");
|
|
725
|
-
|
|
815
|
+
import_utils7 = require("@web-ts-toolkit/utils");
|
|
726
816
|
isSchema = (val) => val instanceof import_mongoose2.Schema;
|
|
727
817
|
isObjectIdType = (val) => val === "ObjectId" || val === import_mongoose2.Schema.Types.ObjectId;
|
|
728
|
-
isReference = (val) => (0,
|
|
818
|
+
isReference = (val) => (0, import_utils7.isPlainObject)(val) && !!val.ref && isObjectIdType(val.type);
|
|
729
819
|
isDocument2 = function isDocument3(doc) {
|
|
730
820
|
return doc instanceof import_mongoose2.Document;
|
|
731
821
|
};
|
|
@@ -737,30 +827,30 @@ function recurseObject(obj) {
|
|
|
737
827
|
if (isSchema(obj)) {
|
|
738
828
|
return buildRefs(obj.tree);
|
|
739
829
|
}
|
|
740
|
-
if (!(0,
|
|
830
|
+
if (!(0, import_utils8.isObject)(obj)) return null;
|
|
741
831
|
if (isReference(obj)) {
|
|
742
832
|
return obj.ref;
|
|
743
833
|
}
|
|
744
834
|
let ret = null;
|
|
745
|
-
(0,
|
|
835
|
+
(0, import_utils8.forEach)(obj, (val) => {
|
|
746
836
|
ret = recurseObject(val);
|
|
747
|
-
if (!(0,
|
|
837
|
+
if (!(0, import_utils8.isEmpty)(ret)) {
|
|
748
838
|
return false;
|
|
749
839
|
}
|
|
750
840
|
});
|
|
751
841
|
return ret;
|
|
752
842
|
}
|
|
753
843
|
function buildRefs(schema) {
|
|
754
|
-
if (!(0,
|
|
844
|
+
if (!(0, import_utils8.isObject)(schema)) return {};
|
|
755
845
|
const references = {};
|
|
756
|
-
(0,
|
|
846
|
+
(0, import_utils8.forEach)(schema, (val, key) => {
|
|
757
847
|
const paths = recurseObject(val);
|
|
758
|
-
if (!(0,
|
|
848
|
+
if (!(0, import_utils8.isEmpty)(paths)) {
|
|
759
849
|
references[key] = paths;
|
|
760
850
|
}
|
|
761
|
-
const target = (0,
|
|
762
|
-
if ((0,
|
|
763
|
-
if (isSchema(target[0]) || (0,
|
|
851
|
+
const target = (0, import_utils8.isObject)(val) && "type" in val ? val.type ?? val : val;
|
|
852
|
+
if ((0, import_utils8.isArray)(target) && target.length > 0) {
|
|
853
|
+
if (isSchema(target[0]) || (0, import_utils8.isPlainObject)(target[0])) {
|
|
764
854
|
return;
|
|
765
855
|
}
|
|
766
856
|
}
|
|
@@ -768,12 +858,12 @@ function buildRefs(schema) {
|
|
|
768
858
|
return references;
|
|
769
859
|
}
|
|
770
860
|
function buildSubPaths(schema) {
|
|
771
|
-
if (!(0,
|
|
861
|
+
if (!(0, import_utils8.isObject)(schema)) return [];
|
|
772
862
|
const subPaths = [];
|
|
773
|
-
(0,
|
|
774
|
-
const target = (0,
|
|
775
|
-
if ((0,
|
|
776
|
-
if (isSchema(target[0]) || (0,
|
|
863
|
+
(0, import_utils8.forEach)(schema, (val, key) => {
|
|
864
|
+
const target = (0, import_utils8.isObject)(val) && "type" in val ? val.type ?? val : val;
|
|
865
|
+
if ((0, import_utils8.isArray)(target) && target.length > 0) {
|
|
866
|
+
if (isSchema(target[0]) || (0, import_utils8.isPlainObject)(target[0]) && !isReference(target[0])) {
|
|
777
867
|
subPaths.push(key);
|
|
778
868
|
}
|
|
779
869
|
}
|
|
@@ -781,12 +871,12 @@ function buildSubPaths(schema) {
|
|
|
781
871
|
return subPaths;
|
|
782
872
|
}
|
|
783
873
|
async function iterateQuery(query, handler, scheduler, scheduled = false) {
|
|
784
|
-
if (!(0,
|
|
874
|
+
if (!(0, import_utils8.isPlainObject)(query)) return query;
|
|
785
875
|
if (!handler) return query;
|
|
786
876
|
const queryObject = query;
|
|
787
877
|
const entries = Object.entries(queryObject);
|
|
788
878
|
const mapEntry = async ([key, val]) => {
|
|
789
|
-
if ((0,
|
|
879
|
+
if ((0, import_utils8.isPlainObject)(val)) {
|
|
790
880
|
const plainValue = val;
|
|
791
881
|
if (plainValue.$$sq) {
|
|
792
882
|
return scheduled || !scheduler ? handler(0 /* SubQuery */, plainValue.$$sq, key) : scheduler.run(() => Promise.resolve(handler(0 /* SubQuery */, plainValue.$$sq, key)));
|
|
@@ -796,7 +886,7 @@ async function iterateQuery(query, handler, scheduler, scheduled = false) {
|
|
|
796
886
|
return iterateQuery(val, handler, scheduler, scheduled);
|
|
797
887
|
}
|
|
798
888
|
}
|
|
799
|
-
if ((0,
|
|
889
|
+
if ((0, import_utils8.isArray)(val)) {
|
|
800
890
|
const items = val;
|
|
801
891
|
if (scheduler && !scheduled) {
|
|
802
892
|
return scheduler.map(items, (v) => iterateQuery(v, handler, scheduler, true));
|
|
@@ -808,7 +898,7 @@ async function iterateQuery(query, handler, scheduler, scheduled = false) {
|
|
|
808
898
|
const values = scheduler && !scheduled ? await scheduler.map(entries, mapEntry) : await Promise.all(entries.map(mapEntry));
|
|
809
899
|
return Object.fromEntries(entries.map(([key], index) => [key, values[index]]));
|
|
810
900
|
}
|
|
811
|
-
var
|
|
901
|
+
var import_utils8, createValidator;
|
|
812
902
|
var init_helpers = __esm({
|
|
813
903
|
"src/helpers/index.ts"() {
|
|
814
904
|
init_collection();
|
|
@@ -817,13 +907,13 @@ var init_helpers = __esm({
|
|
|
817
907
|
init_errors();
|
|
818
908
|
init_query();
|
|
819
909
|
init_sort_policy();
|
|
820
|
-
|
|
910
|
+
import_utils8 = require("@web-ts-toolkit/utils");
|
|
821
911
|
init_lib();
|
|
822
912
|
createValidator = (fn) => {
|
|
823
913
|
const stringHandler = (key) => key.trim().split(" ").every((v) => fn(v));
|
|
824
914
|
const arrayHandler = (arr) => arr.some((item) => {
|
|
825
|
-
if ((0,
|
|
826
|
-
else if ((0,
|
|
915
|
+
if ((0, import_utils8.isString)(item)) return stringHandler(item);
|
|
916
|
+
else if ((0, import_utils8.isArray)(item)) return arrayHandler(item);
|
|
827
917
|
else return false;
|
|
828
918
|
});
|
|
829
919
|
return { stringHandler, arrayHandler };
|
|
@@ -918,25 +1008,25 @@ function defineOpenApiSchemaResolver(resolve) {
|
|
|
918
1008
|
};
|
|
919
1009
|
}
|
|
920
1010
|
function getNestedOpenApiSchemaDataSource(source) {
|
|
921
|
-
return (0,
|
|
1011
|
+
return (0, import_utils9.isPlainObject)(source) && "data" in source ? source.data : void 0;
|
|
922
1012
|
}
|
|
923
1013
|
function unwrapNestedOpenApiSchemaSource(source, fallback) {
|
|
924
|
-
if ((0,
|
|
1014
|
+
if ((0, import_utils9.isPlainObject)(source) && ("default" in source || "data" in source)) {
|
|
925
1015
|
return source.default ?? fallback;
|
|
926
1016
|
}
|
|
927
1017
|
return source ?? fallback;
|
|
928
1018
|
}
|
|
929
1019
|
function isOpenApiSchemaPatch(source) {
|
|
930
|
-
return (0,
|
|
1020
|
+
return (0, import_utils9.isPlainObject)(source) && source.kind === "objectProperties";
|
|
931
1021
|
}
|
|
932
1022
|
function isOpenApiSchemaResolver(source) {
|
|
933
|
-
return (0,
|
|
1023
|
+
return (0, import_utils9.isPlainObject)(source) && source.kind === "schemaResolver" && typeof source.resolve === "function";
|
|
934
1024
|
}
|
|
935
1025
|
function isJsonSchemaLike(source) {
|
|
936
|
-
return (0,
|
|
1026
|
+
return (0, import_utils9.isPlainObject)(source) && ("type" in source || "properties" in source || "$ref" in source || "anyOf" in source);
|
|
937
1027
|
}
|
|
938
1028
|
function hasOpenApiSchema(source) {
|
|
939
|
-
return (0,
|
|
1029
|
+
return (0, import_utils9.isPlainObject)(source) && isJsonSchemaLike(source.openapi);
|
|
940
1030
|
}
|
|
941
1031
|
function toOpenApiSchema(source) {
|
|
942
1032
|
if (!source) return void 0;
|
|
@@ -944,7 +1034,7 @@ function toOpenApiSchema(source) {
|
|
|
944
1034
|
if (!resolvedSource) return void 0;
|
|
945
1035
|
if (isOpenApiSchemaPatch(resolvedSource)) {
|
|
946
1036
|
const schema = toOpenApiSchema(resolvedSource.source) ?? { ...fallbackObjectSchema };
|
|
947
|
-
const properties = (0,
|
|
1037
|
+
const properties = (0, import_utils9.isPlainObject)(schema.properties) ? { ...schema.properties } : {};
|
|
948
1038
|
for (const [key, value] of Object.entries(resolvedSource.properties)) {
|
|
949
1039
|
properties[key] = toOpenApiSchema(value) ?? fallbackObjectSchema;
|
|
950
1040
|
}
|
|
@@ -966,11 +1056,11 @@ function toOpenApiSchema(source) {
|
|
|
966
1056
|
return fallbackObjectSchema;
|
|
967
1057
|
}
|
|
968
1058
|
}
|
|
969
|
-
var import_zod,
|
|
1059
|
+
var import_zod, import_utils9, fallbackObjectSchema;
|
|
970
1060
|
var init_schemas = __esm({
|
|
971
1061
|
"src/openapi/schemas.ts"() {
|
|
972
1062
|
import_zod = require("zod");
|
|
973
|
-
|
|
1063
|
+
import_utils9 = require("@web-ts-toolkit/utils");
|
|
974
1064
|
fallbackObjectSchema = { type: "object", additionalProperties: true };
|
|
975
1065
|
}
|
|
976
1066
|
});
|
|
@@ -993,10 +1083,10 @@ function buildOpenApiSpec(routes, options) {
|
|
|
993
1083
|
paths
|
|
994
1084
|
};
|
|
995
1085
|
}
|
|
996
|
-
var
|
|
1086
|
+
var import_utils10, openApiMediaType, normalizePath, toOpenApiPath, schemaToQueryParameters, schemaToPathParameters, getDefaultResponses, buildOperation;
|
|
997
1087
|
var init_build_spec = __esm({
|
|
998
1088
|
"src/openapi/build-spec.ts"() {
|
|
999
|
-
|
|
1089
|
+
import_utils10 = require("@web-ts-toolkit/utils");
|
|
1000
1090
|
init_responses();
|
|
1001
1091
|
init_schemas();
|
|
1002
1092
|
openApiMediaType = "application/json";
|
|
@@ -1008,9 +1098,9 @@ var init_build_spec = __esm({
|
|
|
1008
1098
|
schemaToQueryParameters = (schema) => {
|
|
1009
1099
|
const jsonSchema = toOpenApiSchema(schema);
|
|
1010
1100
|
if (!jsonSchema || jsonSchema.type !== "object") return [];
|
|
1011
|
-
const properties = (0,
|
|
1101
|
+
const properties = (0, import_utils10.isPlainObject)(jsonSchema.properties) ? jsonSchema.properties : {};
|
|
1012
1102
|
const required = new Set(
|
|
1013
|
-
(0,
|
|
1103
|
+
(0, import_utils10.isArray)(jsonSchema.required) ? jsonSchema.required.filter((item) => typeof item === "string") : []
|
|
1014
1104
|
);
|
|
1015
1105
|
return Object.entries(properties).map(([name, value]) => ({
|
|
1016
1106
|
name,
|
|
@@ -1227,10 +1317,10 @@ var init_logger_default = __esm({
|
|
|
1227
1317
|
});
|
|
1228
1318
|
|
|
1229
1319
|
// src/options/manager.ts
|
|
1230
|
-
var
|
|
1320
|
+
var import_utils11, toPath, cloneConfigValue, cloneForRead, freezeConfigValue, cloneAndFreezeForStore, getNestedOption, resolveNestedOption, OptionsManager;
|
|
1231
1321
|
var init_manager = __esm({
|
|
1232
1322
|
"src/options/manager.ts"() {
|
|
1233
|
-
|
|
1323
|
+
import_utils11 = require("@web-ts-toolkit/utils");
|
|
1234
1324
|
toPath = (key) => {
|
|
1235
1325
|
if (Array.isArray(key)) return key;
|
|
1236
1326
|
return typeof key === "string" ? key.split(".") : [key];
|
|
@@ -1337,20 +1427,20 @@ var init_manager = __esm({
|
|
|
1337
1427
|
return this;
|
|
1338
1428
|
}
|
|
1339
1429
|
get(key, defaultValue) {
|
|
1340
|
-
return (0,
|
|
1430
|
+
return (0, import_utils11.get)(this.currentOptions, key, defaultValue);
|
|
1341
1431
|
}
|
|
1342
1432
|
set(key, value) {
|
|
1343
1433
|
const path = toPath(key);
|
|
1344
1434
|
if (path.length <= 1) {
|
|
1345
|
-
(0,
|
|
1435
|
+
(0, import_utils11.set)(this.currentOptions, path, this.preserveKeys.has(String(path[0])) ? value : cloneAndFreezeForStore(value));
|
|
1346
1436
|
return;
|
|
1347
1437
|
}
|
|
1348
1438
|
const [rootKey, ...nestedPath] = path;
|
|
1349
|
-
const currentRoot = (0,
|
|
1350
|
-
const baseRoot = (0,
|
|
1439
|
+
const currentRoot = (0, import_utils11.get)(this.currentOptions, [rootKey], void 0);
|
|
1440
|
+
const baseRoot = (0, import_utils11.isPlainObject)(currentRoot) ? currentRoot : {};
|
|
1351
1441
|
const nextRoot = cloneConfigValue(baseRoot);
|
|
1352
|
-
(0,
|
|
1353
|
-
(0,
|
|
1442
|
+
(0, import_utils11.set)(nextRoot, nestedPath, cloneForRead(value));
|
|
1443
|
+
(0, import_utils11.set)(this.currentOptions, [rootKey], freezeConfigValue(nextRoot));
|
|
1354
1444
|
}
|
|
1355
1445
|
fetch() {
|
|
1356
1446
|
const cloned = cloneForRead(this.currentOptions);
|
|
@@ -1368,10 +1458,10 @@ var init_manager = __esm({
|
|
|
1368
1458
|
cloned[key] = options[key];
|
|
1369
1459
|
}
|
|
1370
1460
|
}
|
|
1371
|
-
(0,
|
|
1461
|
+
(0, import_utils11.assign)(this.currentOptions, freezeConfigValue(cloned));
|
|
1372
1462
|
}
|
|
1373
1463
|
onchange(key, func) {
|
|
1374
|
-
(0,
|
|
1464
|
+
(0, import_utils11.set)(this.listeners, key, func);
|
|
1375
1465
|
return this;
|
|
1376
1466
|
}
|
|
1377
1467
|
snapshot() {
|
|
@@ -1397,7 +1487,7 @@ var init_manager = __esm({
|
|
|
1397
1487
|
cloned[key] = snap[key];
|
|
1398
1488
|
}
|
|
1399
1489
|
}
|
|
1400
|
-
(0,
|
|
1490
|
+
(0, import_utils11.assign)(current, freezeConfigValue(cloned));
|
|
1401
1491
|
}
|
|
1402
1492
|
};
|
|
1403
1493
|
}
|
|
@@ -1597,10 +1687,10 @@ var init_data_values = __esm({
|
|
|
1597
1687
|
});
|
|
1598
1688
|
|
|
1599
1689
|
// src/options/data-manager.ts
|
|
1600
|
-
var
|
|
1690
|
+
var import_utils12, admitData, DataOptionsManager;
|
|
1601
1691
|
var init_data_manager = __esm({
|
|
1602
1692
|
"src/options/data-manager.ts"() {
|
|
1603
|
-
|
|
1693
|
+
import_utils12 = require("@web-ts-toolkit/utils");
|
|
1604
1694
|
init_manager();
|
|
1605
1695
|
init_data_values();
|
|
1606
1696
|
admitData = (options) => {
|
|
@@ -1618,7 +1708,7 @@ var init_data_manager = __esm({
|
|
|
1618
1708
|
super.set("data", createDataSnapshot(value));
|
|
1619
1709
|
} else if (path.startsWith("data.")) {
|
|
1620
1710
|
const next = copyDataValue(getOwnedDataSnapshot(super.get("data")));
|
|
1621
|
-
(0,
|
|
1711
|
+
(0, import_utils12.set)(next, path.slice("data.".length), value);
|
|
1622
1712
|
super.set("data", createDataSnapshot(next));
|
|
1623
1713
|
} else {
|
|
1624
1714
|
super.set(key, value);
|
|
@@ -1656,7 +1746,7 @@ function validateRequestComplexity(value, options, scope2 = "request") {
|
|
|
1656
1746
|
pushError(`Request exceeds maximum depth of ${limits.maxDepth}`, path);
|
|
1657
1747
|
return;
|
|
1658
1748
|
}
|
|
1659
|
-
if ((0,
|
|
1749
|
+
if ((0, import_utils13.isArray)(current)) {
|
|
1660
1750
|
if (parentKey === "$and" || parentKey === "$or" || parentKey === "$nor") {
|
|
1661
1751
|
logicalClauses += current.length;
|
|
1662
1752
|
if (logicalClauses > limits.maxLogicalClauses) {
|
|
@@ -1676,14 +1766,14 @@ function validateRequestComplexity(value, options, scope2 = "request") {
|
|
|
1676
1766
|
}
|
|
1677
1767
|
return;
|
|
1678
1768
|
}
|
|
1679
|
-
if (!(0,
|
|
1769
|
+
if (!(0, import_utils13.isPlainObject)(current)) return;
|
|
1680
1770
|
for (const [key, child] of Object.entries(current)) {
|
|
1681
1771
|
if (key === "__proto__" || key === "prototype" || key === "constructor") {
|
|
1682
1772
|
pushError(`Unsupported key: ${key}`, path.concat(key));
|
|
1683
1773
|
return;
|
|
1684
1774
|
}
|
|
1685
1775
|
if (scope2 === "request" && key === "include") {
|
|
1686
|
-
includeCount += (0,
|
|
1776
|
+
includeCount += (0, import_utils13.isArray)(child) ? child.length : 1;
|
|
1687
1777
|
if (includeCount > limits.maxIncludeCount) {
|
|
1688
1778
|
pushError(`Request exceeds maximum include count of ${limits.maxIncludeCount}`, path.concat(key));
|
|
1689
1779
|
return;
|
|
@@ -1706,10 +1796,10 @@ function validateRequestComplexity(value, options, scope2 = "request") {
|
|
|
1706
1796
|
visit(value, [], 0);
|
|
1707
1797
|
return errors;
|
|
1708
1798
|
}
|
|
1709
|
-
var
|
|
1799
|
+
var import_utils13, defaultRequestComplexity, normalizePositiveInteger, resolveRequestComplexity;
|
|
1710
1800
|
var init_request_complexity = __esm({
|
|
1711
1801
|
"src/request-complexity.ts"() {
|
|
1712
|
-
|
|
1802
|
+
import_utils13 = require("@web-ts-toolkit/utils");
|
|
1713
1803
|
defaultRequestComplexity = {
|
|
1714
1804
|
maxDepth: 8,
|
|
1715
1805
|
maxNodes: 500,
|
|
@@ -1755,13 +1845,14 @@ var init_request_complexity = __esm({
|
|
|
1755
1845
|
});
|
|
1756
1846
|
|
|
1757
1847
|
// src/runtime.ts
|
|
1758
|
-
var import_mongoose3, import_mongoose_schema_jsonschema,
|
|
1848
|
+
var import_mongoose3, import_mongoose_schema_jsonschema, import_utils14, mongooseJsonSchemaInitialized, ensureMongooseJsonSchemaInitialized, pluralize, FIELD_ACCESS_KEYS, defaultModelOptions, defaultDataOptions, normalizeBasePath, hasModelPermission, classifyPermissionSchema, refreshPermissionMetadata, VIRTUAL_SUPPORTED_ACCESSES, VIRTUAL_UNSUPPORTED_ACCESSES, VIRTUAL_RESERVED_NAMES, VIRTUAL_DANGEROUS_SEGMENTS, VIRTUAL_NAME_PATTERN, isVirtualContainerValue, virtualFullPath, virtualPathsOverlap, collectStoredTopLevel, getChildSchemaForField, getNestedChildFields, cloneVirtualsForValidation, validateVirtualDependsOn, validateVirtualLeafValue, validateVirtualsScope, validateVirtualsTree, getScopeVirtualsObject, toVirtualDescriptor, AccessRuntime, defaultRuntime;
|
|
1759
1849
|
var init_runtime = __esm({
|
|
1760
1850
|
"src/runtime.ts"() {
|
|
1761
1851
|
import_mongoose3 = __toESM(require("mongoose"));
|
|
1762
1852
|
init_public_admission();
|
|
1853
|
+
init_hydration();
|
|
1763
1854
|
import_mongoose_schema_jsonschema = __toESM(require("mongoose-schema-jsonschema"));
|
|
1764
|
-
|
|
1855
|
+
import_utils14 = require("@web-ts-toolkit/utils");
|
|
1765
1856
|
init_helpers();
|
|
1766
1857
|
init_registry();
|
|
1767
1858
|
init_logger_default();
|
|
@@ -1788,44 +1879,44 @@ var init_runtime = __esm({
|
|
|
1788
1879
|
listHardLimit: DEFAULT_LIST_HARD_LIMIT
|
|
1789
1880
|
};
|
|
1790
1881
|
normalizeBasePath = (name, value) => {
|
|
1791
|
-
if ((0,
|
|
1882
|
+
if ((0, import_utils14.isNil)(value)) {
|
|
1792
1883
|
return `/${pluralize(name)}`;
|
|
1793
1884
|
}
|
|
1794
|
-
return (0,
|
|
1885
|
+
return (0, import_utils14.isString)(value) ? (0, import_utils14.addLeadingSlash)(value) : "";
|
|
1795
1886
|
};
|
|
1796
1887
|
hasModelPermission = (value, modelPermissionPrefix) => {
|
|
1797
1888
|
if (!modelPermissionPrefix) {
|
|
1798
1889
|
return true;
|
|
1799
1890
|
}
|
|
1800
|
-
if ((0,
|
|
1891
|
+
if ((0, import_utils14.isString)(value)) {
|
|
1801
1892
|
return value.trim().split(" ").some((item) => item.startsWith(modelPermissionPrefix));
|
|
1802
1893
|
}
|
|
1803
|
-
if ((0,
|
|
1894
|
+
if ((0, import_utils14.isArray)(value)) {
|
|
1804
1895
|
return value.some((item) => {
|
|
1805
|
-
if ((0,
|
|
1896
|
+
if ((0, import_utils14.isString)(item) || (0, import_utils14.isArray)(item)) {
|
|
1806
1897
|
return hasModelPermission(item, modelPermissionPrefix);
|
|
1807
1898
|
}
|
|
1808
1899
|
return true;
|
|
1809
1900
|
});
|
|
1810
1901
|
}
|
|
1811
|
-
return (0,
|
|
1902
|
+
return (0, import_utils14.isFunction)(value);
|
|
1812
1903
|
};
|
|
1813
1904
|
classifyPermissionSchema = (permissionSchema, modelPermissionPrefix) => {
|
|
1814
1905
|
const schemaKeys = Object.keys(permissionSchema);
|
|
1815
1906
|
const globalPermissionKeys = {};
|
|
1816
1907
|
const modelPermissionKeys = {};
|
|
1817
|
-
(0,
|
|
1908
|
+
(0, import_utils14.forEach)(schemaKeys, (schemaKey) => {
|
|
1818
1909
|
const schemaRule = permissionSchema[schemaKey];
|
|
1819
|
-
const ruleEntries = (0,
|
|
1910
|
+
const ruleEntries = (0, import_utils14.isPlainObject)(schemaRule) ? Object.entries(schemaRule) : FIELD_ACCESS_KEYS.map((accessKey) => [accessKey, schemaRule]);
|
|
1820
1911
|
for (let x = 0; x < ruleEntries.length; x++) {
|
|
1821
1912
|
const [accessKey, value] = ruleEntries[x];
|
|
1822
|
-
if (!(0,
|
|
1913
|
+
if (!(0, import_utils14.isArray)(globalPermissionKeys[accessKey])) {
|
|
1823
1914
|
globalPermissionKeys[accessKey] = [];
|
|
1824
1915
|
}
|
|
1825
|
-
if (!(0,
|
|
1916
|
+
if (!(0, import_utils14.isArray)(modelPermissionKeys[accessKey])) {
|
|
1826
1917
|
modelPermissionKeys[accessKey] = [];
|
|
1827
1918
|
}
|
|
1828
|
-
if ((0,
|
|
1919
|
+
if ((0, import_utils14.isBoolean)(value)) {
|
|
1829
1920
|
globalPermissionKeys[accessKey].push(schemaKey);
|
|
1830
1921
|
continue;
|
|
1831
1922
|
}
|
|
@@ -1857,13 +1948,13 @@ var init_runtime = __esm({
|
|
|
1857
1948
|
VIRTUAL_RESERVED_NAMES = /* @__PURE__ */ new Set(["_id", "__v", "id"]);
|
|
1858
1949
|
VIRTUAL_DANGEROUS_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
1859
1950
|
VIRTUAL_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
1860
|
-
isVirtualContainerValue = (value) => (0,
|
|
1951
|
+
isVirtualContainerValue = (value) => (0, import_utils14.isPlainObject)(value) && "sub" in value;
|
|
1861
1952
|
virtualFullPath = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
1862
1953
|
virtualPathsOverlap = (virtualPath, permissionField) => {
|
|
1863
1954
|
if (!virtualPath || !permissionField) return false;
|
|
1864
1955
|
try {
|
|
1865
|
-
if ((0,
|
|
1866
|
-
if ((0,
|
|
1956
|
+
if ((0, import_utils14.get)((0, import_utils14.set)({}, virtualPath, true), permissionField) !== void 0) return true;
|
|
1957
|
+
if ((0, import_utils14.get)((0, import_utils14.set)({}, permissionField, true), virtualPath) !== void 0) return true;
|
|
1867
1958
|
} catch {
|
|
1868
1959
|
return false;
|
|
1869
1960
|
}
|
|
@@ -1924,12 +2015,12 @@ var init_runtime = __esm({
|
|
|
1924
2015
|
};
|
|
1925
2016
|
validateVirtualDependsOn = (dependsOn, entryLabel, storedFields, siblingVirtualNames) => {
|
|
1926
2017
|
if (dependsOn === void 0) return [];
|
|
1927
|
-
if (!(0,
|
|
2018
|
+
if (!(0, import_utils14.isArray)(dependsOn)) {
|
|
1928
2019
|
throw new Error(`Virtual ${entryLabel}: dependsOn must be an array of top-level persisted field names`);
|
|
1929
2020
|
}
|
|
1930
2021
|
const list = dependsOn;
|
|
1931
2022
|
for (const dep of list) {
|
|
1932
|
-
if (!(0,
|
|
2023
|
+
if (!(0, import_utils14.isString)(dep) || dep.length === 0) {
|
|
1933
2024
|
throw new Error(`Virtual ${entryLabel}: dependsOn entries must be non-empty strings`);
|
|
1934
2025
|
}
|
|
1935
2026
|
if (dep.includes(".")) {
|
|
@@ -1951,12 +2042,12 @@ var init_runtime = __esm({
|
|
|
1951
2042
|
return list;
|
|
1952
2043
|
};
|
|
1953
2044
|
validateVirtualLeafValue = (value, entryLabel, storedFields, siblingVirtualNames, sharedDependsOn) => {
|
|
1954
|
-
if ((0,
|
|
1955
|
-
if (!(0,
|
|
2045
|
+
if ((0, import_utils14.isFunction)(value)) return;
|
|
2046
|
+
if (!(0, import_utils14.isPlainObject)(value)) {
|
|
1956
2047
|
throw new Error(`Virtual ${entryLabel}: descriptor must be a getter function or { get, dependsOn }`);
|
|
1957
2048
|
}
|
|
1958
2049
|
const record2 = value;
|
|
1959
|
-
if (!(0,
|
|
2050
|
+
if (!(0, import_utils14.isFunction)(record2.get)) {
|
|
1960
2051
|
throw new Error(`Virtual ${entryLabel}: descriptor.get must be a callable getter function`);
|
|
1961
2052
|
}
|
|
1962
2053
|
validateVirtualDependsOn(record2.dependsOn ?? sharedDependsOn, entryLabel, storedFields, siblingVirtualNames);
|
|
@@ -1996,7 +2087,7 @@ var init_runtime = __esm({
|
|
|
1996
2087
|
`Virtual ${scopeLabel}${name}: scope-container must only hold "sub" (embedded container "${name}" is not a virtual-leaf collision)`
|
|
1997
2088
|
);
|
|
1998
2089
|
}
|
|
1999
|
-
if (!(0,
|
|
2090
|
+
if (!(0, import_utils14.isPlainObject)(record3.sub)) {
|
|
2000
2091
|
throw new Error(`Virtual ${scopeLabel}${name}: scope-container "sub" must be a plain object`);
|
|
2001
2092
|
}
|
|
2002
2093
|
continue;
|
|
@@ -2006,8 +2097,8 @@ var init_runtime = __esm({
|
|
|
2006
2097
|
`Virtual ${scopeLabel}${name}: collides with a stored path (inspected actual Mongoose schema/child scope; getModelAtt alone is insufficient)`
|
|
2007
2098
|
);
|
|
2008
2099
|
}
|
|
2009
|
-
if ((0,
|
|
2010
|
-
if (!(0,
|
|
2100
|
+
if ((0, import_utils14.isFunction)(raw)) continue;
|
|
2101
|
+
if (!(0, import_utils14.isPlainObject)(raw)) {
|
|
2011
2102
|
throw new Error(
|
|
2012
2103
|
`Virtual ${scopeLabel}${name}: malformed descriptor (expected getter, { get, dependsOn }, or per-access record)`
|
|
2013
2104
|
);
|
|
@@ -2061,7 +2152,7 @@ var init_runtime = __esm({
|
|
|
2061
2152
|
};
|
|
2062
2153
|
validateVirtualsTree = (model, virtuals, documentPermissionField, modelName) => {
|
|
2063
2154
|
if (virtuals === void 0 || virtuals === null) return;
|
|
2064
|
-
if (!(0,
|
|
2155
|
+
if (!(0, import_utils14.isPlainObject)(virtuals)) {
|
|
2065
2156
|
throw new Error(`Virtuals for model "${modelName}": virtuals must be a plain object mapping names to descriptors`);
|
|
2066
2157
|
}
|
|
2067
2158
|
const rootSchema = model?.schema ?? null;
|
|
@@ -2108,27 +2199,27 @@ var init_runtime = __esm({
|
|
|
2108
2199
|
visitContainers(rootVirtuals, rootSchema, "");
|
|
2109
2200
|
};
|
|
2110
2201
|
getScopeVirtualsObject = (rootVirtuals, scopePath) => {
|
|
2111
|
-
if (!rootVirtuals || !(0,
|
|
2202
|
+
if (!rootVirtuals || !(0, import_utils14.isPlainObject)(rootVirtuals)) return null;
|
|
2112
2203
|
if (!scopePath || scopePath.length === 0) return rootVirtuals;
|
|
2113
2204
|
let current = rootVirtuals;
|
|
2114
2205
|
for (let i = 0; i < scopePath.length; i += 2) {
|
|
2115
2206
|
const field = scopePath[i];
|
|
2116
2207
|
const subMarker = scopePath[i + 1];
|
|
2117
2208
|
if (!field || subMarker !== "sub") return null;
|
|
2118
|
-
if (!(0,
|
|
2209
|
+
if (!(0, import_utils14.isPlainObject)(current)) return null;
|
|
2119
2210
|
const container = current[field];
|
|
2120
2211
|
if (!isVirtualContainerValue(container)) return null;
|
|
2121
2212
|
current = container.sub;
|
|
2122
|
-
if (!(0,
|
|
2213
|
+
if (!(0, import_utils14.isPlainObject)(current)) return null;
|
|
2123
2214
|
}
|
|
2124
2215
|
return current;
|
|
2125
2216
|
};
|
|
2126
2217
|
toVirtualDescriptor = (leaf, sharedDependsOn) => {
|
|
2127
|
-
if ((0,
|
|
2218
|
+
if ((0, import_utils14.isFunction)(leaf))
|
|
2128
2219
|
return { get: leaf, dependsOn: sharedDependsOn ?? [] };
|
|
2129
|
-
if (!(0,
|
|
2220
|
+
if (!(0, import_utils14.isPlainObject)(leaf)) return null;
|
|
2130
2221
|
const record2 = leaf;
|
|
2131
|
-
if (!(0,
|
|
2222
|
+
if (!(0, import_utils14.isFunction)(record2.get)) return null;
|
|
2132
2223
|
const dependsOn = record2.dependsOn ?? sharedDependsOn ?? [];
|
|
2133
2224
|
return { get: record2.get, dependsOn };
|
|
2134
2225
|
};
|
|
@@ -2193,7 +2284,7 @@ var init_runtime = __esm({
|
|
|
2193
2284
|
}
|
|
2194
2285
|
registerOpenApiRoute(route) {
|
|
2195
2286
|
this.openApiRegistry.register(
|
|
2196
|
-
this.openApiPathPrefix ? { ...route, path: (0,
|
|
2287
|
+
this.openApiPathPrefix ? { ...route, path: (0, import_utils14.normalizeUrlPath)(`${this.openApiPathPrefix}/${route.path}`) } : route
|
|
2197
2288
|
);
|
|
2198
2289
|
}
|
|
2199
2290
|
/**
|
|
@@ -2204,7 +2295,7 @@ var init_runtime = __esm({
|
|
|
2204
2295
|
*/
|
|
2205
2296
|
withOpenApiPathPrefix(prefix, build) {
|
|
2206
2297
|
const previous = this.openApiPathPrefix;
|
|
2207
|
-
this.openApiPathPrefix = (0,
|
|
2298
|
+
this.openApiPathPrefix = (0, import_utils14.normalizeUrlPath)(`${previous}/${prefix}`);
|
|
2208
2299
|
try {
|
|
2209
2300
|
return build();
|
|
2210
2301
|
} finally {
|
|
@@ -2324,9 +2415,25 @@ var init_runtime = __esm({
|
|
|
2324
2415
|
}
|
|
2325
2416
|
/** Update model starting defaults shallowly; already-stored model values are not broadcast-replaced. */
|
|
2326
2417
|
setDefaultModelOptions(options) {
|
|
2418
|
+
assertPublicDefaults(options.defaults);
|
|
2419
|
+
if ("hydration" in options) options = { ...options, hydration: normalizeHydration(options.hydration) };
|
|
2327
2420
|
this.defaultModelOptions.assign(options);
|
|
2328
2421
|
}
|
|
2329
2422
|
setDefaultModelOption(key, value) {
|
|
2423
|
+
const keyStr = String(key);
|
|
2424
|
+
if (keyStr === "hydration" || keyStr.startsWith("hydration.")) {
|
|
2425
|
+
this.defaultModelOptions.set(
|
|
2426
|
+
"hydration",
|
|
2427
|
+
normalizeHydrationUpdate(this.getDefaultModelOptions().hydration, keyStr, value)
|
|
2428
|
+
);
|
|
2429
|
+
return;
|
|
2430
|
+
}
|
|
2431
|
+
if (keyStr === "defaults") assertPublicDefaults(value);
|
|
2432
|
+
else if (keyStr.startsWith("defaults.")) {
|
|
2433
|
+
const proposed = {};
|
|
2434
|
+
(0, import_utils14.set)(proposed, keyStr.slice("defaults.".length), value);
|
|
2435
|
+
assertPublicDefaults(proposed);
|
|
2436
|
+
}
|
|
2330
2437
|
this.defaultModelOptions.set(key, value);
|
|
2331
2438
|
}
|
|
2332
2439
|
getDefaultModelOptions() {
|
|
@@ -2353,7 +2460,7 @@ var init_runtime = __esm({
|
|
|
2353
2460
|
}).onchange("basePath", function(newval, key, target) {
|
|
2354
2461
|
target[key] = normalizeBasePath(
|
|
2355
2462
|
modelName,
|
|
2356
|
-
(0,
|
|
2463
|
+
(0, import_utils14.isString)(newval) || (0, import_utils14.isNil)(newval) ? newval : void 0
|
|
2357
2464
|
);
|
|
2358
2465
|
}).build();
|
|
2359
2466
|
this.modelJsonSchemas[modelName] = model.jsonSchema();
|
|
@@ -2376,6 +2483,7 @@ var init_runtime = __esm({
|
|
|
2376
2483
|
*/
|
|
2377
2484
|
setModelOptions(modelName, options) {
|
|
2378
2485
|
assertPublicDefaults(options.defaults);
|
|
2486
|
+
if ("hydration" in options) options = { ...options, hydration: normalizeHydration(options.hydration) };
|
|
2379
2487
|
const manager = this.getOrCreateModelOptions(modelName);
|
|
2380
2488
|
const defaultOptions = this.getDefaultModelOptions();
|
|
2381
2489
|
const currentModelOptions = manager.fetch();
|
|
@@ -2386,14 +2494,19 @@ var init_runtime = __esm({
|
|
|
2386
2494
|
manager.assign({ ...defaultOptions, ...currentModelOptions, ...options });
|
|
2387
2495
|
}
|
|
2388
2496
|
setModelOption(modelName, key, value) {
|
|
2389
|
-
const manager = this.getOrCreateModelOptions(modelName);
|
|
2390
2497
|
const keyStr = String(key);
|
|
2498
|
+
if (keyStr === "hydration" || keyStr.startsWith("hydration.")) {
|
|
2499
|
+
const hydration = normalizeHydrationUpdate(this.modelOptions[modelName]?.get("hydration"), keyStr, value);
|
|
2500
|
+
this.getOrCreateModelOptions(modelName).set("hydration", hydration);
|
|
2501
|
+
return;
|
|
2502
|
+
}
|
|
2391
2503
|
if (keyStr === "defaults") assertPublicDefaults(value);
|
|
2392
2504
|
else if (keyStr.startsWith("defaults.")) {
|
|
2393
2505
|
const proposed = {};
|
|
2394
|
-
(0,
|
|
2506
|
+
(0, import_utils14.set)(proposed, keyStr.slice("defaults.".length), value);
|
|
2395
2507
|
assertPublicDefaults(proposed);
|
|
2396
2508
|
}
|
|
2509
|
+
const manager = this.getOrCreateModelOptions(modelName);
|
|
2397
2510
|
if (keyStr === "virtuals" || keyStr.startsWith("virtuals.") || keyStr === "documentPermissionField") {
|
|
2398
2511
|
const model = this.getModelInstance(modelName);
|
|
2399
2512
|
const currentVirtuals = manager.get("virtuals");
|
|
@@ -2411,15 +2524,15 @@ var init_runtime = __esm({
|
|
|
2411
2524
|
const segments = nestedPath.split(".");
|
|
2412
2525
|
let cursor = cloned;
|
|
2413
2526
|
for (let i = 0; i < segments.length - 1; i++) {
|
|
2414
|
-
if (!(0,
|
|
2527
|
+
if (!(0, import_utils14.isPlainObject)(cursor)) break;
|
|
2415
2528
|
cursor = cursor[segments[i]];
|
|
2416
2529
|
}
|
|
2417
|
-
if ((0,
|
|
2530
|
+
if ((0, import_utils14.isPlainObject)(cursor)) {
|
|
2418
2531
|
delete cursor[segments[segments.length - 1]];
|
|
2419
2532
|
}
|
|
2420
2533
|
proposedVirtuals = cloned;
|
|
2421
2534
|
} else {
|
|
2422
|
-
(0,
|
|
2535
|
+
(0, import_utils14.set)(cloned, nestedPath, value);
|
|
2423
2536
|
proposedVirtuals = cloned;
|
|
2424
2537
|
}
|
|
2425
2538
|
}
|
|
@@ -2497,8 +2610,8 @@ var init_runtime = __esm({
|
|
|
2497
2610
|
if (!scopeVirtuals || !(virtualName in scopeVirtuals)) return void 0;
|
|
2498
2611
|
const entry = scopeVirtuals[virtualName];
|
|
2499
2612
|
if (entry === void 0 || isVirtualContainerValue(entry)) return void 0;
|
|
2500
|
-
if ((0,
|
|
2501
|
-
if (!(0,
|
|
2613
|
+
if ((0, import_utils14.isFunction)(entry)) return { get: entry, dependsOn: [] };
|
|
2614
|
+
if (!(0, import_utils14.isPlainObject)(entry)) return void 0;
|
|
2502
2615
|
const record2 = entry;
|
|
2503
2616
|
if ("get" in record2) {
|
|
2504
2617
|
const descriptor = toVirtualDescriptor(entry, void 0);
|
|
@@ -2534,7 +2647,7 @@ var init_runtime = __esm({
|
|
|
2534
2647
|
manager.onchange("basePath", function(newval, key, target) {
|
|
2535
2648
|
target[key] = normalizeBasePath(
|
|
2536
2649
|
dataName,
|
|
2537
|
-
(0,
|
|
2650
|
+
(0, import_utils14.isString)(newval) || (0, import_utils14.isNil)(newval) ? newval : void 0
|
|
2538
2651
|
);
|
|
2539
2652
|
}).build();
|
|
2540
2653
|
return manager;
|
|
@@ -2594,20 +2707,20 @@ var init_runtime = __esm({
|
|
|
2594
2707
|
const schema = model.schema;
|
|
2595
2708
|
this.modelRefs[modelName] = buildRefs(schema.tree);
|
|
2596
2709
|
this.modelSubs[modelName] = buildSubPaths(schema.tree);
|
|
2597
|
-
this.modelAtts[modelName] = (0,
|
|
2710
|
+
this.modelAtts[modelName] = (0, import_utils14.keys)(schema.obj);
|
|
2598
2711
|
}
|
|
2599
2712
|
getModelRef(modelName, refPath) {
|
|
2600
2713
|
this.ensureModelMeta(modelName);
|
|
2601
|
-
const value = (0,
|
|
2602
|
-
return (0,
|
|
2714
|
+
const value = (0, import_utils14.get)(this.modelRefs, `${modelName}.${refPath}`, null);
|
|
2715
|
+
return (0, import_utils14.isString)(value) ? value : null;
|
|
2603
2716
|
}
|
|
2604
2717
|
getModelSub(modelName) {
|
|
2605
2718
|
this.ensureModelMeta(modelName);
|
|
2606
|
-
return (0,
|
|
2719
|
+
return (0, import_utils14.get)(this.modelSubs, modelName, []);
|
|
2607
2720
|
}
|
|
2608
2721
|
getModelAtt(modelName) {
|
|
2609
2722
|
this.ensureModelMeta(modelName);
|
|
2610
|
-
return (0,
|
|
2723
|
+
return (0, import_utils14.get)(this.modelAtts, modelName, []);
|
|
2611
2724
|
}
|
|
2612
2725
|
};
|
|
2613
2726
|
defaultRuntime = new AccessRuntime({ allowGlobalModelLookup: true });
|
|
@@ -2783,10 +2896,10 @@ var init_options = __esm({
|
|
|
2783
2896
|
});
|
|
2784
2897
|
|
|
2785
2898
|
// src/permission.ts
|
|
2786
|
-
var
|
|
2899
|
+
var import_utils15, Permission, permission_default;
|
|
2787
2900
|
var init_permission = __esm({
|
|
2788
2901
|
"src/permission.ts"() {
|
|
2789
|
-
|
|
2902
|
+
import_utils15 = require("@web-ts-toolkit/utils");
|
|
2790
2903
|
Permission = class {
|
|
2791
2904
|
constructor(permissions) {
|
|
2792
2905
|
this.permissions = { ...permissions };
|
|
@@ -2802,7 +2915,7 @@ var init_permission = __esm({
|
|
|
2802
2915
|
return [permissionOrPermissions].concat(permissions);
|
|
2803
2916
|
}
|
|
2804
2917
|
hasKey(permission) {
|
|
2805
|
-
return (0,
|
|
2918
|
+
return (0, import_utils15.hasOwn)(this.permissions, permission);
|
|
2806
2919
|
}
|
|
2807
2920
|
has(permission) {
|
|
2808
2921
|
return this.permissions[permission] === true;
|
|
@@ -3872,36 +3985,36 @@ function planVirtualProjection(args) {
|
|
|
3872
3985
|
relatedPlans
|
|
3873
3986
|
};
|
|
3874
3987
|
}
|
|
3875
|
-
var
|
|
3988
|
+
var import_utils18, isVirtualContainerValue2, getScopeVirtualsObject2, toSnapshotDescriptor, resolveSnapshotDescriptor, getScopedPermissionSchema, resolveAlwaysSelectForAccess, stripVirtualsFromNormalizedSelect, snapshotVirtualPaths, stripLeadingDash, dbPrefixForScope, toDbPath;
|
|
3876
3989
|
var init_virtual_projection = __esm({
|
|
3877
3990
|
"src/acl/virtual-projection.ts"() {
|
|
3878
|
-
|
|
3991
|
+
import_utils18 = require("@web-ts-toolkit/utils");
|
|
3879
3992
|
init_query();
|
|
3880
3993
|
init_field_authorization();
|
|
3881
3994
|
init_output_projection();
|
|
3882
|
-
isVirtualContainerValue2 = (value) => (0,
|
|
3995
|
+
isVirtualContainerValue2 = (value) => (0, import_utils18.isPlainObject)(value) && "sub" in value;
|
|
3883
3996
|
getScopeVirtualsObject2 = (rootVirtuals, scopePath) => {
|
|
3884
|
-
if (!rootVirtuals || !(0,
|
|
3997
|
+
if (!rootVirtuals || !(0, import_utils18.isPlainObject)(rootVirtuals)) return null;
|
|
3885
3998
|
if (!scopePath || scopePath.length === 0) return rootVirtuals;
|
|
3886
3999
|
let current = rootVirtuals;
|
|
3887
4000
|
for (let i = 0; i < scopePath.length; i += 2) {
|
|
3888
4001
|
const field = scopePath[i];
|
|
3889
4002
|
const subMarker = scopePath[i + 1];
|
|
3890
4003
|
if (!field || subMarker !== "sub") return null;
|
|
3891
|
-
if (!(0,
|
|
4004
|
+
if (!(0, import_utils18.isPlainObject)(current)) return null;
|
|
3892
4005
|
const container = current[field];
|
|
3893
4006
|
if (!isVirtualContainerValue2(container)) return null;
|
|
3894
4007
|
current = container.sub;
|
|
3895
|
-
if (!(0,
|
|
4008
|
+
if (!(0, import_utils18.isPlainObject)(current)) return null;
|
|
3896
4009
|
}
|
|
3897
4010
|
return current;
|
|
3898
4011
|
};
|
|
3899
4012
|
toSnapshotDescriptor = (leaf, sharedDependsOn) => {
|
|
3900
|
-
if ((0,
|
|
4013
|
+
if ((0, import_utils18.isFunction)(leaf))
|
|
3901
4014
|
return { get: leaf, dependsOn: sharedDependsOn ?? [] };
|
|
3902
|
-
if (!(0,
|
|
4015
|
+
if (!(0, import_utils18.isPlainObject)(leaf)) return null;
|
|
3903
4016
|
const record2 = leaf;
|
|
3904
|
-
if (!(0,
|
|
4017
|
+
if (!(0, import_utils18.isFunction)(record2.get)) return null;
|
|
3905
4018
|
const dependsOn = record2.dependsOn ?? sharedDependsOn ?? [];
|
|
3906
4019
|
return { get: record2.get, dependsOn: [...dependsOn] };
|
|
3907
4020
|
};
|
|
@@ -3909,8 +4022,8 @@ var init_virtual_projection = __esm({
|
|
|
3909
4022
|
if (!scopeVirtuals || !(virtualName in scopeVirtuals)) return void 0;
|
|
3910
4023
|
const entry = scopeVirtuals[virtualName];
|
|
3911
4024
|
if (entry === void 0 || isVirtualContainerValue2(entry)) return void 0;
|
|
3912
|
-
if ((0,
|
|
3913
|
-
if (!(0,
|
|
4025
|
+
if ((0, import_utils18.isFunction)(entry)) return { get: entry, dependsOn: [] };
|
|
4026
|
+
if (!(0, import_utils18.isPlainObject)(entry)) return void 0;
|
|
3914
4027
|
const record2 = entry;
|
|
3915
4028
|
if ("get" in record2) {
|
|
3916
4029
|
return toSnapshotDescriptor(entry, void 0) ?? void 0;
|
|
@@ -3929,20 +4042,20 @@ var init_virtual_projection = __esm({
|
|
|
3929
4042
|
return void 0;
|
|
3930
4043
|
};
|
|
3931
4044
|
getScopedPermissionSchema = (root, scopePath) => {
|
|
3932
|
-
if (!root || !(0,
|
|
4045
|
+
if (!root || !(0, import_utils18.isPlainObject)(root)) return null;
|
|
3933
4046
|
if (scopePath.length === 0) return root;
|
|
3934
|
-
const scoped = (0,
|
|
3935
|
-
return (0,
|
|
4047
|
+
const scoped = (0, import_utils18.get)(root, scopePath.join("."));
|
|
4048
|
+
return (0, import_utils18.isPlainObject)(scoped) ? scoped : null;
|
|
3936
4049
|
};
|
|
3937
4050
|
resolveAlwaysSelectForAccess = (raw, access) => {
|
|
3938
4051
|
if (!raw) return [];
|
|
3939
|
-
if ((0,
|
|
3940
|
-
if ((0,
|
|
4052
|
+
if ((0, import_utils18.isArray)(raw)) return [...raw];
|
|
4053
|
+
if ((0, import_utils18.isPlainObject)(raw)) {
|
|
3941
4054
|
const record2 = raw;
|
|
3942
4055
|
const exact = record2[access];
|
|
3943
|
-
if ((0,
|
|
4056
|
+
if ((0, import_utils18.isArray)(exact)) return [...exact];
|
|
3944
4057
|
const def = record2.default;
|
|
3945
|
-
if ((0,
|
|
4058
|
+
if ((0, import_utils18.isArray)(def)) return [...def];
|
|
3946
4059
|
return [];
|
|
3947
4060
|
}
|
|
3948
4061
|
return [];
|
|
@@ -4182,12 +4295,11 @@ var init_output_projection = __esm({
|
|
|
4182
4295
|
|
|
4183
4296
|
// src/acl/model-output-planning.ts
|
|
4184
4297
|
function getCapturedAuthorizationOption(configuration, key) {
|
|
4185
|
-
return resolveNestedOption((path, fallback) => (0,
|
|
4298
|
+
return resolveNestedOption((path, fallback) => (0, import_utils19.get)(configuration, path, fallback), key);
|
|
4186
4299
|
}
|
|
4187
|
-
function captureModelAuthorizationConfiguration(runtime, modelName) {
|
|
4300
|
+
function captureModelAuthorizationConfiguration(runtime, modelName, options = runtime.getModelOptions(modelName)) {
|
|
4188
4301
|
const model = runtime.getModelInstance(modelName);
|
|
4189
4302
|
if (!model) return authorizationError(`unknown receiving model: ${modelName}`);
|
|
4190
|
-
const options = runtime.getModelOptions(modelName);
|
|
4191
4303
|
const virtuals = options.virtuals;
|
|
4192
4304
|
return {
|
|
4193
4305
|
catalog: captureAuthorizationFieldCatalog(model.schema, virtuals, options.documentPermissionField),
|
|
@@ -4205,7 +4317,8 @@ function captureModelAuthorizationConfiguration(runtime, modelName) {
|
|
|
4205
4317
|
baseFilter: options.baseFilter,
|
|
4206
4318
|
idField: options.idField,
|
|
4207
4319
|
resolveIdFilter: options.resolveIdFilter,
|
|
4208
|
-
operationAccess: options.operationAccess
|
|
4320
|
+
operationAccess: options.operationAccess,
|
|
4321
|
+
hydration: options.hydration
|
|
4209
4322
|
};
|
|
4210
4323
|
}
|
|
4211
4324
|
function planModelOutputForHelper(args) {
|
|
@@ -4230,10 +4343,10 @@ function planModelOutputForHelper(args) {
|
|
|
4230
4343
|
requestedSelect: args.select
|
|
4231
4344
|
});
|
|
4232
4345
|
}
|
|
4233
|
-
var
|
|
4346
|
+
var import_utils19;
|
|
4234
4347
|
var init_model_output_planning = __esm({
|
|
4235
4348
|
"src/acl/model-output-planning.ts"() {
|
|
4236
|
-
|
|
4349
|
+
import_utils19 = require("@web-ts-toolkit/utils");
|
|
4237
4350
|
init_manager();
|
|
4238
4351
|
init_field_catalog();
|
|
4239
4352
|
init_authorization_snapshot();
|
|
@@ -4244,10 +4357,10 @@ var init_model_output_planning = __esm({
|
|
|
4244
4357
|
|
|
4245
4358
|
// src/core-shared.ts
|
|
4246
4359
|
function isAndFilter(filter2) {
|
|
4247
|
-
return !!filter2 && (0,
|
|
4360
|
+
return !!filter2 && (0, import_utils20.isPlainObject)(filter2) && Object.keys(filter2).length === 1 && (0, import_utils20.isArray)(filter2.$and);
|
|
4248
4361
|
}
|
|
4249
4362
|
function isMergeableClause(filter2) {
|
|
4250
|
-
return !!filter2 && (0,
|
|
4363
|
+
return !!filter2 && (0, import_utils20.isPlainObject)(filter2) && Object.keys(filter2).every((key) => !key.startsWith("$"));
|
|
4251
4364
|
}
|
|
4252
4365
|
function optimizeAndFilter(clausesInput) {
|
|
4253
4366
|
const clauses = [];
|
|
@@ -4264,11 +4377,11 @@ function optimizeAndFilter(clausesInput) {
|
|
|
4264
4377
|
const dedupeKey = (value) => {
|
|
4265
4378
|
if (value instanceof RegExp) return `regexp:${JSON.stringify([value.source, value.flags])}`;
|
|
4266
4379
|
if (value instanceof Date) return `date:${value.getTime()}`;
|
|
4267
|
-
if ((0,
|
|
4380
|
+
if ((0, import_utils20.isArray)(value)) {
|
|
4268
4381
|
const entries = Array.from(value, dedupeKey);
|
|
4269
4382
|
return entries.every((entry) => entry !== void 0) ? `array:${JSON.stringify(entries)}` : void 0;
|
|
4270
4383
|
}
|
|
4271
|
-
if ((0,
|
|
4384
|
+
if ((0, import_utils20.isPlainObject)(value)) {
|
|
4272
4385
|
const entries = Object.keys(value).sort().map((key) => [key, dedupeKey(value[key])]);
|
|
4273
4386
|
return entries.every(([, entry]) => entry !== void 0) ? `object:${JSON.stringify(entries)}` : void 0;
|
|
4274
4387
|
}
|
|
@@ -4298,7 +4411,7 @@ function optimizeAndFilter(clausesInput) {
|
|
|
4298
4411
|
}
|
|
4299
4412
|
let canMerge = true;
|
|
4300
4413
|
for (const [key, value] of Object.entries(clause)) {
|
|
4301
|
-
if ((0,
|
|
4414
|
+
if ((0, import_utils20.hasOwn)(mergedClause, key) && !(0, import_node_util4.isDeepStrictEqual)(mergedClause[key], value)) {
|
|
4302
4415
|
canMerge = false;
|
|
4303
4416
|
break;
|
|
4304
4417
|
}
|
|
@@ -4309,24 +4422,24 @@ function optimizeAndFilter(clausesInput) {
|
|
|
4309
4422
|
}
|
|
4310
4423
|
Object.assign(mergedClause, clause);
|
|
4311
4424
|
}
|
|
4312
|
-
const finalClauses = (0,
|
|
4425
|
+
const finalClauses = (0, import_utils20.isEmpty)(mergedClause) ? remainingClauses : [mergedClause, ...remainingClauses];
|
|
4313
4426
|
if (finalClauses.length === 0) return null;
|
|
4314
4427
|
if (finalClauses.length === 1) return finalClauses[0];
|
|
4315
4428
|
return { $and: finalClauses };
|
|
4316
4429
|
}
|
|
4317
4430
|
function normalizeFilter(filter2) {
|
|
4318
4431
|
if (filter2 === false) return false;
|
|
4319
|
-
if (!filter2 || !(0,
|
|
4432
|
+
if (!filter2 || !(0, import_utils20.isPlainObject)(filter2) || (0, import_utils20.isEmpty)(filter2)) return null;
|
|
4320
4433
|
if (!isAndFilter(filter2)) {
|
|
4321
4434
|
return filter2;
|
|
4322
4435
|
}
|
|
4323
4436
|
return optimizeAndFilter(filter2.$and);
|
|
4324
4437
|
}
|
|
4325
4438
|
async function resolveIdentifierFilter(req, idField, resolveIdFilter, id) {
|
|
4326
|
-
if ((0,
|
|
4439
|
+
if ((0, import_utils20.isFunction)(resolveIdFilter)) {
|
|
4327
4440
|
return await resolveIdFilter.call(req, id);
|
|
4328
4441
|
}
|
|
4329
|
-
if ((0,
|
|
4442
|
+
if ((0, import_utils20.isString)(idField)) {
|
|
4330
4443
|
return { [idField]: id };
|
|
4331
4444
|
}
|
|
4332
4445
|
return { _id: id };
|
|
@@ -4350,7 +4463,7 @@ async function resolveAccessFilterParts({
|
|
|
4350
4463
|
}
|
|
4351
4464
|
const overrideFilterFn = getOption(`overrideFilter.${access}`, null);
|
|
4352
4465
|
const baseFilterFn = rows.mode === "request" ? getOption(`baseFilter.${access}`, null) : null;
|
|
4353
|
-
if (nextFilter !== false && (0,
|
|
4466
|
+
if (nextFilter !== false && (0, import_utils20.isFunction)(overrideFilterFn)) {
|
|
4354
4467
|
nextFilter = normalizeFilter(await overrideFilterFn.call(req, nextFilter, permissions));
|
|
4355
4468
|
}
|
|
4356
4469
|
if (nextFilter === false) return { transformed: false, scope: {}, filter: false };
|
|
@@ -4358,7 +4471,7 @@ async function resolveAccessFilterParts({
|
|
|
4358
4471
|
const scope2 = rows.mode === "scope" ? rows.filter : {};
|
|
4359
4472
|
return { transformed: nextFilter ?? {}, scope: scope2, filter: intersectFilters(nextFilter, scope2) };
|
|
4360
4473
|
}
|
|
4361
|
-
if (!(0,
|
|
4474
|
+
if (!(0, import_utils20.isFunction)(baseFilterFn)) return { transformed: nextFilter ?? {}, scope: {}, filter: nextFilter ?? {} };
|
|
4362
4475
|
const cached = cache.get(cacheKey);
|
|
4363
4476
|
const reusable = cached?.resolver === baseFilterFn;
|
|
4364
4477
|
const baseFilter = normalizeFilter(
|
|
@@ -4393,34 +4506,34 @@ async function setRequestPermissions(req) {
|
|
|
4393
4506
|
if (owner === activeRuntime) return;
|
|
4394
4507
|
if (hasFieldValue && owner === void 0) return;
|
|
4395
4508
|
const globalPermissions = getGlobalOption("globalPermissions");
|
|
4396
|
-
const permissions = (0,
|
|
4397
|
-
if ((0,
|
|
4398
|
-
else if ((0,
|
|
4399
|
-
else if ((0,
|
|
4509
|
+
const permissions = (0, import_utils20.isFunction)(globalPermissions) ? await globalPermissions.call(req, req) : void 0;
|
|
4510
|
+
if ((0, import_utils20.isPlainObject)(permissions)) req[requestPermissionField] = permissions;
|
|
4511
|
+
else if ((0, import_utils20.isArray)(permissions)) req[requestPermissionField] = (0, import_utils20.arrayToRecord)(permissions);
|
|
4512
|
+
else if ((0, import_utils20.isString)(permissions)) req[requestPermissionField] = { [permissions]: true };
|
|
4400
4513
|
else req[requestPermissionField] = {};
|
|
4401
4514
|
owners.set(requestPermissionField, activeRuntime);
|
|
4402
4515
|
}
|
|
4403
4516
|
async function evaluateRouteGuard(req, permissions, routeGuard) {
|
|
4404
4517
|
const phas = (key) => permissions.has(key);
|
|
4405
4518
|
const { stringHandler, arrayHandler } = createValidator(phas);
|
|
4406
|
-
if ((0,
|
|
4519
|
+
if ((0, import_utils20.isBoolean)(routeGuard)) {
|
|
4407
4520
|
return routeGuard === true;
|
|
4408
4521
|
}
|
|
4409
|
-
if ((0,
|
|
4522
|
+
if ((0, import_utils20.isString)(routeGuard)) {
|
|
4410
4523
|
return stringHandler(routeGuard);
|
|
4411
4524
|
}
|
|
4412
|
-
if ((0,
|
|
4525
|
+
if ((0, import_utils20.isArray)(routeGuard)) {
|
|
4413
4526
|
return arrayHandler(routeGuard);
|
|
4414
4527
|
}
|
|
4415
|
-
if ((0,
|
|
4528
|
+
if ((0, import_utils20.isFunction)(routeGuard)) {
|
|
4416
4529
|
return routeGuard.call(req, permissions);
|
|
4417
4530
|
}
|
|
4418
4531
|
return false;
|
|
4419
4532
|
}
|
|
4420
4533
|
async function callHookChain(req, hook, doc, permissions, context) {
|
|
4421
|
-
const hooks = (0,
|
|
4534
|
+
const hooks = (0, import_utils20.castArray)(hook);
|
|
4422
4535
|
for (let x = 0; x < hooks.length; x++) {
|
|
4423
|
-
if ((0,
|
|
4536
|
+
if ((0, import_utils20.isFunction)(hooks[x])) {
|
|
4424
4537
|
doc = await hooks[x].call(req, doc, permissions, context);
|
|
4425
4538
|
}
|
|
4426
4539
|
}
|
|
@@ -4440,22 +4553,22 @@ async function collectSchemaFields({
|
|
|
4440
4553
|
for (let x = 0; x < keys2.length; x++) {
|
|
4441
4554
|
const key = keys2[x];
|
|
4442
4555
|
const value = extractScopedOutputRule(permissionSchema, key, access);
|
|
4443
|
-
if ((0,
|
|
4556
|
+
if ((0, import_utils20.isBoolean)(value)) {
|
|
4444
4557
|
if (value) fields.push(key);
|
|
4445
|
-
} else if ((0,
|
|
4558
|
+
} else if ((0, import_utils20.isString)(value)) {
|
|
4446
4559
|
if (stringHandler(value)) fields.push(key);
|
|
4447
|
-
} else if ((0,
|
|
4560
|
+
} else if ((0, import_utils20.isArray)(value)) {
|
|
4448
4561
|
if (arrayHandler(value)) fields.push(key);
|
|
4449
|
-
} else if ((0,
|
|
4562
|
+
} else if ((0, import_utils20.isFunction)(value)) {
|
|
4450
4563
|
if (await value.call(req, ...functionArgs)) fields.push(key);
|
|
4451
4564
|
}
|
|
4452
4565
|
}
|
|
4453
4566
|
return fields;
|
|
4454
4567
|
}
|
|
4455
|
-
var
|
|
4568
|
+
var import_utils20, import_node_util4, permissionFieldOwners;
|
|
4456
4569
|
var init_core_shared = __esm({
|
|
4457
4570
|
"src/core-shared.ts"() {
|
|
4458
|
-
|
|
4571
|
+
import_utils20 = require("@web-ts-toolkit/utils");
|
|
4459
4572
|
import_node_util4 = require("util");
|
|
4460
4573
|
init_helpers();
|
|
4461
4574
|
init_options();
|
|
@@ -4683,7 +4796,7 @@ async function resolveOutputDocumentAuthorization(args) {
|
|
|
4683
4796
|
try {
|
|
4684
4797
|
const run = () => hook.call(this, doc, permissions, args.context);
|
|
4685
4798
|
const grants = await getRequestWorkState(binding.request, binding.runtime).hookGate.run(run);
|
|
4686
|
-
return (0,
|
|
4799
|
+
return (0, import_utils24.isPlainObject)(grants) ? grants : {};
|
|
4687
4800
|
} catch (error2) {
|
|
4688
4801
|
warn("docPermissions hook failed; applying empty document permissions", {
|
|
4689
4802
|
modelName: binding.modelName,
|
|
@@ -4798,7 +4911,7 @@ function copyOutputValue(value, plan, path) {
|
|
|
4798
4911
|
const visit = (input, current) => {
|
|
4799
4912
|
if (Array.isArray(input)) return input.map((entry) => visit(entry, current));
|
|
4800
4913
|
if (input instanceof Map) return visit(Object.fromEntries(input), current);
|
|
4801
|
-
if (!(0,
|
|
4914
|
+
if (!(0, import_utils24.isPlainObject)(input)) return deepIsolateValue(input);
|
|
4802
4915
|
const output = {};
|
|
4803
4916
|
for (const [key, entry] of Object.entries(input)) {
|
|
4804
4917
|
const child = `${current}.${key}`;
|
|
@@ -4814,7 +4927,7 @@ function copyOutputValue(value, plan, path) {
|
|
|
4814
4927
|
}
|
|
4815
4928
|
function copyAuthorizedReference(value, plan, path) {
|
|
4816
4929
|
if (Array.isArray(value)) return value.map((entry) => copyAuthorizedReference(entry, plan, path));
|
|
4817
|
-
if (!(0,
|
|
4930
|
+
if (!(0, import_utils24.isPlainObject)(value)) return deepIsolateValue(value);
|
|
4818
4931
|
const handle = getAssociatedDocumentAuthorization(value, plan.authorization);
|
|
4819
4932
|
if (handle) {
|
|
4820
4933
|
const copy = deepIsolateValue(value);
|
|
@@ -4831,8 +4944,8 @@ function retainOutputMetadata(output, source, configuration, scope2) {
|
|
|
4831
4944
|
if (scope2.length || configuration.stripPermissionsField) return;
|
|
4832
4945
|
const parts = (configuration.documentPermissionField ?? "_permissions").split(".");
|
|
4833
4946
|
let value = source;
|
|
4834
|
-
for (const part of parts) value = (0,
|
|
4835
|
-
if (!(0,
|
|
4947
|
+
for (const part of parts) value = (0, import_utils24.isPlainObject)(value) ? value[part] : void 0;
|
|
4948
|
+
if (!(0, import_utils24.isPlainObject)(value)) return;
|
|
4836
4949
|
const keys2 = configuration.exposedDocPermissionKeys;
|
|
4837
4950
|
const metadata = Object.fromEntries(
|
|
4838
4951
|
Object.entries(value).filter(
|
|
@@ -4842,12 +4955,13 @@ function retainOutputMetadata(output, source, configuration, scope2) {
|
|
|
4842
4955
|
const copy = { ...output };
|
|
4843
4956
|
let target = copy;
|
|
4844
4957
|
for (const part of parts.slice(0, -1)) {
|
|
4845
|
-
target[part] = (0,
|
|
4958
|
+
target[part] = (0, import_utils24.isPlainObject)(target[part]) ? { ...target[part] } : {};
|
|
4846
4959
|
target = target[part];
|
|
4847
4960
|
}
|
|
4848
4961
|
target[parts[parts.length - 1]] = deepIsolateValue(metadata);
|
|
4849
4962
|
transferDocumentAuthorizationGraph(output[parts[0]], copy[parts[0]]);
|
|
4850
4963
|
output[parts[0]] = copy[parts[0]];
|
|
4964
|
+
attachPermissionsAlias(output, parts.join("."));
|
|
4851
4965
|
}
|
|
4852
4966
|
function helperPlan(authorization, binding) {
|
|
4853
4967
|
const { configuration, authorization: policy, access } = readServiceAuthorization(authorization, binding);
|
|
@@ -4883,7 +4997,7 @@ async function filterExistingOutput(source, plan, handle, associated) {
|
|
|
4883
4997
|
for (const entry of value2) values.push(await one(entry) ?? null);
|
|
4884
4998
|
return values;
|
|
4885
4999
|
}
|
|
4886
|
-
if (!(0,
|
|
5000
|
+
if (!(0, import_utils24.isPlainObject)(value2)) return value2 === null ? null : void 0;
|
|
4887
5001
|
const childHandle = associated ? getAssociatedDocumentAuthorization(value2) : void 0;
|
|
4888
5002
|
let child = scoped;
|
|
4889
5003
|
if (childHandle) {
|
|
@@ -4963,7 +5077,7 @@ async function filterModelOutputForHelper(args) {
|
|
|
4963
5077
|
const plan = helperPlan(normalized.authorization, binding);
|
|
4964
5078
|
if (args.doc == null) return { output: args.doc, fields: [] };
|
|
4965
5079
|
const source = isolateDocForOutput(args.doc);
|
|
4966
|
-
if (!(0,
|
|
5080
|
+
if (!(0, import_utils24.isPlainObject)(source)) return authorizationError("output helper requires one plain or hydrated document");
|
|
4967
5081
|
const knownOutput = !!args.doc && typeof args.doc === "object" && isKnownAuthorizationOutput(args.doc);
|
|
4968
5082
|
const handle = await resolveOutputDocumentAuthorization({
|
|
4969
5083
|
authorization: normalized.authorization,
|
|
@@ -4974,10 +5088,11 @@ async function filterModelOutputForHelper(args) {
|
|
|
4974
5088
|
});
|
|
4975
5089
|
return filterExistingOutput(source, plan, handle, false);
|
|
4976
5090
|
}
|
|
4977
|
-
var
|
|
5091
|
+
var import_utils24, unresolvedDocuments, owningDocuments;
|
|
4978
5092
|
var init_output_field_filter = __esm({
|
|
4979
5093
|
"src/acl/output-field-filter.ts"() {
|
|
4980
|
-
|
|
5094
|
+
import_utils24 = require("@web-ts-toolkit/utils");
|
|
5095
|
+
init_permissions_alias();
|
|
4981
5096
|
init_document();
|
|
4982
5097
|
init_request_work();
|
|
4983
5098
|
init_logger_helpers();
|
|
@@ -5069,8 +5184,8 @@ async function finalizeSingleDoc(args, input) {
|
|
|
5069
5184
|
const limit = args.resolvedLimit;
|
|
5070
5185
|
const gate = args.sharedGate;
|
|
5071
5186
|
const isolated = isolateDocForOutput(input);
|
|
5072
|
-
const output = (0,
|
|
5073
|
-
if (captured && (0,
|
|
5187
|
+
const output = (0, import_utils25.isPlainObject)(isolated) ? isolated : {};
|
|
5188
|
+
if (captured && (0, import_utils25.isPlainObject)(input))
|
|
5074
5189
|
for (const key of Object.keys(output)) {
|
|
5075
5190
|
transferDocumentAuthorizationGraph(input[key], output[key]);
|
|
5076
5191
|
}
|
|
@@ -5125,7 +5240,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
5125
5240
|
);
|
|
5126
5241
|
continue;
|
|
5127
5242
|
}
|
|
5128
|
-
if (captured && !(0,
|
|
5243
|
+
if (captured && !(0, import_utils25.isPlainObject)(rawContainer) && !Array.isArray(rawContainer)) {
|
|
5129
5244
|
delete output[containerName];
|
|
5130
5245
|
continue;
|
|
5131
5246
|
}
|
|
@@ -5147,7 +5262,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
5147
5262
|
};
|
|
5148
5263
|
const finalizeOneChild = async (rawChild) => {
|
|
5149
5264
|
if (captured && Array.isArray(rawChild)) return mapWithConcurrencyLimit(rawChild, limit, finalizeOneChild);
|
|
5150
|
-
if (!(0,
|
|
5265
|
+
if (!(0, import_utils25.isPlainObject)(rawChild) && !Array.isArray(rawChild)) return captured ? null : deepIsolateValue(rawChild);
|
|
5151
5266
|
if (args.traversal?.finalizeEmbeddedChildren) {
|
|
5152
5267
|
return args.traversal.finalizeEmbeddedChildren({
|
|
5153
5268
|
containerName,
|
|
@@ -5167,7 +5282,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
5167
5282
|
if (Array.isArray(rawContainer)) {
|
|
5168
5283
|
const finalized = await mapWithConcurrencyLimit(rawContainer, limit, (entry) => finalizeOneChild(entry));
|
|
5169
5284
|
output[containerName] = finalized;
|
|
5170
|
-
} else if ((0,
|
|
5285
|
+
} else if ((0, import_utils25.isPlainObject)(rawContainer)) {
|
|
5171
5286
|
output[containerName] = await finalizeOneChild(rawContainer);
|
|
5172
5287
|
}
|
|
5173
5288
|
}
|
|
@@ -5175,7 +5290,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
5175
5290
|
for (const target of relatedTargets) {
|
|
5176
5291
|
let rawRelated;
|
|
5177
5292
|
try {
|
|
5178
|
-
rawRelated = target.path.includes(".") ? (0,
|
|
5293
|
+
rawRelated = target.path.includes(".") ? (0, import_utils25.get)(output, target.path) : output[target.path];
|
|
5179
5294
|
} catch {
|
|
5180
5295
|
continue;
|
|
5181
5296
|
}
|
|
@@ -5204,7 +5319,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
5204
5319
|
related: target.plan.relatedPlans?.length ? (args.related ?? []).filter((entry) => entry.path.startsWith(`${target.path}.`)) : []
|
|
5205
5320
|
};
|
|
5206
5321
|
const finalizeOneRelated = async (rawChild) => {
|
|
5207
|
-
if (!(0,
|
|
5322
|
+
if (!(0, import_utils25.isPlainObject)(rawChild) && !Array.isArray(rawChild)) return rawChild;
|
|
5208
5323
|
if (typeof rawChild?._bsontype === "string") return rawChild;
|
|
5209
5324
|
if (args.traversal?.finalizeRelatedValue) {
|
|
5210
5325
|
return args.traversal.finalizeRelatedValue({ path: target.path, target, rawValue: rawChild, parentArgs: args });
|
|
@@ -5214,13 +5329,13 @@ async function finalizeSingleDoc(args, input) {
|
|
|
5214
5329
|
let finalized;
|
|
5215
5330
|
if (Array.isArray(rawRelated)) {
|
|
5216
5331
|
finalized = await mapWithConcurrencyLimit(rawRelated, limit, (entry) => finalizeOneRelated(entry));
|
|
5217
|
-
} else if ((0,
|
|
5332
|
+
} else if ((0, import_utils25.isPlainObject)(rawRelated)) {
|
|
5218
5333
|
finalized = await finalizeOneRelated(rawRelated);
|
|
5219
5334
|
} else {
|
|
5220
5335
|
continue;
|
|
5221
5336
|
}
|
|
5222
5337
|
try {
|
|
5223
|
-
if (target.path.includes(".")) (0,
|
|
5338
|
+
if (target.path.includes(".")) (0, import_utils25.set)(output, target.path, finalized);
|
|
5224
5339
|
else output[target.path] = finalized;
|
|
5225
5340
|
} catch {
|
|
5226
5341
|
}
|
|
@@ -5390,10 +5505,10 @@ async function finalizeModelOutputs(args) {
|
|
|
5390
5505
|
return finalizeSingleDoc(internal, input);
|
|
5391
5506
|
});
|
|
5392
5507
|
}
|
|
5393
|
-
var
|
|
5508
|
+
var import_utils25, isVirtualContainerValue3, getScopeVirtualsObject3, getScopeVirtualNames, getScopedPermissionSchema2, resolveGlobalPermissions, resolveDocPermissions, isAbsentDependency, __finalizeInternals;
|
|
5394
5509
|
var init_finalize_model_output = __esm({
|
|
5395
5510
|
"src/output/finalize-model-output.ts"() {
|
|
5396
|
-
|
|
5511
|
+
import_utils25 = require("@web-ts-toolkit/utils");
|
|
5397
5512
|
init_document();
|
|
5398
5513
|
init_concurrency();
|
|
5399
5514
|
init_request_work();
|
|
@@ -5404,20 +5519,20 @@ var init_finalize_model_output = __esm({
|
|
|
5404
5519
|
init_output_field_filter();
|
|
5405
5520
|
init_field_authorization();
|
|
5406
5521
|
init_field_catalog();
|
|
5407
|
-
isVirtualContainerValue3 = (value) => (0,
|
|
5522
|
+
isVirtualContainerValue3 = (value) => (0, import_utils25.isPlainObject)(value) && "sub" in value;
|
|
5408
5523
|
getScopeVirtualsObject3 = (rootVirtuals, scopePath) => {
|
|
5409
|
-
if (!rootVirtuals || !(0,
|
|
5524
|
+
if (!rootVirtuals || !(0, import_utils25.isPlainObject)(rootVirtuals)) return null;
|
|
5410
5525
|
if (scopePath.length === 0) return rootVirtuals;
|
|
5411
5526
|
let current = rootVirtuals;
|
|
5412
5527
|
for (let i = 0; i < scopePath.length; i += 2) {
|
|
5413
5528
|
const field = scopePath[i];
|
|
5414
5529
|
const subMarker = scopePath[i + 1];
|
|
5415
5530
|
if (!field || subMarker !== "sub") return null;
|
|
5416
|
-
if (!(0,
|
|
5531
|
+
if (!(0, import_utils25.isPlainObject)(current)) return null;
|
|
5417
5532
|
const container = current[field];
|
|
5418
5533
|
if (!isVirtualContainerValue3(container)) return null;
|
|
5419
5534
|
current = container.sub;
|
|
5420
|
-
if (!(0,
|
|
5535
|
+
if (!(0, import_utils25.isPlainObject)(current)) return null;
|
|
5421
5536
|
}
|
|
5422
5537
|
return current;
|
|
5423
5538
|
};
|
|
@@ -5430,11 +5545,11 @@ var init_finalize_model_output = __esm({
|
|
|
5430
5545
|
return Object.entries(scopeVirtuals).filter(([, v]) => v !== void 0 && !isVirtualContainerValue3(v)).map(([k]) => k);
|
|
5431
5546
|
};
|
|
5432
5547
|
getScopedPermissionSchema2 = (root, scopePath) => {
|
|
5433
|
-
if (!root || !(0,
|
|
5548
|
+
if (!root || !(0, import_utils25.isPlainObject)(root)) return null;
|
|
5434
5549
|
if (scopePath.length === 0) return root;
|
|
5435
5550
|
try {
|
|
5436
|
-
const scoped = (0,
|
|
5437
|
-
return (0,
|
|
5551
|
+
const scoped = (0, import_utils25.get)(root, scopePath.join("."));
|
|
5552
|
+
return (0, import_utils25.isPlainObject)(scoped) ? scoped : null;
|
|
5438
5553
|
} catch {
|
|
5439
5554
|
return null;
|
|
5440
5555
|
}
|
|
@@ -5493,7 +5608,7 @@ var init_finalize_model_output = __esm({
|
|
|
5493
5608
|
const grants = await args.sharedGate.run(
|
|
5494
5609
|
() => hook.call(args.request, isolatedForHook, globalPerms, scopeContext)
|
|
5495
5610
|
);
|
|
5496
|
-
const normalized = (0,
|
|
5611
|
+
const normalized = (0, import_utils25.isPlainObject)(grants) ? grants : {};
|
|
5497
5612
|
scopeContext.docPermissions = normalized;
|
|
5498
5613
|
return normalized;
|
|
5499
5614
|
}
|
|
@@ -5565,15 +5680,15 @@ __export(index_exports, {
|
|
|
5565
5680
|
setModelOptions: () => setModelOptions
|
|
5566
5681
|
});
|
|
5567
5682
|
module.exports = __toCommonJS(index_exports);
|
|
5568
|
-
var
|
|
5683
|
+
var import_utils43 = require("@web-ts-toolkit/utils");
|
|
5569
5684
|
|
|
5570
5685
|
// src/middleware.ts
|
|
5571
5686
|
var import_express_json_router5 = __toESM(require("@web-ts-toolkit/express-json-router"));
|
|
5572
|
-
var
|
|
5687
|
+
var import_utils36 = require("@web-ts-toolkit/utils");
|
|
5573
5688
|
|
|
5574
5689
|
// src/core.ts
|
|
5575
5690
|
init_public_admission();
|
|
5576
|
-
var
|
|
5691
|
+
var import_utils35 = require("@web-ts-toolkit/utils");
|
|
5577
5692
|
init_options();
|
|
5578
5693
|
|
|
5579
5694
|
// src/meta.ts
|
|
@@ -5598,13 +5713,13 @@ var getModelRef = (modelName, refPath) => {
|
|
|
5598
5713
|
};
|
|
5599
5714
|
|
|
5600
5715
|
// src/services/base.ts
|
|
5601
|
-
var
|
|
5716
|
+
var import_utils21 = require("@web-ts-toolkit/utils");
|
|
5602
5717
|
init_options();
|
|
5603
5718
|
init_helpers();
|
|
5604
5719
|
init_document();
|
|
5605
5720
|
|
|
5606
5721
|
// src/output/include-output.ts
|
|
5607
|
-
var
|
|
5722
|
+
var import_utils16 = require("@web-ts-toolkit/utils");
|
|
5608
5723
|
init_document_authorization();
|
|
5609
5724
|
init_document();
|
|
5610
5725
|
var outputs2 = /* @__PURE__ */ new WeakMap();
|
|
@@ -5621,7 +5736,7 @@ function attachIncludeOutput(doc, path, value) {
|
|
|
5621
5736
|
const state = stateFor(doc);
|
|
5622
5737
|
if (!state) throw new Error("Include attachment requires a prepared output row");
|
|
5623
5738
|
state.attachments.push({ path, value });
|
|
5624
|
-
(0,
|
|
5739
|
+
(0, import_utils16.set)(doc, path, deepIsolateValue(value));
|
|
5625
5740
|
}
|
|
5626
5741
|
function getIncludeSource(doc) {
|
|
5627
5742
|
return stateFor(doc)?.source ?? doc;
|
|
@@ -5636,7 +5751,7 @@ function restoreIncludeOutput(doc, output) {
|
|
|
5636
5751
|
for (const { path, value } of attachments) {
|
|
5637
5752
|
const copy = deepIsolateValue(value);
|
|
5638
5753
|
if (copy !== null && typeof copy === "object") origins.set(copy, value);
|
|
5639
|
-
(0,
|
|
5754
|
+
(0, import_utils16.set)(output, path, copy);
|
|
5640
5755
|
}
|
|
5641
5756
|
return origins;
|
|
5642
5757
|
}
|
|
@@ -5763,7 +5878,7 @@ function requestFieldScope(options) {
|
|
|
5763
5878
|
init_public_admission();
|
|
5764
5879
|
|
|
5765
5880
|
// src/correlated-includes.ts
|
|
5766
|
-
var
|
|
5881
|
+
var import_utils17 = require("@web-ts-toolkit/utils");
|
|
5767
5882
|
init_request_complexity();
|
|
5768
5883
|
init_sort_policy();
|
|
5769
5884
|
var PARENT_MARKER_KEY = "$parent";
|
|
@@ -5776,10 +5891,10 @@ var FIELD_SEGMENT_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
|
5776
5891
|
var ARRAY_INDEX_SEGMENT_PATTERN = /^(0|[1-9]\d*)$/;
|
|
5777
5892
|
var ownKeys = (value) => Object.keys(value);
|
|
5778
5893
|
function isParentRefMarker(value) {
|
|
5779
|
-
return (0,
|
|
5894
|
+
return (0, import_utils17.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === PARENT_MARKER_KEY;
|
|
5780
5895
|
}
|
|
5781
5896
|
function isEscapedParentRef(value) {
|
|
5782
|
-
return (0,
|
|
5897
|
+
return (0, import_utils17.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === ESCAPE_WRAPPER_KEY;
|
|
5783
5898
|
}
|
|
5784
5899
|
function hasMarkerKey(value) {
|
|
5785
5900
|
return ownKeys(value).includes(PARENT_MARKER_KEY) || ownKeys(value).includes(ESCAPE_WRAPPER_KEY);
|
|
@@ -5798,12 +5913,12 @@ function containsParentMarkerShape(value) {
|
|
|
5798
5913
|
const seen = /* @__PURE__ */ new Set();
|
|
5799
5914
|
const visit = (current) => {
|
|
5800
5915
|
if (isParentRefMarker(current) || isEscapedParentRef(current)) return true;
|
|
5801
|
-
if ((0,
|
|
5916
|
+
if ((0, import_utils17.isArray)(current)) {
|
|
5802
5917
|
if (seen.has(current)) return false;
|
|
5803
5918
|
seen.add(current);
|
|
5804
5919
|
return current.some(visit);
|
|
5805
5920
|
}
|
|
5806
|
-
if ((0,
|
|
5921
|
+
if ((0, import_utils17.isPlainObject)(current)) {
|
|
5807
5922
|
if (seen.has(current)) return false;
|
|
5808
5923
|
seen.add(current);
|
|
5809
5924
|
if (hasMarkerKey(current)) return true;
|
|
@@ -5833,7 +5948,7 @@ function scanTemplateValueNode(value, path, issues) {
|
|
|
5833
5948
|
}
|
|
5834
5949
|
return;
|
|
5835
5950
|
}
|
|
5836
|
-
if ((0,
|
|
5951
|
+
if ((0, import_utils17.isPlainObject)(value)) {
|
|
5837
5952
|
if (hasMarkerKey(value)) {
|
|
5838
5953
|
issues.push({
|
|
5839
5954
|
message: 'Malformed $parent reference: objects carrying $parent must be exactly { "$parent": "<field>" }',
|
|
@@ -5844,7 +5959,7 @@ function scanTemplateValueNode(value, path, issues) {
|
|
|
5844
5959
|
scanTemplateObjectEntries(value, path, issues);
|
|
5845
5960
|
return;
|
|
5846
5961
|
}
|
|
5847
|
-
if ((0,
|
|
5962
|
+
if ((0, import_utils17.isArray)(value)) {
|
|
5848
5963
|
value.forEach((item, index) => scanTemplateValueNode(item, [...path, index], issues));
|
|
5849
5964
|
}
|
|
5850
5965
|
}
|
|
@@ -5885,7 +6000,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
|
|
|
5885
6000
|
continue;
|
|
5886
6001
|
}
|
|
5887
6002
|
if (LOGICAL_CLAUSE_KEYS.has(key)) {
|
|
5888
|
-
if (!(0,
|
|
6003
|
+
if (!(0, import_utils17.isArray)(child)) {
|
|
5889
6004
|
scanTemplateValueNode(child, childPath, issues);
|
|
5890
6005
|
continue;
|
|
5891
6006
|
}
|
|
@@ -5898,7 +6013,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
|
|
|
5898
6013
|
});
|
|
5899
6014
|
return;
|
|
5900
6015
|
}
|
|
5901
|
-
if ((0,
|
|
6016
|
+
if ((0, import_utils17.isPlainObject)(clause)) {
|
|
5902
6017
|
scanTemplateObjectEntries(clause, clausePath, issues);
|
|
5903
6018
|
}
|
|
5904
6019
|
});
|
|
@@ -5909,7 +6024,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
|
|
|
5909
6024
|
}
|
|
5910
6025
|
function validateCorrelatedFilterTemplate(filter2) {
|
|
5911
6026
|
const issues = [];
|
|
5912
|
-
if (!(0,
|
|
6027
|
+
if (!(0, import_utils17.isPlainObject)(filter2)) {
|
|
5913
6028
|
issues.push({ message: "Correlated include filter must be an object", path: [] });
|
|
5914
6029
|
return issues;
|
|
5915
6030
|
}
|
|
@@ -5952,13 +6067,13 @@ function collectFilterReferencePaths(filter2) {
|
|
|
5952
6067
|
return;
|
|
5953
6068
|
}
|
|
5954
6069
|
if (isEscapedParentRef(value)) return;
|
|
5955
|
-
if ((0,
|
|
6070
|
+
if ((0, import_utils17.isArray)(value)) {
|
|
5956
6071
|
if (seen.has(value)) return;
|
|
5957
6072
|
seen.add(value);
|
|
5958
6073
|
value.forEach(visitValue);
|
|
5959
6074
|
return;
|
|
5960
6075
|
}
|
|
5961
|
-
if ((0,
|
|
6076
|
+
if ((0, import_utils17.isPlainObject)(value)) {
|
|
5962
6077
|
if (seen.has(value)) return;
|
|
5963
6078
|
seen.add(value);
|
|
5964
6079
|
for (const [key, child] of Object.entries(value)) {
|
|
@@ -6004,7 +6119,7 @@ function getOwnPathValue(parent, path) {
|
|
|
6004
6119
|
return current;
|
|
6005
6120
|
}
|
|
6006
6121
|
function cloneSubstitutedValue(value) {
|
|
6007
|
-
if ((0,
|
|
6122
|
+
if ((0, import_utils17.isPlainObject)(value) || (0, import_utils17.isArray)(value)) return (0, import_utils17.cloneDeep)(value);
|
|
6008
6123
|
return value;
|
|
6009
6124
|
}
|
|
6010
6125
|
function literalParentRefObject(path) {
|
|
@@ -6045,7 +6160,7 @@ function resolveObjectEntries(obj, parent) {
|
|
|
6045
6160
|
continue;
|
|
6046
6161
|
}
|
|
6047
6162
|
if (LOGICAL_CLAUSE_KEYS.has(key)) {
|
|
6048
|
-
if (!(0,
|
|
6163
|
+
if (!(0, import_utils17.isArray)(child)) {
|
|
6049
6164
|
out[key] = resolveValueNode(child, parent, false);
|
|
6050
6165
|
continue;
|
|
6051
6166
|
}
|
|
@@ -6053,7 +6168,7 @@ function resolveObjectEntries(obj, parent) {
|
|
|
6053
6168
|
if (isParentRefMarker(clause) || isEscapedParentRef(clause)) {
|
|
6054
6169
|
throw new CorrelatedReferenceError(`Unsupported $parent reference as a direct ${key} clause`);
|
|
6055
6170
|
}
|
|
6056
|
-
if (!(0,
|
|
6171
|
+
if (!(0, import_utils17.isPlainObject)(clause)) return cloneSubstitutedValue(clause);
|
|
6057
6172
|
return resolveObjectEntries(clause, parent);
|
|
6058
6173
|
});
|
|
6059
6174
|
continue;
|
|
@@ -6082,10 +6197,10 @@ function resolveValueNode(template, parent, bare) {
|
|
|
6082
6197
|
}
|
|
6083
6198
|
const value = getOwnPathValue(parent, path);
|
|
6084
6199
|
if (value === void 0 || value === null) throw UNRESOLVABLE;
|
|
6085
|
-
if (bare && (0,
|
|
6200
|
+
if (bare && (0, import_utils17.isPlainObject)(value)) return { $eq: (0, import_utils17.cloneDeep)(value) };
|
|
6086
6201
|
return cloneSubstitutedValue(value);
|
|
6087
6202
|
}
|
|
6088
|
-
if ((0,
|
|
6203
|
+
if ((0, import_utils17.isPlainObject)(template)) {
|
|
6089
6204
|
if (hasMarkerKey(template)) {
|
|
6090
6205
|
throw new CorrelatedReferenceError(
|
|
6091
6206
|
'Malformed $parent reference: objects carrying $parent must be exactly { "$parent": "<field>" }'
|
|
@@ -6093,7 +6208,7 @@ function resolveValueNode(template, parent, bare) {
|
|
|
6093
6208
|
}
|
|
6094
6209
|
return resolveObjectEntries(template, parent);
|
|
6095
6210
|
}
|
|
6096
|
-
if ((0,
|
|
6211
|
+
if ((0, import_utils17.isArray)(template)) {
|
|
6097
6212
|
return template.map((item) => resolveValueNode(item, parent, false));
|
|
6098
6213
|
}
|
|
6099
6214
|
return template;
|
|
@@ -6127,7 +6242,7 @@ function resolveCorrelatedIdTemplate(id, parent) {
|
|
|
6127
6242
|
}
|
|
6128
6243
|
function resolveCorrelatedFilterTemplate(filter2, parent) {
|
|
6129
6244
|
try {
|
|
6130
|
-
if (!(0,
|
|
6245
|
+
if (!(0, import_utils17.isPlainObject)(filter2) || isParentRefMarker(filter2) || isEscapedParentRef(filter2)) {
|
|
6131
6246
|
throw new CorrelatedReferenceError("Correlated include filter must be an object");
|
|
6132
6247
|
}
|
|
6133
6248
|
return { status: "resolved", filter: resolveObjectEntries(filter2, parent) };
|
|
@@ -6142,7 +6257,7 @@ function validateExpandedCorrelatedOperands(expanded, limits) {
|
|
|
6142
6257
|
var MAX_NESTED_INCLUDE_DEPTH = 10;
|
|
6143
6258
|
function validateCorrelatedArgsShape(args, op, depth) {
|
|
6144
6259
|
if (args === void 0) return [];
|
|
6145
|
-
if (!(0,
|
|
6260
|
+
if (!(0, import_utils17.isPlainObject)(args)) return ["Correlated include args must be an object"];
|
|
6146
6261
|
const record2 = args;
|
|
6147
6262
|
const allowed = op === "list" ? /* @__PURE__ */ new Set(["select", "sort", "skip", "limit", "page", "pageSize", "include"]) : /* @__PURE__ */ new Set(["select", "sort", "include"]);
|
|
6148
6263
|
for (const key of Object.keys(record2)) {
|
|
@@ -6164,7 +6279,7 @@ function validateCorrelatedArgsShape(args, op, depth) {
|
|
|
6164
6279
|
return [];
|
|
6165
6280
|
}
|
|
6166
6281
|
function validateCorrelatedIncludeShape(entry, depth = 0) {
|
|
6167
|
-
if (!(0,
|
|
6282
|
+
if (!(0, import_utils17.isPlainObject)(entry)) return ["Correlated include must be an object"];
|
|
6168
6283
|
const record2 = entry;
|
|
6169
6284
|
if (record2.mode !== "correlated") return ['Correlated include mode must be "correlated"'];
|
|
6170
6285
|
if (typeof record2.model !== "string" || record2.model.length === 0)
|
|
@@ -6177,7 +6292,7 @@ function validateCorrelatedIncludeShape(entry, depth = 0) {
|
|
|
6177
6292
|
if ("localField" in record2 || "foreignField" in record2) {
|
|
6178
6293
|
return ["Correlated includes must not carry localField or foreignField"];
|
|
6179
6294
|
}
|
|
6180
|
-
if (record2.options !== void 0 && !((0,
|
|
6295
|
+
if (record2.options !== void 0 && !((0, import_utils17.isPlainObject)(record2.options) && Object.keys(record2.options).length === 0)) {
|
|
6181
6296
|
return ["Correlated include options must be absent or empty"];
|
|
6182
6297
|
}
|
|
6183
6298
|
const hasId = record2.id !== void 0;
|
|
@@ -6199,7 +6314,7 @@ function validateCorrelatedIncludeShape(entry, depth = 0) {
|
|
|
6199
6314
|
return validateCorrelatedArgsShape(record2.args, record2.op, depth);
|
|
6200
6315
|
}
|
|
6201
6316
|
function isCorrelatedInclude(value) {
|
|
6202
|
-
return (0,
|
|
6317
|
+
return (0, import_utils17.isPlainObject)(value) && value.mode === "correlated";
|
|
6203
6318
|
}
|
|
6204
6319
|
|
|
6205
6320
|
// src/services/base.ts
|
|
@@ -6346,7 +6461,7 @@ function snapshotGroups(sources, valueOf, multipleKeys) {
|
|
|
6346
6461
|
if (sources.length > MAX_GROUPS) invalid(`groups exceed ${MAX_GROUPS}`);
|
|
6347
6462
|
const budget = new KeyBudget();
|
|
6348
6463
|
const values = [];
|
|
6349
|
-
const
|
|
6464
|
+
const aliases2 = [];
|
|
6350
6465
|
const indices = /* @__PURE__ */ new Map();
|
|
6351
6466
|
const groups = [];
|
|
6352
6467
|
for (const source of sources) {
|
|
@@ -6357,7 +6472,7 @@ function snapshotGroups(sources, valueOf, multipleKeys) {
|
|
|
6357
6472
|
if (index === void 0) {
|
|
6358
6473
|
index = values.length;
|
|
6359
6474
|
indices.set(alias, index);
|
|
6360
|
-
|
|
6475
|
+
aliases2.push(alias);
|
|
6361
6476
|
values.push(snapshot);
|
|
6362
6477
|
}
|
|
6363
6478
|
group.add(index);
|
|
@@ -6377,7 +6492,7 @@ function snapshotGroups(sources, valueOf, multipleKeys) {
|
|
|
6377
6492
|
}
|
|
6378
6493
|
return Object.freeze({
|
|
6379
6494
|
values: Object.freeze(values),
|
|
6380
|
-
aliases: Object.freeze(
|
|
6495
|
+
aliases: Object.freeze(aliases2),
|
|
6381
6496
|
groups: Object.freeze((multipleKeys ? groups : values.map((_, i) => [i])).map((group) => Object.freeze(group)))
|
|
6382
6497
|
});
|
|
6383
6498
|
}
|
|
@@ -6427,7 +6542,7 @@ function getServiceExecutors(receiver) {
|
|
|
6427
6542
|
if (!registered) authorizationError("unregistered service receiver");
|
|
6428
6543
|
return registered;
|
|
6429
6544
|
}
|
|
6430
|
-
function createServiceExecution(receiver, access, authorization, applicability = "service", relatedTargets = [], parent, configuration, requestPermissions) {
|
|
6545
|
+
function createServiceExecution(receiver, access, authorization, applicability = "service", relatedTargets = [], parent, configuration, requestPermissions, hydration = access.operation === "list" ? "find" : "findOne") {
|
|
6431
6546
|
const registered = getServiceExecutors(receiver);
|
|
6432
6547
|
const receiving = registered.binding();
|
|
6433
6548
|
const binding = Object.freeze({ ...receiving, scopePath: Object.freeze([...receiving.scopePath ?? []]) });
|
|
@@ -6449,11 +6564,23 @@ function createServiceExecution(receiver, access, authorization, applicability =
|
|
|
6449
6564
|
binding,
|
|
6450
6565
|
authorization: call,
|
|
6451
6566
|
access: readServiceAuthorization(call, binding).access,
|
|
6452
|
-
family: execution
|
|
6567
|
+
family: execution,
|
|
6568
|
+
hydration: resolveHydration(readServiceAuthorization(call, binding).configuration, hydration)
|
|
6453
6569
|
})
|
|
6454
6570
|
);
|
|
6455
6571
|
return execution;
|
|
6456
6572
|
}
|
|
6573
|
+
function resolveHydration(configuration, source) {
|
|
6574
|
+
if (source === "lean" || source === "hydrated") return source;
|
|
6575
|
+
return configuration.hydration?.[source] ?? (source === "publicList" ? "lean" : "hydrated");
|
|
6576
|
+
}
|
|
6577
|
+
function withExecutionHydration(receiver, parent, source) {
|
|
6578
|
+
const record2 = readServiceExecution(receiver, parent);
|
|
6579
|
+
const { configuration } = readServiceAuthorization(record2.authorization, record2.binding);
|
|
6580
|
+
const execution = Object.freeze(/* @__PURE__ */ Object.create(null));
|
|
6581
|
+
executions.set(execution, Object.freeze({ ...record2, hydration: resolveHydration(configuration, source) }));
|
|
6582
|
+
return execution;
|
|
6583
|
+
}
|
|
6457
6584
|
function readServiceExecution(receiver, execution) {
|
|
6458
6585
|
const record2 = executions.get(execution);
|
|
6459
6586
|
if (!record2 || record2.receiver !== receiver) authorizationError("invalid execution receiver/call");
|
|
@@ -6658,20 +6785,20 @@ var copyAuthorizedOutput = (value) => {
|
|
|
6658
6785
|
transferDocumentAuthorizationGraph(value, copy);
|
|
6659
6786
|
return copy;
|
|
6660
6787
|
};
|
|
6661
|
-
var isVirtualContainerValueForGuard = (value) => (0,
|
|
6788
|
+
var isVirtualContainerValueForGuard = (value) => (0, import_utils21.isPlainObject)(value) && "sub" in value;
|
|
6662
6789
|
var getScopeVirtualsForGuard = (rootVirtuals, scopePath) => {
|
|
6663
|
-
if (!rootVirtuals || !(0,
|
|
6790
|
+
if (!rootVirtuals || !(0, import_utils21.isPlainObject)(rootVirtuals)) return null;
|
|
6664
6791
|
if (scopePath.length === 0) return rootVirtuals;
|
|
6665
6792
|
let current = rootVirtuals;
|
|
6666
6793
|
for (let i = 0; i < scopePath.length; i += 2) {
|
|
6667
6794
|
const field = scopePath[i];
|
|
6668
6795
|
const subMarker = scopePath[i + 1];
|
|
6669
6796
|
if (!field || subMarker !== "sub") return null;
|
|
6670
|
-
if (!(0,
|
|
6797
|
+
if (!(0, import_utils21.isPlainObject)(current)) return null;
|
|
6671
6798
|
const container = current[field];
|
|
6672
6799
|
if (!isVirtualContainerValueForGuard(container)) return null;
|
|
6673
6800
|
current = container.sub;
|
|
6674
|
-
if (!(0,
|
|
6801
|
+
if (!(0, import_utils21.isPlainObject)(current)) return null;
|
|
6675
6802
|
}
|
|
6676
6803
|
return current;
|
|
6677
6804
|
};
|
|
@@ -6737,7 +6864,7 @@ var sanitizeSubScopeVirtualKeys = (data, snapshot, sub) => {
|
|
|
6737
6864
|
for (const entry of value) stripScope(entry, currentScope);
|
|
6738
6865
|
return;
|
|
6739
6866
|
}
|
|
6740
|
-
if (!(0,
|
|
6867
|
+
if (!(0, import_utils21.isPlainObject)(value)) return;
|
|
6741
6868
|
const record2 = value;
|
|
6742
6869
|
const leaves = getScopeVirtualLeafNames(snapshot, currentScope);
|
|
6743
6870
|
for (const leaf of leaves) {
|
|
@@ -6750,7 +6877,7 @@ var sanitizeSubScopeVirtualKeys = (data, snapshot, sub) => {
|
|
|
6750
6877
|
for (const key of Object.keys(record2)) {
|
|
6751
6878
|
if (leaves.has(key) || containers.has(key)) continue;
|
|
6752
6879
|
const child = record2[key];
|
|
6753
|
-
if (Array.isArray(child) || (0,
|
|
6880
|
+
if (Array.isArray(child) || (0, import_utils21.isPlainObject)(child)) {
|
|
6754
6881
|
stripScope(child, currentScope);
|
|
6755
6882
|
}
|
|
6756
6883
|
}
|
|
@@ -6762,7 +6889,7 @@ var LOGICAL_FILTER_KEYS = /* @__PURE__ */ new Set(["$and", "$or", "$nor"]);
|
|
|
6762
6889
|
var isOperatorKey = (key) => key.startsWith("$");
|
|
6763
6890
|
var REMOVED_VIRTUAL_FILTER = /* @__PURE__ */ Symbol("removed virtual filter clause");
|
|
6764
6891
|
var rewriteFilterObject = (value, visit) => {
|
|
6765
|
-
if (!(0,
|
|
6892
|
+
if (!(0, import_utils21.isPlainObject)(value)) return value;
|
|
6766
6893
|
let changed = false;
|
|
6767
6894
|
const entries = [];
|
|
6768
6895
|
for (const [key, child] of Object.entries(value)) {
|
|
@@ -6793,7 +6920,7 @@ var resolveVirtualFilterField = (path, scope2) => {
|
|
|
6793
6920
|
if (!Object.hasOwn(scope2, segment) || scope2[segment] === void 0) return null;
|
|
6794
6921
|
const definition = scope2[segment];
|
|
6795
6922
|
if (!isVirtualContainerValueForGuard(definition)) return REMOVED_VIRTUAL_FILTER;
|
|
6796
|
-
scope2 = (0,
|
|
6923
|
+
scope2 = (0, import_utils21.isPlainObject)(definition.sub) ? definition.sub : null;
|
|
6797
6924
|
inContainer = true;
|
|
6798
6925
|
}
|
|
6799
6926
|
return scope2;
|
|
@@ -6805,7 +6932,7 @@ var stripVirtualFilterOperator = (key, value, scope2) => {
|
|
|
6805
6932
|
}
|
|
6806
6933
|
if (key === "$all") {
|
|
6807
6934
|
return rewriteFilterClauses(value, (entry) => {
|
|
6808
|
-
if (!(0,
|
|
6935
|
+
if (!(0, import_utils21.isPlainObject)(entry) || Object.keys(entry).length !== 1 || !Object.hasOwn(entry, "$elemMatch")) return entry;
|
|
6809
6936
|
return rewriteFilterObject(entry, (operator, operand) => stripVirtualFilterOperator(operator, operand, scope2));
|
|
6810
6937
|
});
|
|
6811
6938
|
}
|
|
@@ -6820,7 +6947,7 @@ var stripVirtualFilterQuery = (value, scope2, element = false) => {
|
|
|
6820
6947
|
if (isOperatorKey(key)) return element ? stripVirtualFilterOperator(key, child, scope2) : child;
|
|
6821
6948
|
const fieldScope = resolveVirtualFilterField(key, scope2);
|
|
6822
6949
|
if (fieldScope === REMOVED_VIRTUAL_FILTER) return REMOVED_VIRTUAL_FILTER;
|
|
6823
|
-
if (!fieldScope || !(0,
|
|
6950
|
+
if (!fieldScope || !(0, import_utils21.isPlainObject)(child)) return child;
|
|
6824
6951
|
if (Object.keys(child).some(isOperatorKey)) {
|
|
6825
6952
|
return rewriteFilterObject(
|
|
6826
6953
|
child,
|
|
@@ -6842,9 +6969,9 @@ var stripSubVirtualKeysFromFilter = (filter2, snapshot, sub) => {
|
|
|
6842
6969
|
function getCorrelatedTemplateDepth(includes) {
|
|
6843
6970
|
let max = 0;
|
|
6844
6971
|
const visit = (entries, depth) => {
|
|
6845
|
-
const list = (0,
|
|
6972
|
+
const list = (0, import_utils21.castArray)(entries).filter(Boolean);
|
|
6846
6973
|
for (const entry of list) {
|
|
6847
|
-
if (!(0,
|
|
6974
|
+
if (!(0, import_utils21.isPlainObject)(entry)) continue;
|
|
6848
6975
|
max = Math.max(max, depth);
|
|
6849
6976
|
const nested = entry.args?.include;
|
|
6850
6977
|
if (nested !== void 0) {
|
|
@@ -6869,11 +6996,11 @@ function validateClientFilter(filter2) {
|
|
|
6869
6996
|
}
|
|
6870
6997
|
const blockedOperators = /* @__PURE__ */ new Set(["$where", "$expr", "$function", "$accumulator"]);
|
|
6871
6998
|
const visit = (value, path) => {
|
|
6872
|
-
if ((0,
|
|
6999
|
+
if ((0, import_utils21.isArray)(value)) {
|
|
6873
7000
|
value.forEach((item, index) => visit(item, `${path}[${index}]`));
|
|
6874
7001
|
return;
|
|
6875
7002
|
}
|
|
6876
|
-
if (!(0,
|
|
7003
|
+
if (!(0, import_utils21.isPlainObject)(value)) return;
|
|
6877
7004
|
Object.entries(value).forEach(([key, child]) => {
|
|
6878
7005
|
const nextPath = path ? `${path}.${key}` : key;
|
|
6879
7006
|
if (blockedOperators.has(key)) {
|
|
@@ -7042,24 +7169,32 @@ var Base = class {
|
|
|
7042
7169
|
relatedExecution(svc, include, parentAuthorization) {
|
|
7043
7170
|
const op = include.op;
|
|
7044
7171
|
if (!parentAuthorization)
|
|
7045
|
-
return
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7172
|
+
return withExecutionHydration(
|
|
7173
|
+
svc,
|
|
7174
|
+
createServiceExecution(svc, {
|
|
7175
|
+
operation: op,
|
|
7176
|
+
rowAccess: op,
|
|
7177
|
+
virtualAccess: op,
|
|
7178
|
+
outputAccess: op,
|
|
7179
|
+
docPermissionsAccess: op
|
|
7180
|
+
}),
|
|
7181
|
+
"lean"
|
|
7182
|
+
);
|
|
7183
|
+
return withExecutionHydration(
|
|
7053
7184
|
svc,
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7185
|
+
createRelatedExecution(
|
|
7186
|
+
svc,
|
|
7187
|
+
{ operation: op, rowAccess: op, virtualAccess: op, outputAccess: op, docPermissionsAccess: op },
|
|
7188
|
+
parentAuthorization,
|
|
7189
|
+
this.relatedBinding(),
|
|
7190
|
+
include.path
|
|
7191
|
+
),
|
|
7192
|
+
"lean"
|
|
7058
7193
|
);
|
|
7059
7194
|
}
|
|
7060
7195
|
processInclude(include) {
|
|
7061
7196
|
assertPublicAdmission(include, "include");
|
|
7062
|
-
const items = (0,
|
|
7197
|
+
const items = (0, import_utils21.compact)((0, import_utils21.castArray)(include));
|
|
7063
7198
|
const legacy = [];
|
|
7064
7199
|
const correlated = [];
|
|
7065
7200
|
const correlatedReferenceFields = [];
|
|
@@ -7094,23 +7229,23 @@ var Base = class {
|
|
|
7094
7229
|
this.assertIncludeOutputPaths([...legacy, ...correlated]);
|
|
7095
7230
|
let includeLocalFields = [];
|
|
7096
7231
|
let includePaths = [];
|
|
7097
|
-
(0,
|
|
7232
|
+
(0, import_utils21.forEach)(legacy, (inc) => {
|
|
7098
7233
|
includeLocalFields.push(inc.localField);
|
|
7099
7234
|
includePaths.push(inc.path);
|
|
7100
7235
|
});
|
|
7101
|
-
includeLocalFields = (0,
|
|
7102
|
-
includePaths = (0,
|
|
7236
|
+
includeLocalFields = (0, import_utils21.uniq)((0, import_utils21.compact)(includeLocalFields));
|
|
7237
|
+
includePaths = (0, import_utils21.uniq)((0, import_utils21.compact)(includePaths));
|
|
7103
7238
|
return {
|
|
7104
7239
|
includes: legacy,
|
|
7105
7240
|
correlatedIncludes: correlated,
|
|
7106
7241
|
includeLocalFields,
|
|
7107
7242
|
includePaths,
|
|
7108
|
-
correlatedReferenceFields: (0,
|
|
7243
|
+
correlatedReferenceFields: (0, import_utils21.uniq)((0, import_utils21.compact)(correlatedReferenceFields))
|
|
7109
7244
|
};
|
|
7110
7245
|
}
|
|
7111
7246
|
validateIncludeOutputPath(path, modelName) {
|
|
7112
7247
|
const permissionField = getModelOption(modelName, "documentPermissionField");
|
|
7113
|
-
if ((0,
|
|
7248
|
+
if ((0, import_utils21.get)((0, import_utils21.set)({}, path, true), permissionField) !== void 0 || (0, import_utils21.get)((0, import_utils21.set)({}, permissionField, true), path) !== void 0) {
|
|
7114
7249
|
this.throwClientRequestError(
|
|
7115
7250
|
"bad_request" /* BadRequest */,
|
|
7116
7251
|
`Include output path ${path} overlaps document permission field ${permissionField} on model ${modelName}`
|
|
@@ -7135,9 +7270,9 @@ var Base = class {
|
|
|
7135
7270
|
const walk = (node, prefix) => {
|
|
7136
7271
|
for (const [key, value] of Object.entries(node)) {
|
|
7137
7272
|
if (value === void 0) continue;
|
|
7138
|
-
if ((0,
|
|
7273
|
+
if ((0, import_utils21.isPlainObject)(value) && "sub" in value) {
|
|
7139
7274
|
const sub = value.sub;
|
|
7140
|
-
if ((0,
|
|
7275
|
+
if ((0, import_utils21.isPlainObject)(sub)) walk(sub, prefix ? `${prefix}.${key}` : key);
|
|
7141
7276
|
continue;
|
|
7142
7277
|
}
|
|
7143
7278
|
out.push(prefix ? `${prefix}.${key}` : key);
|
|
@@ -7190,7 +7325,7 @@ var Base = class {
|
|
|
7190
7325
|
this.throwClientRequestError("bad_request" /* BadRequest */, `Model ${modelName} not found`);
|
|
7191
7326
|
}
|
|
7192
7327
|
for (const entry of entries) {
|
|
7193
|
-
if (!(0,
|
|
7328
|
+
if (!(0, import_utils21.isPlainObject)(entry)) continue;
|
|
7194
7329
|
const models = visited.get(entry) ?? /* @__PURE__ */ new Set();
|
|
7195
7330
|
if (models.has(modelName)) continue;
|
|
7196
7331
|
models.add(modelName);
|
|
@@ -7200,13 +7335,13 @@ var Base = class {
|
|
|
7200
7335
|
}
|
|
7201
7336
|
if ((entry.op === "read" || entry.op === "list") && typeof entry.model === "string") {
|
|
7202
7337
|
const nested = entry.args?.include;
|
|
7203
|
-
if (nested) pending.push({ entries: (0,
|
|
7338
|
+
if (nested) pending.push({ entries: (0, import_utils21.compact)((0, import_utils21.castArray)(nested)), modelName: entry.model });
|
|
7204
7339
|
}
|
|
7205
7340
|
}
|
|
7206
7341
|
}
|
|
7207
7342
|
}
|
|
7208
7343
|
getForeignKeyValues(value) {
|
|
7209
|
-
return (0,
|
|
7344
|
+
return (0, import_utils21.flatten)((0, import_utils21.castArray)(value));
|
|
7210
7345
|
}
|
|
7211
7346
|
getForeignKey(value) {
|
|
7212
7347
|
return String(value);
|
|
@@ -7214,7 +7349,7 @@ var Base = class {
|
|
|
7214
7349
|
buildForeignKeyIndex(rows, foreignField) {
|
|
7215
7350
|
const index = /* @__PURE__ */ new Map();
|
|
7216
7351
|
for (const row of rows) {
|
|
7217
|
-
for (const value of this.getForeignKeyValues((0,
|
|
7352
|
+
for (const value of this.getForeignKeyValues((0, import_utils21.get)(row, foreignField))) {
|
|
7218
7353
|
const key = this.getForeignKey(value);
|
|
7219
7354
|
const values = index.get(key);
|
|
7220
7355
|
if (values) values.push(row);
|
|
@@ -7250,9 +7385,9 @@ var Base = class {
|
|
|
7250
7385
|
async includeDocs(docs, include, parentAuthorization) {
|
|
7251
7386
|
assertPublicAdmission(include, "include");
|
|
7252
7387
|
if (!include) return docs;
|
|
7253
|
-
const includes = (0,
|
|
7388
|
+
const includes = (0, import_utils21.compact)((0, import_utils21.castArray)(include));
|
|
7254
7389
|
if (includes.length === 0) return docs;
|
|
7255
|
-
const isSingle = !(0,
|
|
7390
|
+
const isSingle = !(0, import_utils21.isArray)(docs);
|
|
7256
7391
|
let docList = (isSingle ? [docs] : docs).map(prepareIncludeOutput);
|
|
7257
7392
|
for (let x = 0; x < includes.length; x++) {
|
|
7258
7393
|
const include2 = includes[x];
|
|
@@ -7282,7 +7417,7 @@ var Base = class {
|
|
|
7282
7417
|
const svc = await this.getAuthorizedTargetService(model, "read", path, parentAuthorization);
|
|
7283
7418
|
for (let y = 0; y < docs.length; y++) {
|
|
7284
7419
|
const doc = docs[y];
|
|
7285
|
-
const localValue = (0,
|
|
7420
|
+
const localValue = (0, import_utils21.get)(doc, localField);
|
|
7286
7421
|
const execution = this.relatedExecution(svc, include, parentAuthorization);
|
|
7287
7422
|
const prepared = await prepareModelQuery(
|
|
7288
7423
|
svc,
|
|
@@ -7296,7 +7431,6 @@ var Base = class {
|
|
|
7296
7431
|
skim,
|
|
7297
7432
|
populateAccess,
|
|
7298
7433
|
access: "read",
|
|
7299
|
-
lean: true,
|
|
7300
7434
|
includePermissions: false,
|
|
7301
7435
|
includeFieldPermissions: false
|
|
7302
7436
|
});
|
|
@@ -7318,15 +7452,15 @@ var Base = class {
|
|
|
7318
7452
|
const { model, op, path, localField, foreignField, filter: _filters, args = {}, options = {} } = include;
|
|
7319
7453
|
const svc = await this.getAuthorizedTargetService(model, op, path, parentAuthorization);
|
|
7320
7454
|
const includeLocalValues = [];
|
|
7321
|
-
(0,
|
|
7322
|
-
includeLocalValues.push(...this.getForeignKeyValues((0,
|
|
7455
|
+
(0, import_utils21.forEach)(docs, (doc) => {
|
|
7456
|
+
includeLocalValues.push(...this.getForeignKeyValues((0, import_utils21.get)(doc, localField)));
|
|
7323
7457
|
});
|
|
7324
7458
|
const execution = this.relatedExecution(svc, include, parentAuthorization);
|
|
7325
7459
|
const prepared = await prepareModelQuery(
|
|
7326
7460
|
svc,
|
|
7327
7461
|
execution,
|
|
7328
7462
|
{ kind: "client-read", filter: _filters ?? {} },
|
|
7329
|
-
{ [foreignField]: { $in: (0,
|
|
7463
|
+
{ [foreignField]: { $in: (0, import_utils21.flatten)(includeLocalValues) } },
|
|
7330
7464
|
true
|
|
7331
7465
|
);
|
|
7332
7466
|
const trustedArgs = this.sanitizeIncludeArgs(args, "list");
|
|
@@ -7335,7 +7469,6 @@ var Base = class {
|
|
|
7335
7469
|
...requestOnlyServiceOptions({
|
|
7336
7470
|
skim,
|
|
7337
7471
|
populateAccess,
|
|
7338
|
-
lean: true,
|
|
7339
7472
|
includePermissions: false,
|
|
7340
7473
|
includeFieldPermissions: false,
|
|
7341
7474
|
includeCount: false
|
|
@@ -7370,7 +7503,7 @@ var Base = class {
|
|
|
7370
7503
|
}
|
|
7371
7504
|
for (let y = 0; y < docs.length; y++) {
|
|
7372
7505
|
const doc = docs[y];
|
|
7373
|
-
const matches = this.getIndexedMatches(index, (0,
|
|
7506
|
+
const matches = this.getIndexedMatches(index, (0, import_utils21.get)(doc, localField));
|
|
7374
7507
|
const isolated = matches.map((m) => copyAuthorizedOutput(m));
|
|
7375
7508
|
attachIncludeOutput(doc, path, op === "list" ? isolated : isolated[0]);
|
|
7376
7509
|
}
|
|
@@ -7379,7 +7512,7 @@ var Base = class {
|
|
|
7379
7512
|
async includeDocsCount(docs, include, parentAuthorization) {
|
|
7380
7513
|
const { model, path, localField, foreignField, filter: _filters } = include;
|
|
7381
7514
|
const svc = await this.getAuthorizedTargetService(model, "count", path, parentAuthorization);
|
|
7382
|
-
const groups = prepareCountGroups(docs, (doc) => (0,
|
|
7515
|
+
const groups = prepareCountGroups(docs, (doc) => (0, import_utils21.get)(doc, localField));
|
|
7383
7516
|
const execution = this.relatedExecution(svc, include, parentAuthorization);
|
|
7384
7517
|
const prepared = await prepareModelQuery(
|
|
7385
7518
|
svc,
|
|
@@ -7433,7 +7566,7 @@ var Base = class {
|
|
|
7433
7566
|
}
|
|
7434
7567
|
const state = this.getCorrelatedExecState();
|
|
7435
7568
|
docs = docs.map(prepareIncludeOutput);
|
|
7436
|
-
const resolvedSnapshots = snapshots ?? docs.map((doc) => (0,
|
|
7569
|
+
const resolvedSnapshots = snapshots ?? docs.map((doc) => (0, import_utils21.cloneDeep)(toObject(getIncludeSource(doc))));
|
|
7437
7570
|
for (const include of correlatedIncludes) {
|
|
7438
7571
|
switch (include.op) {
|
|
7439
7572
|
case "read":
|
|
@@ -7510,7 +7643,6 @@ var Base = class {
|
|
|
7510
7643
|
},
|
|
7511
7644
|
requestOnlyServiceOptions({
|
|
7512
7645
|
access: "read",
|
|
7513
|
-
lean: true,
|
|
7514
7646
|
includePermissions: false,
|
|
7515
7647
|
includeFieldPermissions: false
|
|
7516
7648
|
})
|
|
@@ -7585,7 +7717,6 @@ var Base = class {
|
|
|
7585
7717
|
},
|
|
7586
7718
|
requestOnlyServiceOptions({
|
|
7587
7719
|
access: "read",
|
|
7588
|
-
lean: true,
|
|
7589
7720
|
includePermissions: false,
|
|
7590
7721
|
includeFieldPermissions: false
|
|
7591
7722
|
})
|
|
@@ -7670,7 +7801,6 @@ var Base = class {
|
|
|
7670
7801
|
},
|
|
7671
7802
|
requestOnlyServiceOptions({
|
|
7672
7803
|
includeCount: false,
|
|
7673
|
-
lean: true,
|
|
7674
7804
|
includePermissions: false,
|
|
7675
7805
|
includeFieldPermissions: false
|
|
7676
7806
|
})
|
|
@@ -7785,10 +7915,10 @@ var Base = class {
|
|
|
7785
7915
|
}
|
|
7786
7916
|
let ret = result2.data;
|
|
7787
7917
|
if (sqOptions.path) {
|
|
7788
|
-
ret = (0,
|
|
7918
|
+
ret = (0, import_utils21.isArray)(ret) ? (0, import_utils21.flatten)(ret.map((v) => (0, import_utils21.get)(v, sqOptions.path))) : (0, import_utils21.get)(ret, sqOptions.path);
|
|
7789
7919
|
}
|
|
7790
7920
|
if (sqOptions.compact) {
|
|
7791
|
-
ret = (0,
|
|
7921
|
+
ret = (0, import_utils21.compact)((0, import_utils21.castArray)(ret));
|
|
7792
7922
|
}
|
|
7793
7923
|
return ret;
|
|
7794
7924
|
}
|
|
@@ -7800,11 +7930,11 @@ var Base = class {
|
|
|
7800
7930
|
};
|
|
7801
7931
|
|
|
7802
7932
|
// src/services/service.ts
|
|
7803
|
-
var
|
|
7933
|
+
var import_utils31 = require("@web-ts-toolkit/utils");
|
|
7804
7934
|
var import_just_diff = require("just-diff");
|
|
7805
7935
|
|
|
7806
7936
|
// src/model.ts
|
|
7807
|
-
var
|
|
7937
|
+
var import_utils22 = require("@web-ts-toolkit/utils");
|
|
7808
7938
|
init_runtime_context();
|
|
7809
7939
|
init_runtime();
|
|
7810
7940
|
function admitModelPersistence(adapter, scheduler) {
|
|
@@ -7880,7 +8010,7 @@ var Model = class {
|
|
|
7880
8010
|
}
|
|
7881
8011
|
/** Cast a copy using this model's query schema/setters, without executing query middleware or persistence. */
|
|
7882
8012
|
castFilter(filter2) {
|
|
7883
|
-
const query = this.mongooseModel.countDocuments((0,
|
|
8013
|
+
const query = this.mongooseModel.countDocuments((0, import_utils22.cloneDeep)(filter2));
|
|
7884
8014
|
return query.cast(this.mongooseModel);
|
|
7885
8015
|
}
|
|
7886
8016
|
// see https://mongoosejs.com/docs/api.html#model_Model.distinct
|
|
@@ -7894,7 +8024,7 @@ var Model = class {
|
|
|
7894
8024
|
var model_default = Model;
|
|
7895
8025
|
|
|
7896
8026
|
// src/acl/distinct-field-authorization.ts
|
|
7897
|
-
var
|
|
8027
|
+
var import_utils23 = require("@web-ts-toolkit/utils");
|
|
7898
8028
|
init_field_authorization();
|
|
7899
8029
|
init_field_catalog();
|
|
7900
8030
|
var schemaVariants = (schema) => Object.values(schema.discriminators ?? {});
|
|
@@ -7976,8 +8106,8 @@ function isDistinctFieldAuthorized(args) {
|
|
|
7976
8106
|
if (path !== field && !path.startsWith(`${field}.`) && !field.startsWith(`${path}.`)) continue;
|
|
7977
8107
|
if (path.startsWith(`${field}.`) && (!eligible(path) || !schemaShape(schema, path) || !granted(path)))
|
|
7978
8108
|
return false;
|
|
7979
|
-
if ((0,
|
|
7980
|
-
if (!(0,
|
|
8109
|
+
if ((0, import_utils23.isPlainObject)(raw) && raw.sub !== void 0) {
|
|
8110
|
+
if (!(0, import_utils23.isPlainObject)(raw.sub) || !declaredRulesSafe(raw.sub, path, next)) return false;
|
|
7981
8111
|
}
|
|
7982
8112
|
}
|
|
7983
8113
|
return true;
|
|
@@ -8155,6 +8285,7 @@ function copySubdocumentParent(parent) {
|
|
|
8155
8285
|
init_permission();
|
|
8156
8286
|
init_core_shared();
|
|
8157
8287
|
init_finalize_model_output();
|
|
8288
|
+
init_permissions_alias();
|
|
8158
8289
|
|
|
8159
8290
|
// src/acl/populate-target.ts
|
|
8160
8291
|
var POPULATE_TARGET_PLAN = /* @__PURE__ */ Symbol("accessRouter.populateTargetPlan");
|
|
@@ -8179,7 +8310,7 @@ function getPopulateTargetMeta(entry) {
|
|
|
8179
8310
|
init_document();
|
|
8180
8311
|
|
|
8181
8312
|
// src/helpers/apply-update.ts
|
|
8182
|
-
var
|
|
8313
|
+
var import_utils26 = require("@web-ts-toolkit/utils");
|
|
8183
8314
|
init_lib();
|
|
8184
8315
|
function applyUpdate(target, data, allowedFields) {
|
|
8185
8316
|
const wholeFields = /* @__PURE__ */ new Set();
|
|
@@ -8195,17 +8326,17 @@ function applyUpdate(target, data, allowedFields) {
|
|
|
8195
8326
|
}
|
|
8196
8327
|
};
|
|
8197
8328
|
for (const field of allowedFields) {
|
|
8198
|
-
collectBoundary((0,
|
|
8329
|
+
collectBoundary((0, import_utils26.set)({}, field, true));
|
|
8199
8330
|
}
|
|
8200
8331
|
const apply = (values, prefix = "") => {
|
|
8201
8332
|
for (const [key, value] of Object.entries(values)) {
|
|
8202
8333
|
const path = prefix ? `${prefix}.${key}` : key;
|
|
8203
|
-
if (partialContainers.has(path) && !wholeFields.has(path) && ((0,
|
|
8334
|
+
if (partialContainers.has(path) && !wholeFields.has(path) && ((0, import_utils26.isPlainObject)(value) || Array.isArray(value))) {
|
|
8204
8335
|
apply(value, path);
|
|
8205
8336
|
} else if (isDocument2(target)) {
|
|
8206
8337
|
target.set(path, value);
|
|
8207
8338
|
} else {
|
|
8208
|
-
(0,
|
|
8339
|
+
(0, import_utils26.set)(target, path, value);
|
|
8209
8340
|
}
|
|
8210
8341
|
}
|
|
8211
8342
|
};
|
|
@@ -8213,7 +8344,7 @@ function applyUpdate(target, data, allowedFields) {
|
|
|
8213
8344
|
}
|
|
8214
8345
|
|
|
8215
8346
|
// src/acl/model-input-admission.ts
|
|
8216
|
-
var
|
|
8347
|
+
var import_utils28 = require("@web-ts-toolkit/utils");
|
|
8217
8348
|
var import_mongoose7 = require("mongoose");
|
|
8218
8349
|
init_document();
|
|
8219
8350
|
init_request_work();
|
|
@@ -8221,7 +8352,7 @@ init_logger_helpers();
|
|
|
8221
8352
|
init_request_complexity();
|
|
8222
8353
|
|
|
8223
8354
|
// src/acl/select-resolution.ts
|
|
8224
|
-
var
|
|
8355
|
+
var import_utils27 = require("@web-ts-toolkit/utils");
|
|
8225
8356
|
init_core_shared();
|
|
8226
8357
|
init_helpers();
|
|
8227
8358
|
async function collectAllowedFieldsForRequest({
|
|
@@ -8295,15 +8426,15 @@ async function resolveSelectForRequest({
|
|
|
8295
8426
|
const excludeall = normalizedSelect.every((v) => v.startsWith("-"));
|
|
8296
8427
|
if (excludeall) {
|
|
8297
8428
|
normalizedSelect = normalizedSelect.map((v) => v.substring(1));
|
|
8298
|
-
fields = (0,
|
|
8429
|
+
fields = (0, import_utils27.difference)(fields, normalizedSelect);
|
|
8299
8430
|
if (excludeid) fields.push("-_id");
|
|
8300
8431
|
} else {
|
|
8301
|
-
fields = (0,
|
|
8432
|
+
fields = (0, import_utils27.intersection)(normalizedSelect, fields.concat(excludeid ? "-_id" : "_id"));
|
|
8302
8433
|
}
|
|
8303
8434
|
}
|
|
8304
8435
|
return fields.concat(strippedAlways);
|
|
8305
8436
|
}
|
|
8306
|
-
return (0,
|
|
8437
|
+
return (0, import_utils27.intersection)(normalizedSelect, fields);
|
|
8307
8438
|
}
|
|
8308
8439
|
function stripVirtuals(fields, virtualNames) {
|
|
8309
8440
|
const set13 = virtualNames instanceof Set ? virtualNames : new Set(virtualNames ?? []);
|
|
@@ -8334,7 +8465,7 @@ init_field_catalog();
|
|
|
8334
8465
|
init_service_authorization();
|
|
8335
8466
|
var own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
8336
8467
|
var inside = (path, root) => path === root || path.startsWith(`${root}.`);
|
|
8337
|
-
var record = (value) => (0,
|
|
8468
|
+
var record = (value) => (0, import_utils28.isPlainObject)(value);
|
|
8338
8469
|
function inputValue(value) {
|
|
8339
8470
|
if (typeof value === "function" || typeof value === "symbol") {
|
|
8340
8471
|
authorizationError("input values must be persisted data, not functions or symbols");
|
|
@@ -8403,7 +8534,7 @@ function requestBoundaries(fields) {
|
|
|
8403
8534
|
else visit(value, path);
|
|
8404
8535
|
}
|
|
8405
8536
|
};
|
|
8406
|
-
for (const field of fields) visit((0,
|
|
8537
|
+
for (const field of fields) visit((0, import_utils28.set)({}, field, true));
|
|
8407
8538
|
return [...new Set(result2)];
|
|
8408
8539
|
}
|
|
8409
8540
|
function ownValue(data, parts) {
|
|
@@ -8533,7 +8664,7 @@ function admitModelInput(args) {
|
|
|
8533
8664
|
if (forbidden(catalog, path, requested)) continue;
|
|
8534
8665
|
const supplied = ownValue(data, parts);
|
|
8535
8666
|
if (!supplied) continue;
|
|
8536
|
-
(0,
|
|
8667
|
+
(0, import_utils28.set)(allowedData, field, copyInputValue(supplied.value, path, catalog, scopedRequests, logicalPath(field)));
|
|
8537
8668
|
selected.push(field);
|
|
8538
8669
|
}
|
|
8539
8670
|
return { allowedData, allowedFields };
|
|
@@ -8545,7 +8676,7 @@ async function requestInputFields(args) {
|
|
|
8545
8676
|
const prefix = configuration.modelPermissionPrefix ?? "";
|
|
8546
8677
|
return collectModelRequestFields({
|
|
8547
8678
|
req: args.binding.request,
|
|
8548
|
-
permissionSchema: args.scopePath ? (0,
|
|
8679
|
+
permissionSchema: args.scopePath ? (0, import_utils28.get)(configuration.permissionSchema, [args.scopePath, "sub"]) : configuration.permissionSchema,
|
|
8549
8680
|
access: args.access,
|
|
8550
8681
|
permissions,
|
|
8551
8682
|
grants,
|
|
@@ -8589,13 +8720,13 @@ init_logger_helpers();
|
|
|
8589
8720
|
init_lib();
|
|
8590
8721
|
|
|
8591
8722
|
// src/services/model-subdocument-service.ts
|
|
8592
|
-
var
|
|
8723
|
+
var import_utils30 = require("@web-ts-toolkit/utils");
|
|
8593
8724
|
init_helpers();
|
|
8594
8725
|
init_document();
|
|
8595
8726
|
init_public_admission();
|
|
8596
8727
|
|
|
8597
8728
|
// src/acl/subdocument-authorization.ts
|
|
8598
|
-
var
|
|
8729
|
+
var import_utils29 = require("@web-ts-toolkit/utils");
|
|
8599
8730
|
init_helpers();
|
|
8600
8731
|
init_document();
|
|
8601
8732
|
init_core_shared();
|
|
@@ -8782,8 +8913,8 @@ async function subdocumentGateAllowed(service, gate) {
|
|
|
8782
8913
|
let guard2;
|
|
8783
8914
|
if (access.startsWith("subs.")) {
|
|
8784
8915
|
const [, sub, op] = access.split(".");
|
|
8785
|
-
guard2 = (0,
|
|
8786
|
-
if (guard2 === void 0) guard2 = (0,
|
|
8916
|
+
guard2 = (0, import_utils29.get)(configuration, `operationAccess.${access}`);
|
|
8917
|
+
if (guard2 === void 0) guard2 = (0, import_utils29.get)(configuration, `operationAccess.subs.${sub}`);
|
|
8787
8918
|
if (guard2 === void 0) guard2 = getCapturedAuthorizationOption(configuration, `operationAccess.${op}`);
|
|
8788
8919
|
} else guard2 = getCapturedAuthorizationOption(configuration, `operationAccess.${access}`);
|
|
8789
8920
|
return evaluateRouteGuard(
|
|
@@ -8855,8 +8986,7 @@ async function mutationParent(service, id, call) {
|
|
|
8855
8986
|
const parent = await service.findRawParentDoc({
|
|
8856
8987
|
filter: filter2,
|
|
8857
8988
|
select: parentSelection(service, call),
|
|
8858
|
-
populate: []
|
|
8859
|
-
lean: false
|
|
8989
|
+
populate: []
|
|
8860
8990
|
});
|
|
8861
8991
|
return parent ? { parent } : { error: denied2("not_found" /* NotFound */) };
|
|
8862
8992
|
}
|
|
@@ -8905,18 +9035,17 @@ async function visibleMutationRows(service, call, parentId, rows) {
|
|
|
8905
9035
|
const identity = { _id: parentId };
|
|
8906
9036
|
const filter2 = await subdocumentRows(service, visibility.parent, identity, identity);
|
|
8907
9037
|
if (filter2 === false) return [];
|
|
8908
|
-
const parent = await service.
|
|
9038
|
+
const parent = await getServiceExecutors(service).subdocumentVisibility({
|
|
8909
9039
|
filter: filter2,
|
|
8910
9040
|
select: parentSelection(service, call),
|
|
8911
|
-
populate: []
|
|
8912
|
-
lean: true
|
|
9041
|
+
populate: []
|
|
8913
9042
|
});
|
|
8914
9043
|
if (!parent) return [];
|
|
8915
9044
|
const selected = call.method === "create" ? {} : { _id: { $in: rows.map((row) => row._id) } };
|
|
8916
9045
|
const read = await subdocumentRows(service, visibility.child, selected, selected, call.sub);
|
|
8917
9046
|
const list = visibility.list ? await subdocumentRows(service, visibility.list, {}, {}, call.sub) : {};
|
|
8918
9047
|
if (read === false || list === false) return [];
|
|
8919
|
-
const visible = filterCollection((0,
|
|
9048
|
+
const visible = filterCollection((0, import_utils30.get)(parent, call.sub), intersectFilters(read, list));
|
|
8920
9049
|
return await finalizeSubdocumentRows(service, call.output, parent, visible);
|
|
8921
9050
|
} catch {
|
|
8922
9051
|
return [];
|
|
@@ -8937,11 +9066,10 @@ async function listSub(service, id, sub, options) {
|
|
|
8937
9066
|
const parent = await service.findRawParentDoc({
|
|
8938
9067
|
filter: filter2,
|
|
8939
9068
|
select: parentSelection(service, call),
|
|
8940
|
-
populate: []
|
|
8941
|
-
lean: false
|
|
9069
|
+
populate: []
|
|
8942
9070
|
});
|
|
8943
9071
|
if (!parent) return denied2("not_found" /* NotFound */);
|
|
8944
|
-
const rows = filterCollection((0,
|
|
9072
|
+
const rows = filterCollection((0, import_utils30.get)(parent, sub), childFilter);
|
|
8945
9073
|
const data = await finalizeSubdocumentRows(service, call.output, parent, rows);
|
|
8946
9074
|
return { success: true, kind: "list", code: "success" /* Success */, data, count: data.length };
|
|
8947
9075
|
});
|
|
@@ -8960,11 +9088,10 @@ async function readSub(service, id, sub, subId, options) {
|
|
|
8960
9088
|
const parent = await service.findRawParentDoc({
|
|
8961
9089
|
filter: filter2,
|
|
8962
9090
|
select: parentSelection(service, call),
|
|
8963
|
-
populate: entries
|
|
8964
|
-
lean: false
|
|
9091
|
+
populate: entries
|
|
8965
9092
|
});
|
|
8966
9093
|
if (!parent) return denied2("not_found" /* NotFound */);
|
|
8967
|
-
const row = findElement((0,
|
|
9094
|
+
const row = findElement((0, import_utils30.get)(copySubdocumentParent(parent), sub), childFilter);
|
|
8968
9095
|
if (!row) return denied2("not_found" /* NotFound */);
|
|
8969
9096
|
await service.finalizePopulateForSubParent({ [sub]: [row] }, entries, "subRead");
|
|
8970
9097
|
const data = await finalizeSubdocumentRows(service, call.output, parent, [row]);
|
|
@@ -8984,7 +9111,7 @@ async function updateSub(service, persist, id, sub, subId, data, options) {
|
|
|
8984
9111
|
const identity = { _id: subId };
|
|
8985
9112
|
const filter2 = await subdocumentRows(service, call.child, identity, identity, sub);
|
|
8986
9113
|
if (filter2 === false) return denied2();
|
|
8987
|
-
const row = findElement((0,
|
|
9114
|
+
const row = findElement((0, import_utils30.get)(parent, sub), filter2);
|
|
8988
9115
|
if (!row) return denied2("not_found" /* NotFound */);
|
|
8989
9116
|
const original = isolateDocForOutput(row);
|
|
8990
9117
|
const admit = await inputAdmission(service, call, parent);
|
|
@@ -9011,7 +9138,7 @@ async function bulkUpdateSub(service, persist, id, sub, data, options) {
|
|
|
9011
9138
|
const selected = { _id: { $in: data.map((row) => row._id) } };
|
|
9012
9139
|
const filter2 = await subdocumentRows(service, call.child, selected, selected, sub);
|
|
9013
9140
|
if (filter2 === false) return denied2();
|
|
9014
|
-
const rows = filterCollection((0,
|
|
9141
|
+
const rows = filterCollection((0, import_utils30.get)(parent, sub), filter2);
|
|
9015
9142
|
const originals = rows.map((row) => isolateDocForOutput(row));
|
|
9016
9143
|
const admit = await inputAdmission(service, call, parent);
|
|
9017
9144
|
for (const [index, row] of rows.entries()) {
|
|
@@ -9039,7 +9166,7 @@ async function createSub(service, persist, id, sub, data, options) {
|
|
|
9039
9166
|
const lookup = await mutationParent(service, id, call);
|
|
9040
9167
|
if ("error" in lookup) return lookup.error;
|
|
9041
9168
|
const { parent } = lookup;
|
|
9042
|
-
const rows = (0,
|
|
9169
|
+
const rows = (0, import_utils30.get)(parent, sub);
|
|
9043
9170
|
const admit = await inputAdmission(service, call, parent);
|
|
9044
9171
|
const allowed = (Array.isArray(data) ? data : [data]).map((row) => admit(row).allowedData);
|
|
9045
9172
|
if (options?.addFirst) rows.unshift(...allowed);
|
|
@@ -9060,7 +9187,7 @@ async function deleteSub(service, persist, id, sub, subId, options) {
|
|
|
9060
9187
|
const identity = { _id: subId };
|
|
9061
9188
|
const filter2 = await subdocumentRows(service, call.child, identity, identity, sub);
|
|
9062
9189
|
if (filter2 === false) return denied2();
|
|
9063
|
-
const row = findElement((0,
|
|
9190
|
+
const row = findElement((0, import_utils30.get)(parent, sub), filter2);
|
|
9064
9191
|
if (!row) return denied2("not_found" /* NotFound */);
|
|
9065
9192
|
await ("deleteOne" in row ? row.deleteOne?.() : row.remove?.());
|
|
9066
9193
|
await persist(() => parent.save());
|
|
@@ -9069,7 +9196,7 @@ async function deleteSub(service, persist, id, sub, subId, options) {
|
|
|
9069
9196
|
}
|
|
9070
9197
|
async function getParentDoc(service, id, sub, args, options) {
|
|
9071
9198
|
assertPublicAdmission({ args, options });
|
|
9072
|
-
const { access = "read"
|
|
9199
|
+
const { access = "read" } = options ?? {};
|
|
9073
9200
|
const identity = deepIsolateValue(await service.genIDFilter(id));
|
|
9074
9201
|
const filter2 = intersectFilters(identity, await service.genFilter(access, deepIsolateValue(identity)));
|
|
9075
9202
|
if (filter2 === false) return null;
|
|
@@ -9077,8 +9204,7 @@ async function getParentDoc(service, id, sub, args, options) {
|
|
|
9077
9204
|
return service.findRawParentDoc({
|
|
9078
9205
|
filter: filter2,
|
|
9079
9206
|
select: access === "read" ? "" : sub,
|
|
9080
|
-
populate
|
|
9081
|
-
lean
|
|
9207
|
+
populate
|
|
9082
9208
|
});
|
|
9083
9209
|
}
|
|
9084
9210
|
|
|
@@ -9108,8 +9234,7 @@ function resolveFindOneOptions(service, options = {}) {
|
|
|
9108
9234
|
includePermissions,
|
|
9109
9235
|
includeFieldPermissions: options.includeFieldPermissions ?? service.defaults.findOneOptions?.includeFieldPermissions ?? includePermissions,
|
|
9110
9236
|
access: options.access ?? service.defaults.findOneOptions?.access ?? "read",
|
|
9111
|
-
populateAccess: options.populateAccess ?? service.defaults.findOneOptions?.populateAccess
|
|
9112
|
-
lean: options.lean ?? service.defaults.findOneOptions?.lean ?? false
|
|
9237
|
+
populateAccess: options.populateAccess ?? service.defaults.findOneOptions?.populateAccess
|
|
9113
9238
|
});
|
|
9114
9239
|
}
|
|
9115
9240
|
function resolveFindByIdArgs(service, args = {}) {
|
|
@@ -9126,8 +9251,7 @@ function resolveFindByIdOptions(service, options = {}) {
|
|
|
9126
9251
|
includePermissions,
|
|
9127
9252
|
includeFieldPermissions: options.includeFieldPermissions ?? service.defaults.findByIdOptions?.includeFieldPermissions ?? includePermissions,
|
|
9128
9253
|
access: options.access ?? service.defaults.findByIdOptions?.access ?? "read",
|
|
9129
|
-
populateAccess: options.populateAccess ?? service.defaults.findByIdOptions?.populateAccess
|
|
9130
|
-
lean: options.lean ?? service.defaults.findByIdOptions?.lean ?? false
|
|
9254
|
+
populateAccess: options.populateAccess ?? service.defaults.findByIdOptions?.populateAccess
|
|
9131
9255
|
});
|
|
9132
9256
|
}
|
|
9133
9257
|
function resolveFindArgs(service, args = {}) {
|
|
@@ -9149,8 +9273,7 @@ function resolveFindOptions(service, options = {}) {
|
|
|
9149
9273
|
includePermissions,
|
|
9150
9274
|
includeFieldPermissions: options.includeFieldPermissions ?? service.defaults.findOptions?.includeFieldPermissions ?? includePermissions,
|
|
9151
9275
|
includeCount: options.includeCount ?? service.defaults.findOptions?.includeCount ?? false,
|
|
9152
|
-
populateAccess: options.populateAccess ?? service.defaults.findOptions?.populateAccess ?? "read"
|
|
9153
|
-
lean: options.lean ?? service.defaults.findOptions?.lean ?? false
|
|
9276
|
+
populateAccess: options.populateAccess ?? service.defaults.findOptions?.populateAccess ?? "read"
|
|
9154
9277
|
});
|
|
9155
9278
|
}
|
|
9156
9279
|
function resolveCreateArgs(service, args = {}) {
|
|
@@ -9264,7 +9387,7 @@ var Service = class extends Base {
|
|
|
9264
9387
|
model: this.model.mongooseModel,
|
|
9265
9388
|
modelName: this.modelName
|
|
9266
9389
|
}),
|
|
9267
|
-
configuration: () => this.requestRuntime.getModelInstance(this.modelName) ? captureModelAuthorizationConfiguration(this.requestRuntime, this.modelName) : { catalog: { paths: [] }, ...this.options },
|
|
9390
|
+
configuration: () => this.requestRuntime.getModelInstance(this.modelName) ? captureModelAuthorizationConfiguration(this.requestRuntime, this.modelName, this.options) : { catalog: { paths: [] }, ...this.options },
|
|
9268
9391
|
permissions: () => this.requestCore.getPermissions?.() ?? new permission_default({}),
|
|
9269
9392
|
parse: (filter2) => this.parseClientData(filter2, this.getCorrelatedExecState().scheduler),
|
|
9270
9393
|
validate: (filter2, expanded) => {
|
|
@@ -9308,26 +9431,37 @@ var Service = class extends Base {
|
|
|
9308
9431
|
data: await this.model.countDocuments(filter2),
|
|
9309
9432
|
query: { filter: filter2 }
|
|
9310
9433
|
}),
|
|
9311
|
-
groupedCount: (filter2, field, input) => this.countPreparedByFieldValueGroups(field, input, filter2)
|
|
9434
|
+
groupedCount: (filter2, field, input) => this.countPreparedByFieldValueGroups(field, input, filter2),
|
|
9435
|
+
subdocumentVisibility: ({ filter: filter2, select, populate }) => this.model.findOne({ filter: filter2, select, populate, lean: true })
|
|
9312
9436
|
});
|
|
9313
9437
|
}
|
|
9314
9438
|
get options() {
|
|
9315
9439
|
return modelServiceOptions(this, () => this.getModelRouterOptions(this.modelName));
|
|
9316
9440
|
}
|
|
9441
|
+
/**
|
|
9442
|
+
* Presentation/query defaults for this service instance; an explicit assignment
|
|
9443
|
+
* replaces the runtime defaults bag, not a per-bucket merge. Fetch mode belongs
|
|
9444
|
+
* to the owning model's hydration configuration and affects all its services.
|
|
9445
|
+
* Legacy method-option lean/hydration keys throw on assignment and before calls
|
|
9446
|
+
* if an assigned JavaScript bag is later mutated.
|
|
9447
|
+
*/
|
|
9317
9448
|
get defaults() {
|
|
9318
9449
|
return this.defaultsOverride ?? this.options.defaults ?? {};
|
|
9319
9450
|
}
|
|
9320
9451
|
set defaults(value) {
|
|
9452
|
+
assertHydrationDefaults(value);
|
|
9321
9453
|
this.defaultsOverride = value;
|
|
9322
9454
|
}
|
|
9323
9455
|
get baseFieldsExt() {
|
|
9324
9456
|
return this.baseFields.concat(this.options.documentPermissionField);
|
|
9325
9457
|
}
|
|
9458
|
+
/** Raw hydrated parent/null. Fetch mode is fixed, independent of model read settings. */
|
|
9326
9459
|
findRawParentDoc(args) {
|
|
9327
9460
|
return this.model.findOne({
|
|
9328
|
-
...args,
|
|
9329
9461
|
filter: args.filter,
|
|
9330
|
-
|
|
9462
|
+
select: args.select,
|
|
9463
|
+
populate: args.populate,
|
|
9464
|
+
lean: false
|
|
9331
9465
|
});
|
|
9332
9466
|
}
|
|
9333
9467
|
createModelAdapter(modelName) {
|
|
@@ -9432,23 +9566,34 @@ var Service = class extends Base {
|
|
|
9432
9566
|
}
|
|
9433
9567
|
});
|
|
9434
9568
|
const output = deepIsolateValue(finalized);
|
|
9569
|
+
removeGeneratedPermissionsAlias(output);
|
|
9435
9570
|
const includeOrigins = restoreIncludeOutput(args.doc, output);
|
|
9436
9571
|
const field = configuration.documentPermissionField ?? "_permissions";
|
|
9437
9572
|
unsetDocPath(output, field);
|
|
9438
9573
|
if (!configuration.stripPermissionsField) {
|
|
9439
|
-
(0,
|
|
9574
|
+
(0, import_utils31.set)(output, field, args.includePermissions || args.includeFieldPermissions ? deepIsolateValue(grants) : {});
|
|
9440
9575
|
if (args.includeFieldPermissions && !configuration.disableFieldPermissions) {
|
|
9441
9576
|
const rowAccess = this.asServiceHookContext(context).fieldPermissionAccess ?? await this.getFieldPermissionAccess([snapshot._id]);
|
|
9442
9577
|
const id = String(snapshot._id);
|
|
9443
9578
|
const views = rowAccess.readIds?.has(id) ? await requestOutputFieldPaths(handle, binding, "read") : [];
|
|
9444
9579
|
const edits = rowAccess.updateIds?.has(id) ? await requestOutputFieldPaths(handle, binding, "update") : [];
|
|
9445
9580
|
const map2 = (paths) => paths.length ? Object.fromEntries(paths.map((path) => [path, true])) : { $: "_" };
|
|
9446
|
-
(0,
|
|
9447
|
-
(0,
|
|
9448
|
-
} else if (!args.includePermissions)
|
|
9449
|
-
|
|
9581
|
+
(0, import_utils31.set)(output, `${field}._view`, map2(views));
|
|
9582
|
+
(0, import_utils31.set)(output, `${field}._edit`, map2(edits));
|
|
9583
|
+
} else if (!args.includePermissions) (0, import_utils31.set)(output, field, { _view: { $: "_" }, _edit: { $: "_" } });
|
|
9584
|
+
const exposed = configuration.exposedDocPermissionKeys;
|
|
9585
|
+
if (exposed) {
|
|
9586
|
+
const metadata = (0, import_utils31.get)(output, field);
|
|
9587
|
+
(0, import_utils31.set)(
|
|
9588
|
+
output,
|
|
9589
|
+
field,
|
|
9590
|
+
Object.fromEntries(
|
|
9591
|
+
Object.entries(metadata).filter(([key]) => key === "_view" || key === "_edit" || exposed.includes(key))
|
|
9592
|
+
)
|
|
9593
|
+
);
|
|
9594
|
+
}
|
|
9595
|
+
attachPermissionsAlias(output, field);
|
|
9450
9596
|
}
|
|
9451
|
-
this.preservePermissionsVirtual(getIncludeOriginal(args.doc), output, args.lean);
|
|
9452
9597
|
transferDocumentAuthorizationGraph(finalized, output, includeOrigins);
|
|
9453
9598
|
return {
|
|
9454
9599
|
data: output,
|
|
@@ -9663,36 +9808,6 @@ var Service = class extends Base {
|
|
|
9663
9808
|
stripVirtualsFromFilterForSnapshot(filter2, snapshot) {
|
|
9664
9809
|
return stripVirtualKeysFromFilter(filter2, snapshot);
|
|
9665
9810
|
}
|
|
9666
|
-
/**
|
|
9667
|
-
* Preserve the `permissions` Mongoose virtual (from `permissionsPlugin`) for
|
|
9668
|
-
* hydrated outputs. `isolateDocForOutput` uses `toObject({ virtuals: false })`
|
|
9669
|
-
* so Mongoose getter virtuals never leak into package-virtual planning;
|
|
9670
|
-
* `lean: true` therefore drops them (explicit parity rule). For `lean: false`
|
|
9671
|
-
* (hydrated Mongoose documents) the historical contract exposes
|
|
9672
|
-
* `doc.permissions` as an alias of the document-permission field. The shared
|
|
9673
|
-
* finalizer keeps only the document-permission field, so restore the alias
|
|
9674
|
-
* here for backward compatibility when the input was hydrated and the
|
|
9675
|
-
* virtual existed. Lean outputs stay without the virtual. Models without
|
|
9676
|
-
* the plugin never had the virtual and stay unchanged.
|
|
9677
|
-
*/
|
|
9678
|
-
preservePermissionsVirtual(originalDoc, finalized, lean) {
|
|
9679
|
-
try {
|
|
9680
|
-
if (lean) return;
|
|
9681
|
-
if (!isDocument2(originalDoc)) return;
|
|
9682
|
-
const schema = originalDoc.schema;
|
|
9683
|
-
if (!schema?.virtualpath("permissions")) return;
|
|
9684
|
-
const docField = this.options?.documentPermissionField ?? "_permissions";
|
|
9685
|
-
if (docField in finalized && !("permissions" in finalized)) {
|
|
9686
|
-
Object.defineProperty(finalized, "permissions", {
|
|
9687
|
-
value: finalized[docField],
|
|
9688
|
-
enumerable: false,
|
|
9689
|
-
writable: true,
|
|
9690
|
-
configurable: true
|
|
9691
|
-
});
|
|
9692
|
-
}
|
|
9693
|
-
} catch {
|
|
9694
|
-
}
|
|
9695
|
-
}
|
|
9696
9811
|
/**
|
|
9697
9812
|
* VIRT-05 populate + association helpers.
|
|
9698
9813
|
*
|
|
@@ -9729,7 +9844,7 @@ var Service = class extends Base {
|
|
|
9729
9844
|
return docs.map((doc) => {
|
|
9730
9845
|
try {
|
|
9731
9846
|
const plain = toObject(doc);
|
|
9732
|
-
const val = (0,
|
|
9847
|
+
const val = (0, import_utils31.get)(plain, associationField);
|
|
9733
9848
|
return deepIsolateValue(val);
|
|
9734
9849
|
} catch {
|
|
9735
9850
|
return void 0;
|
|
@@ -9826,7 +9941,7 @@ var Service = class extends Base {
|
|
|
9826
9941
|
if (this.isScalarPopulateValue(rawTarget)) return rawTarget;
|
|
9827
9942
|
const isDoc = (() => {
|
|
9828
9943
|
try {
|
|
9829
|
-
if ((0,
|
|
9944
|
+
if ((0, import_utils31.isPlainObject)(rawTarget)) return true;
|
|
9830
9945
|
const maybe = rawTarget;
|
|
9831
9946
|
if (maybe && typeof maybe === "object" && "_doc" in maybe) return true;
|
|
9832
9947
|
if (maybe && typeof maybe.toObject === "function") return true;
|
|
@@ -9914,7 +10029,7 @@ var Service = class extends Base {
|
|
|
9914
10029
|
child = getDocValue(current, key);
|
|
9915
10030
|
if (child === void 0) {
|
|
9916
10031
|
try {
|
|
9917
|
-
child = (0,
|
|
10032
|
+
child = (0, import_utils31.get)(current, key);
|
|
9918
10033
|
} catch {
|
|
9919
10034
|
return;
|
|
9920
10035
|
}
|
|
@@ -10050,7 +10165,7 @@ var Service = class extends Base {
|
|
|
10050
10165
|
async findOnePrepared(execution, filter2, args, options) {
|
|
10051
10166
|
if (filter2 === false) return { success: false, kind: "error", code: "forbidden" /* Forbidden */, query: { filter: filter2 } };
|
|
10052
10167
|
const { select: requestedSelect, sort, populate, include } = this.resolveFindOneArgs(args);
|
|
10053
|
-
const { includePermissions, includeFieldPermissions, access, populateAccess
|
|
10168
|
+
const { includePermissions, includeFieldPermissions, access, populateAccess } = this.resolveFindOneOptions(options);
|
|
10054
10169
|
const state = readServiceExecution(this, execution);
|
|
10055
10170
|
const virtualSnapshot = readServiceAuthorization(state.authorization, state.binding).configuration;
|
|
10056
10171
|
let processedInclude;
|
|
@@ -10112,7 +10227,7 @@ var Service = class extends Base {
|
|
|
10112
10227
|
return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: sortErrors, query };
|
|
10113
10228
|
}
|
|
10114
10229
|
}
|
|
10115
|
-
let doc = await this.model.findOne({ ...query, select: dbSelect, lean });
|
|
10230
|
+
let doc = await this.model.findOne({ ...query, select: dbSelect, lean: state.hydration === "lean" });
|
|
10116
10231
|
if (!doc) {
|
|
10117
10232
|
this.completeOp("findOne", startedAt, "not_found" /* NotFound */, _filter);
|
|
10118
10233
|
return { success: false, kind: "error", code: "not_found" /* NotFound */, query };
|
|
@@ -10126,7 +10241,7 @@ var Service = class extends Base {
|
|
|
10126
10241
|
originalDocumentSnapshot: toObject(doc),
|
|
10127
10242
|
resolvedQuery: query
|
|
10128
10243
|
};
|
|
10129
|
-
const correlatedSnapshots = [(0,
|
|
10244
|
+
const correlatedSnapshots = [(0, import_utils31.cloneDeep)(toObject(doc))];
|
|
10130
10245
|
try {
|
|
10131
10246
|
doc = await this.includeDocs(doc, includes, state.authorization);
|
|
10132
10247
|
if (correlatedIncludes.length > 0) {
|
|
@@ -10175,7 +10290,6 @@ var Service = class extends Base {
|
|
|
10175
10290
|
context,
|
|
10176
10291
|
includePermissions,
|
|
10177
10292
|
includeFieldPermissions,
|
|
10178
|
-
lean,
|
|
10179
10293
|
sharedGate: findOneGate
|
|
10180
10294
|
});
|
|
10181
10295
|
} catch (error2) {
|
|
@@ -10200,7 +10314,7 @@ var Service = class extends Base {
|
|
|
10200
10314
|
try {
|
|
10201
10315
|
this.admitServiceCall(args, options);
|
|
10202
10316
|
const { select, populate, include } = this.resolveFindByIdArgs(args);
|
|
10203
|
-
const { skim, includePermissions, includeFieldPermissions, access, populateAccess
|
|
10317
|
+
const { skim, includePermissions, includeFieldPermissions, access, populateAccess } = this.resolveFindByIdOptions(options);
|
|
10204
10318
|
const execution = createServiceExecution(
|
|
10205
10319
|
this,
|
|
10206
10320
|
{
|
|
@@ -10212,7 +10326,11 @@ var Service = class extends Base {
|
|
|
10212
10326
|
},
|
|
10213
10327
|
options?.authorization,
|
|
10214
10328
|
"service",
|
|
10215
|
-
this.captureRelated(args, this.defaults.findByIdArgs)
|
|
10329
|
+
this.captureRelated(args, this.defaults.findByIdArgs),
|
|
10330
|
+
void 0,
|
|
10331
|
+
void 0,
|
|
10332
|
+
void 0,
|
|
10333
|
+
"findById"
|
|
10216
10334
|
);
|
|
10217
10335
|
const filter2 = readModelIdentifier(this, execution, await resolveModelIdentifier(this, execution, id));
|
|
10218
10336
|
const query = await prepareModelQuery(this, execution, { kind: "client-read", filter: filter2 });
|
|
@@ -10225,7 +10343,7 @@ var Service = class extends Base {
|
|
|
10225
10343
|
populate,
|
|
10226
10344
|
include
|
|
10227
10345
|
},
|
|
10228
|
-
{ skim, includePermissions, includeFieldPermissions, access, populateAccess
|
|
10346
|
+
{ skim, includePermissions, includeFieldPermissions, access, populateAccess }
|
|
10229
10347
|
);
|
|
10230
10348
|
} catch (error2) {
|
|
10231
10349
|
const result2 = this.getClientRequestErrorResult(error2);
|
|
@@ -10271,7 +10389,7 @@ var Service = class extends Base {
|
|
|
10271
10389
|
page,
|
|
10272
10390
|
pageSize
|
|
10273
10391
|
} = this.resolveFindArgs(args);
|
|
10274
|
-
const { includePermissions, includeFieldPermissions, includeCount, populateAccess
|
|
10392
|
+
const { includePermissions, includeFieldPermissions, includeCount, populateAccess } = this.resolveFindOptions(options);
|
|
10275
10393
|
let processedInclude;
|
|
10276
10394
|
try {
|
|
10277
10395
|
processedInclude = this.processInclude(include);
|
|
@@ -10302,7 +10420,7 @@ var Service = class extends Base {
|
|
|
10302
10420
|
const findAssociationField = this.getAssociationFieldFromOptions(options);
|
|
10303
10421
|
const withAssocSelect = findAssociationField && !finalSelect.includes(findAssociationField) ? [...finalSelect, findAssociationField] : finalSelect;
|
|
10304
10422
|
const dbSelect = this.buildDbSelectForAssociation(withAssocSelect, findAssociationField);
|
|
10305
|
-
const filteredPopulate = (0,
|
|
10423
|
+
const filteredPopulate = (0, import_utils31.isArray)(withAssocSelect) && (0, import_utils31.isArray)(_populate) ? _populate.filter(
|
|
10306
10424
|
(p) => withAssocSelect.some(
|
|
10307
10425
|
(field) => field === p.path || field.startsWith(`${p.path}.`) || p.path.startsWith(`${field}.`)
|
|
10308
10426
|
)
|
|
@@ -10346,10 +10464,10 @@ var Service = class extends Base {
|
|
|
10346
10464
|
...query,
|
|
10347
10465
|
select: dbSelect,
|
|
10348
10466
|
hardLimit: this.options.listHardLimit,
|
|
10349
|
-
lean
|
|
10467
|
+
lean: state.hydration === "lean"
|
|
10350
10468
|
});
|
|
10351
10469
|
const capturedAssociation = findAssociationField ? this.captureAssociationValues(docs, findAssociationField) : void 0;
|
|
10352
|
-
const correlatedSnapshots = docs.map((doc) => (0,
|
|
10470
|
+
const correlatedSnapshots = docs.map((doc) => (0, import_utils31.cloneDeep)(toObject(doc)));
|
|
10353
10471
|
try {
|
|
10354
10472
|
docs = await this.includeDocs(docs, includes, state.authorization);
|
|
10355
10473
|
if (correlatedIncludes.length > 0) {
|
|
@@ -10421,7 +10539,6 @@ var Service = class extends Base {
|
|
|
10421
10539
|
context: contexts[i],
|
|
10422
10540
|
includePermissions,
|
|
10423
10541
|
includeFieldPermissions,
|
|
10424
|
-
lean,
|
|
10425
10542
|
sharedGate,
|
|
10426
10543
|
privateAssociationField
|
|
10427
10544
|
});
|
|
@@ -10543,12 +10660,12 @@ var Service = class extends Base {
|
|
|
10543
10660
|
context.allowedFields = allowedFields;
|
|
10544
10661
|
context.allowedData = allowedData;
|
|
10545
10662
|
const validated = await this.validate(allowedData, "create", context);
|
|
10546
|
-
if ((0,
|
|
10663
|
+
if ((0, import_utils31.isBoolean)(validated)) {
|
|
10547
10664
|
if (!validated) {
|
|
10548
10665
|
validationErrors.push({ index, errors: [] });
|
|
10549
10666
|
return void 0;
|
|
10550
10667
|
}
|
|
10551
|
-
} else if ((0,
|
|
10668
|
+
} else if ((0, import_utils31.isArray)(validated)) {
|
|
10552
10669
|
if (validated.length > 0) {
|
|
10553
10670
|
validationErrors.push({
|
|
10554
10671
|
index,
|
|
@@ -10611,7 +10728,6 @@ var Service = class extends Base {
|
|
|
10611
10728
|
context: contexts[index],
|
|
10612
10729
|
includePermissions,
|
|
10613
10730
|
includeFieldPermissions,
|
|
10614
|
-
lean: false,
|
|
10615
10731
|
sharedGate: createGate
|
|
10616
10732
|
});
|
|
10617
10733
|
outputContexts[index] = output.context;
|
|
@@ -10674,8 +10790,7 @@ var Service = class extends Base {
|
|
|
10674
10790
|
doc: data,
|
|
10675
10791
|
plan: newPlan,
|
|
10676
10792
|
context: newContext,
|
|
10677
|
-
includePermissions
|
|
10678
|
-
lean: false
|
|
10793
|
+
includePermissions
|
|
10679
10794
|
});
|
|
10680
10795
|
return {
|
|
10681
10796
|
success: true,
|
|
@@ -10751,7 +10866,7 @@ var Service = class extends Base {
|
|
|
10751
10866
|
}
|
|
10752
10867
|
let doc = await this.model.findOne({
|
|
10753
10868
|
filter: _filter,
|
|
10754
|
-
select: (0,
|
|
10869
|
+
select: (0, import_utils31.uniq)([...updatePlan.persistedFetchSelection, ...inputFetchPaths(captured.configuration.catalog)]).map(
|
|
10755
10870
|
(path) => `+${path}`
|
|
10756
10871
|
)
|
|
10757
10872
|
});
|
|
@@ -10790,12 +10905,12 @@ var Service = class extends Base {
|
|
|
10790
10905
|
context.allowedFields = allowedFields;
|
|
10791
10906
|
context.allowedData = allowedData;
|
|
10792
10907
|
const validated = await this.validate(allowedData, "update", context);
|
|
10793
|
-
if ((0,
|
|
10908
|
+
if ((0, import_utils31.isBoolean)(validated)) {
|
|
10794
10909
|
if (!validated) {
|
|
10795
10910
|
this.completeOp("updateOne", startedAt, "bad_request" /* BadRequest */, _filter);
|
|
10796
10911
|
return { success: false, kind: "error", code: "bad_request" /* BadRequest */ };
|
|
10797
10912
|
}
|
|
10798
|
-
} else if ((0,
|
|
10913
|
+
} else if ((0, import_utils31.isArray)(validated)) {
|
|
10799
10914
|
if (validated.length > 0) {
|
|
10800
10915
|
this.completeOp("updateOne", startedAt, "bad_request" /* BadRequest */, _filter);
|
|
10801
10916
|
return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: validated };
|
|
@@ -10815,10 +10930,10 @@ var Service = class extends Base {
|
|
|
10815
10930
|
const diffExcludeFields = [this.options.documentPermissionField, "__v"];
|
|
10816
10931
|
this.asServiceHookContext(context).diff = (d) => {
|
|
10817
10932
|
context.changes = (0, import_just_diff.diff)(
|
|
10818
|
-
(0,
|
|
10819
|
-
(0,
|
|
10933
|
+
(0, import_utils31.omit)(context.originalDocumentSnapshot, diffExcludeFields),
|
|
10934
|
+
(0, import_utils31.omit)(d.toObject({ virtuals: false }), diffExcludeFields)
|
|
10820
10935
|
) || [];
|
|
10821
|
-
context.modifiedPaths = (0,
|
|
10936
|
+
context.modifiedPaths = (0, import_utils31.uniq)(context.changes.map((di) => di.path.length > 0 ? String(di.path[0]) : ""));
|
|
10822
10937
|
};
|
|
10823
10938
|
doc = assertModelDocument(await this.afterPersist(doc, "update", context), this.modelName, "afterPersist");
|
|
10824
10939
|
context.currentDocument = doc;
|
|
@@ -10843,8 +10958,7 @@ var Service = class extends Base {
|
|
|
10843
10958
|
plan: updatePlan,
|
|
10844
10959
|
context,
|
|
10845
10960
|
includePermissions,
|
|
10846
|
-
includeFieldPermissions
|
|
10847
|
-
lean: false
|
|
10961
|
+
includeFieldPermissions
|
|
10848
10962
|
});
|
|
10849
10963
|
const outputDoc = decorate ? await this.hookGate.run(() => decorate(output.data, output.context)) : output.data;
|
|
10850
10964
|
this.completeOp("updateOne", startedAt, "success" /* Success */, _filter);
|
|
@@ -11363,7 +11477,7 @@ var Service = class extends Base {
|
|
|
11363
11477
|
return resolveExistsOptions(this, options);
|
|
11364
11478
|
}
|
|
11365
11479
|
async getFieldPermissionAccess(ids) {
|
|
11366
|
-
const uniqueIds = (0,
|
|
11480
|
+
const uniqueIds = (0, import_utils31.compact)((0, import_utils31.uniqBy)(ids, (id) => String(id)).map((id) => String(id)));
|
|
11367
11481
|
if (uniqueIds.length === 0) {
|
|
11368
11482
|
return {
|
|
11369
11483
|
readIds: /* @__PURE__ */ new Set(),
|
|
@@ -11409,7 +11523,7 @@ var Service = class extends Base {
|
|
|
11409
11523
|
* (direct/root-entry 200); count measures visible rows, not all updated rows.
|
|
11410
11524
|
*/
|
|
11411
11525
|
async bulkUpdateSub(id, sub, data, options) {
|
|
11412
|
-
return bulkUpdateSub(this, this.persist, id, sub, (0,
|
|
11526
|
+
return bulkUpdateSub(this, this.persist, id, sub, (0, import_utils31.castArray)(data), options);
|
|
11413
11527
|
}
|
|
11414
11528
|
/**
|
|
11415
11529
|
* Append/prepend admitted rows, then return the visible full array (including when
|
|
@@ -11426,14 +11540,16 @@ var Service = class extends Base {
|
|
|
11426
11540
|
async deleteSub(id, sub, subId, options) {
|
|
11427
11541
|
return deleteSub(this, this.persist, id, sub, subId, options);
|
|
11428
11542
|
}
|
|
11543
|
+
/** Raw hydrated parent/null, with row policy and populate; no finalized permission metadata. */
|
|
11429
11544
|
async getParentDoc(id, sub, args, options) {
|
|
11430
11545
|
return getParentDoc(this, id, sub, args, options);
|
|
11431
11546
|
}
|
|
11432
11547
|
};
|
|
11433
11548
|
|
|
11434
11549
|
// src/services/public-service.ts
|
|
11435
|
-
var
|
|
11550
|
+
var import_utils32 = require("@web-ts-toolkit/utils");
|
|
11436
11551
|
init_helpers();
|
|
11552
|
+
init_permissions_alias();
|
|
11437
11553
|
init_public_admission();
|
|
11438
11554
|
var PublicService = class extends Service {
|
|
11439
11555
|
/** Public dispatch stays request-only even for JS callers and transformed envelopes. */
|
|
@@ -11471,36 +11587,61 @@ var PublicService = class extends Service {
|
|
|
11471
11587
|
const admission = this.admitPublicCall({ args, options, filter: filter2 });
|
|
11472
11588
|
if (admission) return admission;
|
|
11473
11589
|
const { select, populate, include, sort, skip, limit, page, pageSize, tasks } = this.resolvePublicListArgs(args);
|
|
11474
|
-
const { skim, includePermissions, includeFieldPermissions, includeCount, populateAccess
|
|
11475
|
-
|
|
11476
|
-
|
|
11477
|
-
|
|
11478
|
-
|
|
11479
|
-
|
|
11480
|
-
|
|
11481
|
-
|
|
11482
|
-
|
|
11483
|
-
|
|
11484
|
-
|
|
11485
|
-
|
|
11486
|
-
|
|
11487
|
-
|
|
11488
|
-
|
|
11590
|
+
const { skim, includePermissions, includeFieldPermissions, includeCount, populateAccess } = this.resolvePublicListOptions(options);
|
|
11591
|
+
try {
|
|
11592
|
+
const execution = withExecutionHydration(
|
|
11593
|
+
this,
|
|
11594
|
+
createServiceExecution(
|
|
11595
|
+
this,
|
|
11596
|
+
{
|
|
11597
|
+
operation: "list",
|
|
11598
|
+
rowAccess: "list",
|
|
11599
|
+
virtualAccess: "list",
|
|
11600
|
+
outputAccess: "list",
|
|
11601
|
+
docPermissionsAccess: "list"
|
|
11602
|
+
},
|
|
11603
|
+
requestOnlyServiceOptions({}).authorization,
|
|
11604
|
+
"service",
|
|
11605
|
+
this.captureRelated({ populate, include }, this.defaults.findArgs)
|
|
11606
|
+
),
|
|
11607
|
+
"publicList"
|
|
11608
|
+
);
|
|
11609
|
+
const query = await prepareModelQuery(this, execution, { kind: "client-read", filter: filter2 });
|
|
11610
|
+
const result2 = await executePreparedFind(
|
|
11611
|
+
this,
|
|
11612
|
+
execution,
|
|
11613
|
+
query,
|
|
11614
|
+
{ select, populate, include, sort, skip, limit, page, pageSize },
|
|
11615
|
+
requestOnlyServiceOptions({
|
|
11616
|
+
skim,
|
|
11617
|
+
includePermissions,
|
|
11618
|
+
includeFieldPermissions,
|
|
11619
|
+
includeCount,
|
|
11620
|
+
populateAccess
|
|
11621
|
+
}),
|
|
11622
|
+
async (doc, context) => {
|
|
11623
|
+
doc = toObject(doc);
|
|
11624
|
+
return this.decorate(doc, "list", context);
|
|
11625
|
+
}
|
|
11626
|
+
);
|
|
11627
|
+
if (!result2.success) {
|
|
11628
|
+
return result2;
|
|
11489
11629
|
}
|
|
11490
|
-
|
|
11491
|
-
|
|
11492
|
-
|
|
11630
|
+
const docs = await this.decorateAll(result2.data, "list", {
|
|
11631
|
+
mongooseModel: this.model.mongooseModel,
|
|
11632
|
+
modelName: this.modelName,
|
|
11633
|
+
operation: "list",
|
|
11634
|
+
resolvedQuery: result2.query
|
|
11635
|
+
});
|
|
11636
|
+
const transformedDocs = docs.map(
|
|
11637
|
+
(row) => this.runTasks(row, tasks)
|
|
11638
|
+
);
|
|
11639
|
+
return { ...result2, data: transformedDocs };
|
|
11640
|
+
} catch (error2) {
|
|
11641
|
+
const result2 = this.getClientRequestErrorResult(error2);
|
|
11642
|
+
if (result2) return result2;
|
|
11643
|
+
throw error2;
|
|
11493
11644
|
}
|
|
11494
|
-
const docs = await this.decorateAll(result2.data, "list", {
|
|
11495
|
-
mongooseModel: this.model.mongooseModel,
|
|
11496
|
-
modelName: this.modelName,
|
|
11497
|
-
operation: "list",
|
|
11498
|
-
resolvedQuery: result2.query
|
|
11499
|
-
});
|
|
11500
|
-
const transformedDocs = docs.map(
|
|
11501
|
-
(row) => this.runTasks(row, tasks)
|
|
11502
|
-
);
|
|
11503
|
-
return { ...result2, data: transformedDocs };
|
|
11504
11645
|
}
|
|
11505
11646
|
async _create(data, args, options) {
|
|
11506
11647
|
const admission = this.admitPublicCall({ args, options, data });
|
|
@@ -11516,7 +11657,7 @@ var PublicService = class extends Service {
|
|
|
11516
11657
|
let d = toObject(doc);
|
|
11517
11658
|
d = await this.decorate(d, "create", context);
|
|
11518
11659
|
d = this.runTasks(d, tasks);
|
|
11519
|
-
if (select) d = (0,
|
|
11660
|
+
if (select) d = copyPermissionsAlias(d, (0, import_utils32.pick)(d, [...normalizeSelect(select), ...this.baseFieldsExt]));
|
|
11520
11661
|
return d;
|
|
11521
11662
|
}
|
|
11522
11663
|
);
|
|
@@ -11537,21 +11678,25 @@ var PublicService = class extends Service {
|
|
|
11537
11678
|
const admission = this.admitPublicCall({ args, options });
|
|
11538
11679
|
if (admission) return admission;
|
|
11539
11680
|
const { select, populate, include, tasks } = this.resolvePublicReadArgs(args);
|
|
11540
|
-
const { skim, includePermissions, includeFieldPermissions, tryList, populateAccess
|
|
11681
|
+
const { skim, includePermissions, includeFieldPermissions, tryList, populateAccess } = this.resolvePublicReadOptions(options);
|
|
11541
11682
|
try {
|
|
11542
11683
|
let access = "read";
|
|
11543
|
-
let execution =
|
|
11684
|
+
let execution = withExecutionHydration(
|
|
11544
11685
|
this,
|
|
11545
|
-
|
|
11546
|
-
|
|
11547
|
-
|
|
11548
|
-
|
|
11549
|
-
|
|
11550
|
-
|
|
11551
|
-
|
|
11552
|
-
|
|
11553
|
-
|
|
11554
|
-
|
|
11686
|
+
createServiceExecution(
|
|
11687
|
+
this,
|
|
11688
|
+
{
|
|
11689
|
+
operation: "read",
|
|
11690
|
+
rowAccess: access,
|
|
11691
|
+
virtualAccess: access,
|
|
11692
|
+
outputAccess: access,
|
|
11693
|
+
docPermissionsAccess: access
|
|
11694
|
+
},
|
|
11695
|
+
requestOnlyServiceOptions({}).authorization,
|
|
11696
|
+
"service",
|
|
11697
|
+
this.captureRelated({ populate, include }, this.defaults.findOneArgs)
|
|
11698
|
+
),
|
|
11699
|
+
"publicRead"
|
|
11555
11700
|
);
|
|
11556
11701
|
const identifier = await resolveModelIdentifier(this, execution, id);
|
|
11557
11702
|
const query = await prepareModelQuery(this, execution, {
|
|
@@ -11563,7 +11708,7 @@ var PublicService = class extends Service {
|
|
|
11563
11708
|
execution,
|
|
11564
11709
|
query,
|
|
11565
11710
|
{ select, populate, include },
|
|
11566
|
-
requestOnlyServiceOptions({ skim, includePermissions, includeFieldPermissions, access, populateAccess
|
|
11711
|
+
requestOnlyServiceOptions({ skim, includePermissions, includeFieldPermissions, access, populateAccess })
|
|
11567
11712
|
);
|
|
11568
11713
|
if (!result2.success && (result2.code === "bad_request" /* BadRequest */ || result2.code === "forbidden" /* Forbidden */)) return result2;
|
|
11569
11714
|
if (tryList && (!result2.success || !result2.data)) {
|
|
@@ -11593,8 +11738,7 @@ var PublicService = class extends Service {
|
|
|
11593
11738
|
includePermissions,
|
|
11594
11739
|
includeFieldPermissions,
|
|
11595
11740
|
access,
|
|
11596
|
-
populateAccess
|
|
11597
|
-
lean
|
|
11741
|
+
populateAccess
|
|
11598
11742
|
})
|
|
11599
11743
|
);
|
|
11600
11744
|
}
|
|
@@ -11615,43 +11759,79 @@ var PublicService = class extends Service {
|
|
|
11615
11759
|
const admission = this.admitPublicCall({ args, options, filter: filter2 });
|
|
11616
11760
|
if (admission) return admission;
|
|
11617
11761
|
const { select, sort, populate, include, tasks } = this.resolvePublicReadFilterArgs(args);
|
|
11618
|
-
const { skim, includePermissions, includeFieldPermissions, tryList, populateAccess
|
|
11762
|
+
const { skim, includePermissions, includeFieldPermissions, tryList, populateAccess } = this.resolvePublicReadOptions(options);
|
|
11619
11763
|
let access = "read";
|
|
11620
|
-
|
|
11621
|
-
|
|
11622
|
-
|
|
11623
|
-
|
|
11624
|
-
|
|
11625
|
-
|
|
11626
|
-
|
|
11627
|
-
|
|
11628
|
-
|
|
11629
|
-
|
|
11630
|
-
|
|
11631
|
-
|
|
11632
|
-
|
|
11633
|
-
|
|
11634
|
-
|
|
11635
|
-
|
|
11636
|
-
|
|
11637
|
-
|
|
11638
|
-
|
|
11764
|
+
try {
|
|
11765
|
+
let execution = withExecutionHydration(
|
|
11766
|
+
this,
|
|
11767
|
+
createServiceExecution(
|
|
11768
|
+
this,
|
|
11769
|
+
{
|
|
11770
|
+
operation: "read",
|
|
11771
|
+
rowAccess: access,
|
|
11772
|
+
virtualAccess: access,
|
|
11773
|
+
outputAccess: access,
|
|
11774
|
+
docPermissionsAccess: access
|
|
11775
|
+
},
|
|
11776
|
+
requestOnlyServiceOptions({}).authorization,
|
|
11777
|
+
"service",
|
|
11778
|
+
this.captureRelated({ populate, include }, this.defaults.findOneArgs)
|
|
11779
|
+
),
|
|
11780
|
+
"publicRead"
|
|
11781
|
+
);
|
|
11782
|
+
const query = await prepareModelQuery(this, execution, { kind: "client-read", filter: filter2 });
|
|
11783
|
+
let result2 = await executePreparedFindOne(
|
|
11784
|
+
this,
|
|
11785
|
+
execution,
|
|
11786
|
+
query,
|
|
11639
11787
|
{
|
|
11640
11788
|
select,
|
|
11641
11789
|
sort,
|
|
11642
11790
|
populate,
|
|
11643
11791
|
include
|
|
11644
11792
|
},
|
|
11645
|
-
requestOnlyServiceOptions({ skim, includePermissions, includeFieldPermissions, access, populateAccess
|
|
11793
|
+
requestOnlyServiceOptions({ skim, includePermissions, includeFieldPermissions, access, populateAccess })
|
|
11646
11794
|
);
|
|
11795
|
+
if (!result2.success && (result2.code === "bad_request" /* BadRequest */ || result2.code === "forbidden" /* Forbidden */)) return result2;
|
|
11796
|
+
if (tryList && (!result2.success || !result2.data)) {
|
|
11797
|
+
const listAllowed = await this.requestCore.isAllowed(this.modelName, "list");
|
|
11798
|
+
if (!listAllowed) {
|
|
11799
|
+
return { success: false, kind: "error", code: "unauthorized" /* Unauthorized */, errors: ["Unauthorized"] };
|
|
11800
|
+
}
|
|
11801
|
+
access = "list";
|
|
11802
|
+
execution = deriveServiceExecution(this, execution, {
|
|
11803
|
+
operation: "read",
|
|
11804
|
+
rowAccess: access,
|
|
11805
|
+
virtualAccess: access,
|
|
11806
|
+
outputAccess: access,
|
|
11807
|
+
docPermissionsAccess: access
|
|
11808
|
+
});
|
|
11809
|
+
const fallback = await prepareModelQuery(this, execution, { kind: "client-read", filter: filter2 });
|
|
11810
|
+
result2 = await executePreparedFindOne(
|
|
11811
|
+
this,
|
|
11812
|
+
execution,
|
|
11813
|
+
fallback,
|
|
11814
|
+
{
|
|
11815
|
+
select,
|
|
11816
|
+
sort,
|
|
11817
|
+
populate,
|
|
11818
|
+
include
|
|
11819
|
+
},
|
|
11820
|
+
requestOnlyServiceOptions({ skim, includePermissions, includeFieldPermissions, access, populateAccess })
|
|
11821
|
+
);
|
|
11822
|
+
}
|
|
11823
|
+
if (!result2.success) {
|
|
11824
|
+
return result2;
|
|
11825
|
+
}
|
|
11826
|
+
let doc = toObject(result2.data);
|
|
11827
|
+
doc = await this.decorate(doc, access, result2.context);
|
|
11828
|
+
doc = this.runTasks(doc, tasks);
|
|
11829
|
+
return { ...result2, data: doc };
|
|
11830
|
+
} catch (error2) {
|
|
11831
|
+
const result2 = this.getClientRequestErrorResult(error2);
|
|
11832
|
+
if (result2) return result2;
|
|
11833
|
+
throw error2;
|
|
11647
11834
|
}
|
|
11648
|
-
if (!result2.success) {
|
|
11649
|
-
return result2;
|
|
11650
|
-
}
|
|
11651
|
-
let doc = toObject(result2.data);
|
|
11652
|
-
doc = await this.decorate(doc, access, result2.context);
|
|
11653
|
-
doc = this.runTasks(doc, tasks);
|
|
11654
|
-
return { ...result2, data: doc };
|
|
11655
11835
|
}
|
|
11656
11836
|
async _update(id, data, args, options) {
|
|
11657
11837
|
const admission = this.admitPublicCall({ args, options, data });
|
|
@@ -11672,8 +11852,8 @@ var PublicService = class extends Service {
|
|
|
11672
11852
|
let d = toObject(doc);
|
|
11673
11853
|
d = await this.decorate(d, "update", context);
|
|
11674
11854
|
d = this.runTasks(d, tasks);
|
|
11675
|
-
if (select) d = (0,
|
|
11676
|
-
else if (!returningAll) d = (0,
|
|
11855
|
+
if (select) d = copyPermissionsAlias(d, (0, import_utils32.pick)(d, [...normalizeSelect(select), ...this.baseFieldsExt]));
|
|
11856
|
+
else if (!returningAll) d = copyPermissionsAlias(d, (0, import_utils32.pick)(d, [...Object.keys(data), "_id"]));
|
|
11677
11857
|
return d;
|
|
11678
11858
|
}
|
|
11679
11859
|
);
|
|
@@ -11753,8 +11933,8 @@ var PublicService = class extends Service {
|
|
|
11753
11933
|
let d = toObject(doc);
|
|
11754
11934
|
d = await this.decorate(d, "update", context);
|
|
11755
11935
|
d = this.runTasks(d, tasks2);
|
|
11756
|
-
if (select2) d = (0,
|
|
11757
|
-
else if (!returningAll) d = (0,
|
|
11936
|
+
if (select2) d = copyPermissionsAlias(d, (0, import_utils32.pick)(d, [...normalizeSelect(select2), ...this.baseFieldsExt]));
|
|
11937
|
+
else if (!returningAll) d = copyPermissionsAlias(d, (0, import_utils32.pick)(d, [...Object.keys(otherData), "_id"]));
|
|
11758
11938
|
return d;
|
|
11759
11939
|
}
|
|
11760
11940
|
);
|
|
@@ -11783,7 +11963,7 @@ var PublicService = class extends Service {
|
|
|
11783
11963
|
let d = toObject(doc);
|
|
11784
11964
|
d = await this.decorate(d, "create", context);
|
|
11785
11965
|
d = this.runTasks(d, tasks);
|
|
11786
|
-
if (select) d = (0,
|
|
11966
|
+
if (select) d = copyPermissionsAlias(d, (0, import_utils32.pick)(d, [...normalizeSelect(select), ...this.baseFieldsExt]));
|
|
11787
11967
|
return d;
|
|
11788
11968
|
}
|
|
11789
11969
|
);
|
|
@@ -11844,8 +12024,7 @@ var PublicService = class extends Service {
|
|
|
11844
12024
|
includePermissions,
|
|
11845
12025
|
includeFieldPermissions: options.includeFieldPermissions ?? this.defaults.publicListOptions?.includeFieldPermissions ?? includePermissions,
|
|
11846
12026
|
includeCount: options.includeCount ?? this.defaults.publicListOptions?.includeCount ?? false,
|
|
11847
|
-
populateAccess: options.populateAccess ?? this.defaults.publicListOptions?.populateAccess ?? "read"
|
|
11848
|
-
lean: options.lean ?? this.defaults.publicListOptions?.lean ?? true
|
|
12027
|
+
populateAccess: options.populateAccess ?? this.defaults.publicListOptions?.populateAccess ?? "read"
|
|
11849
12028
|
};
|
|
11850
12029
|
}
|
|
11851
12030
|
resolvePublicCreateArgs(args = {}) {
|
|
@@ -11886,8 +12065,7 @@ var PublicService = class extends Service {
|
|
|
11886
12065
|
includePermissions,
|
|
11887
12066
|
includeFieldPermissions: options.includeFieldPermissions ?? this.defaults.publicReadOptions?.includeFieldPermissions ?? includePermissions,
|
|
11888
12067
|
tryList: options.tryList ?? this.defaults.publicReadOptions?.tryList ?? true,
|
|
11889
|
-
populateAccess: options.populateAccess ?? this.defaults.publicReadOptions?.populateAccess
|
|
11890
|
-
lean: options.lean ?? this.defaults.publicReadOptions?.lean ?? false
|
|
12068
|
+
populateAccess: options.populateAccess ?? this.defaults.publicReadOptions?.populateAccess
|
|
11891
12069
|
};
|
|
11892
12070
|
}
|
|
11893
12071
|
resolvePublicUpdateArgs(args = {}) {
|
|
@@ -11913,7 +12091,7 @@ var PublicService = class extends Service {
|
|
|
11913
12091
|
init_options();
|
|
11914
12092
|
init_data_values();
|
|
11915
12093
|
init_helpers();
|
|
11916
|
-
var
|
|
12094
|
+
var import_utils33 = require("@web-ts-toolkit/utils");
|
|
11917
12095
|
init_request_complexity();
|
|
11918
12096
|
init_runtime_context();
|
|
11919
12097
|
init_runtime();
|
|
@@ -11942,7 +12120,7 @@ var DataService = class {
|
|
|
11942
12120
|
let doc = await findElement(this.data, _filter);
|
|
11943
12121
|
if (!doc) return { success: false, kind: "error", code: "not_found" /* NotFound */, query };
|
|
11944
12122
|
doc = await this.trimOutputFields(doc, access);
|
|
11945
|
-
if (_select.length > 0) doc = (0,
|
|
12123
|
+
if (_select.length > 0) doc = (0, import_utils33.pick)(doc, _select);
|
|
11946
12124
|
return {
|
|
11947
12125
|
success: true,
|
|
11948
12126
|
kind: "single",
|
|
@@ -11988,13 +12166,13 @@ var DataService = class {
|
|
|
11988
12166
|
const totalCount = docs.length;
|
|
11989
12167
|
if (sort) {
|
|
11990
12168
|
const normalizedSort = normalizeSortForOrderBy(sort);
|
|
11991
|
-
docs = (0,
|
|
12169
|
+
docs = (0, import_utils33.orderBy)(docs, normalizedSort.fields, normalizedSort.orders);
|
|
11992
12170
|
}
|
|
11993
12171
|
const pagedDocs = docs.slice(query.skip, query.limit && query.skip + query.limit);
|
|
11994
12172
|
const { maxHookConcurrency } = this.getRequestComplexity();
|
|
11995
12173
|
const trimmed = await mapWithConcurrencyLimit(pagedDocs, maxHookConcurrency, async (doc) => {
|
|
11996
12174
|
doc = await this.trimOutputFields(doc, "list");
|
|
11997
|
-
if (_select.length > 0) doc = (0,
|
|
12175
|
+
if (_select.length > 0) doc = (0, import_utils33.pick)(doc, _select);
|
|
11998
12176
|
return copyDataValue(doc);
|
|
11999
12177
|
});
|
|
12000
12178
|
if (!hasExplicitLimit && trimmed.length === totalCount) {
|
|
@@ -12069,7 +12247,13 @@ var DataService = class {
|
|
|
12069
12247
|
init_helpers();
|
|
12070
12248
|
|
|
12071
12249
|
// src/processors.ts
|
|
12072
|
-
var
|
|
12250
|
+
var import_utils34 = require("@web-ts-toolkit/utils");
|
|
12251
|
+
init_permissions_alias();
|
|
12252
|
+
function cloneProcessorValue(value) {
|
|
12253
|
+
const copy = (0, import_utils34.cloneDeep)(value);
|
|
12254
|
+
copyPermissionsAliasGraph(value, copy);
|
|
12255
|
+
return copy;
|
|
12256
|
+
}
|
|
12073
12257
|
var UNSAFE_PATH_KEYS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
12074
12258
|
var DEFAULT_MAX_SLICE = 1e3;
|
|
12075
12259
|
var DEFAULT_MASK_REPLACEMENT = "***";
|
|
@@ -12104,10 +12288,10 @@ function resolveLeafParents(obj, src) {
|
|
|
12104
12288
|
for (let ind = 0; ind < segs.length - 1; ind += 1) {
|
|
12105
12289
|
const seg = segs[ind];
|
|
12106
12290
|
targets = targets.reduce((ret, target) => {
|
|
12107
|
-
if (!(0,
|
|
12291
|
+
if (!(0, import_utils34.isPlainObject)(target)) return ret;
|
|
12108
12292
|
const targetObject = target;
|
|
12109
12293
|
const next = targetObject[seg];
|
|
12110
|
-
if ((0,
|
|
12294
|
+
if ((0, import_utils34.isArray)(next)) {
|
|
12111
12295
|
for (const item of next) {
|
|
12112
12296
|
ret.push(item);
|
|
12113
12297
|
}
|
|
@@ -12117,8 +12301,8 @@ function resolveLeafParents(obj, src) {
|
|
|
12117
12301
|
}
|
|
12118
12302
|
const leaf = segs[segs.length - 1];
|
|
12119
12303
|
const pairs = [];
|
|
12120
|
-
(0,
|
|
12121
|
-
if (!(0,
|
|
12304
|
+
(0, import_utils34.forEach)(targets, (target) => {
|
|
12305
|
+
if (!(0, import_utils34.isPlainObject)(target)) return;
|
|
12122
12306
|
pairs.push({ parent: target, leaf });
|
|
12123
12307
|
});
|
|
12124
12308
|
return pairs;
|
|
@@ -12126,8 +12310,8 @@ function resolveLeafParents(obj, src) {
|
|
|
12126
12310
|
var copyAndDepopulate = (docObject, operations, options = { mutable: true, idField: "_id" }) => {
|
|
12127
12311
|
const mutable = options.mutable !== false;
|
|
12128
12312
|
const idField = options.idField ?? "_id";
|
|
12129
|
-
const obj = mutable ? docObject : (
|
|
12130
|
-
(0,
|
|
12313
|
+
const obj = mutable ? docObject : cloneProcessorValue(docObject);
|
|
12314
|
+
(0, import_utils34.forEach)(Array.isArray(operations) ? operations : [], (op) => {
|
|
12131
12315
|
if (!op || typeof op.src !== "string" || typeof op.dest !== "string") return;
|
|
12132
12316
|
const src = op.src;
|
|
12133
12317
|
const dest = op.dest;
|
|
@@ -12136,19 +12320,19 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
12136
12320
|
assertSafePath(dest);
|
|
12137
12321
|
let targets = [obj];
|
|
12138
12322
|
const segs = src.split(".");
|
|
12139
|
-
(0,
|
|
12323
|
+
(0, import_utils34.forEach)(segs, (seg, ind) => {
|
|
12140
12324
|
if (segs.length === ind + 1) {
|
|
12141
|
-
(0,
|
|
12142
|
-
if (!(0,
|
|
12325
|
+
(0, import_utils34.forEach)(targets, (target) => {
|
|
12326
|
+
if (!(0, import_utils34.isPlainObject)(target)) return;
|
|
12143
12327
|
const targetObject = target;
|
|
12144
12328
|
const leaf = targetObject[seg];
|
|
12145
12329
|
const sourceForDest = leaf;
|
|
12146
12330
|
let depopulated;
|
|
12147
|
-
if ((0,
|
|
12331
|
+
if ((0, import_utils34.isArray)(leaf)) {
|
|
12148
12332
|
if (leaf.length === 0) {
|
|
12149
12333
|
depopulated = [];
|
|
12150
|
-
} else if (leaf.every((item) => (0,
|
|
12151
|
-
depopulated = (0,
|
|
12334
|
+
} else if (leaf.every((item) => (0, import_utils34.isPlainObject)(item))) {
|
|
12335
|
+
depopulated = (0, import_utils34.map)(leaf, idField).map((id, i) => {
|
|
12152
12336
|
if (id === void 0) {
|
|
12153
12337
|
failMissingId(`${src}[${i}]`);
|
|
12154
12338
|
}
|
|
@@ -12157,8 +12341,8 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
12157
12341
|
} else {
|
|
12158
12342
|
return;
|
|
12159
12343
|
}
|
|
12160
|
-
} else if ((0,
|
|
12161
|
-
const id = (0,
|
|
12344
|
+
} else if ((0, import_utils34.isPlainObject)(leaf)) {
|
|
12345
|
+
const id = (0, import_utils34.get)(leaf, idField);
|
|
12162
12346
|
if (id === void 0) {
|
|
12163
12347
|
failMissingId(src);
|
|
12164
12348
|
}
|
|
@@ -12166,15 +12350,15 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
12166
12350
|
} else {
|
|
12167
12351
|
return;
|
|
12168
12352
|
}
|
|
12169
|
-
(0,
|
|
12170
|
-
(0,
|
|
12353
|
+
(0, import_utils34.set)(targetObject, dest, sourceForDest);
|
|
12354
|
+
(0, import_utils34.set)(targetObject, seg, depopulated);
|
|
12171
12355
|
});
|
|
12172
12356
|
} else {
|
|
12173
12357
|
targets = targets.reduce((ret, target) => {
|
|
12174
|
-
if (!(0,
|
|
12358
|
+
if (!(0, import_utils34.isPlainObject)(target)) return ret;
|
|
12175
12359
|
const targetObject = target;
|
|
12176
12360
|
const next = targetObject[seg];
|
|
12177
|
-
if ((0,
|
|
12361
|
+
if ((0, import_utils34.isArray)(next)) {
|
|
12178
12362
|
for (const item of next) {
|
|
12179
12363
|
ret.push(item);
|
|
12180
12364
|
}
|
|
@@ -12188,8 +12372,8 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
12188
12372
|
};
|
|
12189
12373
|
var copyPaths = (docObject, operations, options = { mutable: true }) => {
|
|
12190
12374
|
const mutable = options.mutable !== false;
|
|
12191
|
-
const obj = mutable ? docObject : (
|
|
12192
|
-
(0,
|
|
12375
|
+
const obj = mutable ? docObject : cloneProcessorValue(docObject);
|
|
12376
|
+
(0, import_utils34.forEach)(Array.isArray(operations) ? operations : [], (op) => {
|
|
12193
12377
|
if (!op || typeof op.src !== "string" || typeof op.dest !== "string") return;
|
|
12194
12378
|
const src = op.src;
|
|
12195
12379
|
const dest = op.dest;
|
|
@@ -12197,17 +12381,17 @@ var copyPaths = (docObject, operations, options = { mutable: true }) => {
|
|
|
12197
12381
|
assertSafePath(src, "copyPaths");
|
|
12198
12382
|
assertSafePath(dest, "copyPaths");
|
|
12199
12383
|
if (src === dest) return;
|
|
12200
|
-
(0,
|
|
12201
|
-
if (!(0,
|
|
12202
|
-
(0,
|
|
12384
|
+
(0, import_utils34.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
|
|
12385
|
+
if (!(0, import_utils34.hasOwn)(parent, leaf)) return;
|
|
12386
|
+
(0, import_utils34.set)(parent, dest, cloneProcessorValue(parent[leaf]));
|
|
12203
12387
|
});
|
|
12204
12388
|
});
|
|
12205
12389
|
return obj;
|
|
12206
12390
|
};
|
|
12207
12391
|
var movePaths = (docObject, operations, options = { mutable: true }) => {
|
|
12208
12392
|
const mutable = options.mutable !== false;
|
|
12209
|
-
const obj = mutable ? docObject : (
|
|
12210
|
-
(0,
|
|
12393
|
+
const obj = mutable ? docObject : cloneProcessorValue(docObject);
|
|
12394
|
+
(0, import_utils34.forEach)(Array.isArray(operations) ? operations : [], (op) => {
|
|
12211
12395
|
if (!op || typeof op.src !== "string" || typeof op.dest !== "string") return;
|
|
12212
12396
|
const src = op.src;
|
|
12213
12397
|
const dest = op.dest;
|
|
@@ -12215,10 +12399,10 @@ var movePaths = (docObject, operations, options = { mutable: true }) => {
|
|
|
12215
12399
|
assertSafePath(src, "movePaths");
|
|
12216
12400
|
assertSafePath(dest, "movePaths");
|
|
12217
12401
|
if (src === dest) return;
|
|
12218
|
-
(0,
|
|
12219
|
-
if (!(0,
|
|
12220
|
-
const value = (
|
|
12221
|
-
(0,
|
|
12402
|
+
(0, import_utils34.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
|
|
12403
|
+
if (!(0, import_utils34.hasOwn)(parent, leaf)) return;
|
|
12404
|
+
const value = cloneProcessorValue(parent[leaf]);
|
|
12405
|
+
(0, import_utils34.set)(parent, dest, value);
|
|
12222
12406
|
if (dest === leaf || dest.startsWith(`${leaf}.`)) return;
|
|
12223
12407
|
delete parent[leaf];
|
|
12224
12408
|
});
|
|
@@ -12229,8 +12413,8 @@ var sliceArrays = (docObject, operations, options = { mutable: true, maxSlice: D
|
|
|
12229
12413
|
const mutable = options.mutable !== false;
|
|
12230
12414
|
const maxSlice = options.maxSlice ?? DEFAULT_MAX_SLICE;
|
|
12231
12415
|
assertNonNegativeSafeInteger(maxSlice, "maxSlice", "sliceArrays");
|
|
12232
|
-
const obj = mutable ? docObject : (
|
|
12233
|
-
(0,
|
|
12416
|
+
const obj = mutable ? docObject : cloneProcessorValue(docObject);
|
|
12417
|
+
(0, import_utils34.forEach)(Array.isArray(operations) ? operations : [], (op) => {
|
|
12234
12418
|
if (!op || typeof op.src !== "string") return;
|
|
12235
12419
|
const src = op.src;
|
|
12236
12420
|
if (src.length === 0) return;
|
|
@@ -12247,15 +12431,15 @@ var sliceArrays = (docObject, operations, options = { mutable: true, maxSlice: D
|
|
|
12247
12431
|
assertNonNegativeSafeInteger(op.limit, "limit", "sliceArrays");
|
|
12248
12432
|
limit = Math.min(op.limit, maxSlice);
|
|
12249
12433
|
}
|
|
12250
|
-
(0,
|
|
12434
|
+
(0, import_utils34.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
|
|
12251
12435
|
const leafValue = parent[leaf];
|
|
12252
|
-
if (!(0,
|
|
12436
|
+
if (!(0, import_utils34.isArray)(leafValue)) return;
|
|
12253
12437
|
const end = typeof limit === "undefined" ? void 0 : skip + limit;
|
|
12254
12438
|
const window = leafValue.slice(skip, end);
|
|
12255
12439
|
if (typeof rawDest === "undefined") {
|
|
12256
|
-
(0,
|
|
12440
|
+
(0, import_utils34.set)(parent, leaf, window);
|
|
12257
12441
|
} else {
|
|
12258
|
-
(0,
|
|
12442
|
+
(0, import_utils34.set)(parent, rawDest, window);
|
|
12259
12443
|
}
|
|
12260
12444
|
});
|
|
12261
12445
|
});
|
|
@@ -12263,44 +12447,44 @@ var sliceArrays = (docObject, operations, options = { mutable: true, maxSlice: D
|
|
|
12263
12447
|
};
|
|
12264
12448
|
var countPaths = (docObject, operations, options = { mutable: true }) => {
|
|
12265
12449
|
const mutable = options.mutable !== false;
|
|
12266
|
-
const obj = mutable ? docObject : (
|
|
12267
|
-
(0,
|
|
12450
|
+
const obj = mutable ? docObject : cloneProcessorValue(docObject);
|
|
12451
|
+
(0, import_utils34.forEach)(Array.isArray(operations) ? operations : [], (op) => {
|
|
12268
12452
|
if (!op || typeof op.src !== "string" || typeof op.dest !== "string") return;
|
|
12269
12453
|
const src = op.src;
|
|
12270
12454
|
const dest = op.dest;
|
|
12271
12455
|
if (src.length === 0 || dest.length === 0) return;
|
|
12272
12456
|
assertSafePath(src, "countPaths");
|
|
12273
12457
|
assertSafePath(dest, "countPaths");
|
|
12274
|
-
(0,
|
|
12275
|
-
if (!(0,
|
|
12458
|
+
(0, import_utils34.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
|
|
12459
|
+
if (!(0, import_utils34.hasOwn)(parent, leaf)) return;
|
|
12276
12460
|
const leafValue = parent[leaf];
|
|
12277
12461
|
let count;
|
|
12278
|
-
if ((0,
|
|
12462
|
+
if ((0, import_utils34.isArray)(leafValue)) {
|
|
12279
12463
|
count = leafValue.length;
|
|
12280
|
-
} else if ((0,
|
|
12464
|
+
} else if ((0, import_utils34.isPlainObject)(leafValue)) {
|
|
12281
12465
|
count = Object.keys(leafValue).length;
|
|
12282
12466
|
} else if (leafValue === null || typeof leafValue === "undefined") {
|
|
12283
12467
|
count = 0;
|
|
12284
12468
|
} else {
|
|
12285
12469
|
count = 1;
|
|
12286
12470
|
}
|
|
12287
|
-
(0,
|
|
12471
|
+
(0, import_utils34.set)(parent, dest, count);
|
|
12288
12472
|
});
|
|
12289
12473
|
});
|
|
12290
12474
|
return obj;
|
|
12291
12475
|
};
|
|
12292
12476
|
var maskPaths = (docObject, operations, options = { mutable: true }) => {
|
|
12293
12477
|
const mutable = options.mutable !== false;
|
|
12294
|
-
const obj = mutable ? docObject : (
|
|
12295
|
-
(0,
|
|
12478
|
+
const obj = mutable ? docObject : cloneProcessorValue(docObject);
|
|
12479
|
+
(0, import_utils34.forEach)(Array.isArray(operations) ? operations : [], (op) => {
|
|
12296
12480
|
if (!op || typeof op.src !== "string") return;
|
|
12297
12481
|
const src = op.src;
|
|
12298
12482
|
if (src.length === 0) return;
|
|
12299
12483
|
assertSafePath(src, "maskPaths");
|
|
12300
12484
|
const replacement = Object.prototype.hasOwnProperty.call(op, "replacement") ? op.replacement : DEFAULT_MASK_REPLACEMENT;
|
|
12301
|
-
(0,
|
|
12302
|
-
if (!(0,
|
|
12303
|
-
(0,
|
|
12485
|
+
(0, import_utils34.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
|
|
12486
|
+
if (!(0, import_utils34.hasOwn)(parent, leaf)) return;
|
|
12487
|
+
(0, import_utils34.set)(parent, leaf, replacement);
|
|
12304
12488
|
});
|
|
12305
12489
|
});
|
|
12306
12490
|
return obj;
|
|
@@ -12400,10 +12584,10 @@ var Core = class {
|
|
|
12400
12584
|
getIdentifier(modelName) {
|
|
12401
12585
|
const resolveIdFilter = getModelOption(modelName, "resolveIdFilter");
|
|
12402
12586
|
const idField = getModelOption(modelName, "idField");
|
|
12403
|
-
if ((0,
|
|
12587
|
+
if ((0, import_utils35.isFunction)(resolveIdFilter)) {
|
|
12404
12588
|
return null;
|
|
12405
12589
|
}
|
|
12406
|
-
if ((0,
|
|
12590
|
+
if ((0, import_utils35.isString)(idField)) {
|
|
12407
12591
|
return idField;
|
|
12408
12592
|
}
|
|
12409
12593
|
return "_id";
|
|
@@ -12524,15 +12708,15 @@ var Core = class {
|
|
|
12524
12708
|
if (!_populate) return [];
|
|
12525
12709
|
let populate = Array.isArray(_populate) ? _populate : [_populate];
|
|
12526
12710
|
for (const p of populate) {
|
|
12527
|
-
if (!(0,
|
|
12711
|
+
if (!(0, import_utils35.isString)(p)) assertPopulateAccess(p.access);
|
|
12528
12712
|
}
|
|
12529
|
-
populate = (0,
|
|
12713
|
+
populate = (0, import_utils35.compact)(
|
|
12530
12714
|
await Promise.all(
|
|
12531
12715
|
populate.map(async (p) => {
|
|
12532
|
-
const populateAccess = !(0,
|
|
12716
|
+
const populateAccess = !(0, import_utils35.isString)(p) && p.access ? p.access : access;
|
|
12533
12717
|
assertPopulateAccess(populateAccess);
|
|
12534
|
-
const originalSelect = (0,
|
|
12535
|
-
const ret = (0,
|
|
12718
|
+
const originalSelect = (0, import_utils35.isString)(p) ? void 0 : p.select;
|
|
12719
|
+
const ret = (0, import_utils35.isString)(p) ? { path: p } : {
|
|
12536
12720
|
path: p.path,
|
|
12537
12721
|
select: normalizeSelect(p.select)
|
|
12538
12722
|
};
|
|
@@ -12560,7 +12744,7 @@ var Core = class {
|
|
|
12560
12744
|
}
|
|
12561
12745
|
ret.select = await this.requestPopulateSelect(refModelName, populateAccess, ret.select);
|
|
12562
12746
|
const hookInputs = getModelOption(refModelName, `alwaysSelectFields.${populateAccess}`, []);
|
|
12563
|
-
ret.select = (0,
|
|
12747
|
+
ret.select = (0, import_utils35.uniq)([...ret.select, ...stripVirtuals(hookInputs, runtime.getVirtualNames(refModelName))]);
|
|
12564
12748
|
const filter2 = await this.genFilter(refModelName, populateAccess, null);
|
|
12565
12749
|
if (filter2 === false) return null;
|
|
12566
12750
|
ret.match = filter2;
|
|
@@ -12596,7 +12780,7 @@ var Core = class {
|
|
|
12596
12780
|
internalFetch: { baseFields: ["_id"] },
|
|
12597
12781
|
globalPermissions: globalForPlan
|
|
12598
12782
|
});
|
|
12599
|
-
const merged = (0,
|
|
12783
|
+
const merged = (0, import_utils35.uniq)([...normalizeSelect(ret.select), ...targetPlan.virtualOnlyDeps ?? []]).filter(
|
|
12600
12784
|
(t) => t !== "-_id" && !t.includes(".sub.")
|
|
12601
12785
|
);
|
|
12602
12786
|
if (!merged.includes("_id")) merged.push("_id");
|
|
@@ -12620,10 +12804,10 @@ var Core = class {
|
|
|
12620
12804
|
}
|
|
12621
12805
|
async validate(modelName, allowedData, access, context) {
|
|
12622
12806
|
const validate = getModelOption(modelName, `validate.${access}`, null);
|
|
12623
|
-
if ((0,
|
|
12807
|
+
if ((0, import_utils35.isFunction)(validate)) {
|
|
12624
12808
|
const permissions = this.getGlobalPermissions();
|
|
12625
12809
|
return validate.call(this.req, allowedData, permissions, context);
|
|
12626
|
-
} else if ((0,
|
|
12810
|
+
} else if ((0, import_utils35.isBoolean)(validate) || (0, import_utils35.isArray)(validate)) {
|
|
12627
12811
|
return validate;
|
|
12628
12812
|
} else {
|
|
12629
12813
|
return true;
|
|
@@ -12648,7 +12832,7 @@ var Core = class {
|
|
|
12648
12832
|
const changeOptions = getModelOption(modelName, `onChange`, {});
|
|
12649
12833
|
for (let x = 0; x < context.modifiedPaths.length; x++) {
|
|
12650
12834
|
const mpath = context.modifiedPaths[x];
|
|
12651
|
-
if ((0,
|
|
12835
|
+
if ((0, import_utils35.isFunction)(changeOptions[mpath])) {
|
|
12652
12836
|
await changeOptions[mpath].call(
|
|
12653
12837
|
this.req,
|
|
12654
12838
|
context.originalDocumentSnapshot[mpath],
|
|
@@ -12672,7 +12856,7 @@ var Core = class {
|
|
|
12672
12856
|
async genDocPermissions(modelName, doc, access, context) {
|
|
12673
12857
|
const docPermissionsFn = getModelOption(modelName, `docPermissions.${access}`, null);
|
|
12674
12858
|
let docPermissions = {};
|
|
12675
|
-
if ((0,
|
|
12859
|
+
if ((0, import_utils35.isFunction)(docPermissionsFn)) {
|
|
12676
12860
|
const permissions = this.getGlobalPermissions();
|
|
12677
12861
|
try {
|
|
12678
12862
|
docPermissions = await getRequestWorkState(this.req, this.requestRuntime).hookGate.run(
|
|
@@ -12756,7 +12940,7 @@ var Core = class {
|
|
|
12756
12940
|
readExists ? requestFields("read") : [],
|
|
12757
12941
|
updateExists ? requestFields("update") : []
|
|
12758
12942
|
]);
|
|
12759
|
-
const viewObj = (0,
|
|
12943
|
+
const viewObj = (0, import_utils35.reduce)(
|
|
12760
12944
|
views,
|
|
12761
12945
|
(ret, view) => {
|
|
12762
12946
|
ret[view] = true;
|
|
@@ -12764,7 +12948,7 @@ var Core = class {
|
|
|
12764
12948
|
},
|
|
12765
12949
|
{}
|
|
12766
12950
|
);
|
|
12767
|
-
const editObj = (0,
|
|
12951
|
+
const editObj = (0, import_utils35.reduce)(
|
|
12768
12952
|
edits,
|
|
12769
12953
|
(ret, view) => {
|
|
12770
12954
|
ret[view] = true;
|
|
@@ -12795,9 +12979,9 @@ var Core = class {
|
|
|
12795
12979
|
});
|
|
12796
12980
|
}
|
|
12797
12981
|
runTasks(modelName, docObject, task) {
|
|
12798
|
-
const tasks = (0,
|
|
12982
|
+
const tasks = (0, import_utils35.compact)((0, import_utils35.castArray)(task));
|
|
12799
12983
|
if (tasks.length === 0) return docObject;
|
|
12800
|
-
(0,
|
|
12984
|
+
(0, import_utils35.forEach)(tasks, (task2) => {
|
|
12801
12985
|
const { type, args, options } = task2;
|
|
12802
12986
|
switch (type) {
|
|
12803
12987
|
case "COPY_AND_DEPOPULATE":
|
|
@@ -12865,9 +13049,9 @@ var Core = class {
|
|
|
12865
13049
|
}
|
|
12866
13050
|
const [, field, op] = keys2;
|
|
12867
13051
|
const subOption = getExactModelOption(modelName, `operationAccess.${access}`);
|
|
12868
|
-
if ((0,
|
|
13052
|
+
if ((0, import_utils35.isUndefined)(subOption)) {
|
|
12869
13053
|
const subFieldOption = getExactModelOption(modelName, `operationAccess.subs.${field}`);
|
|
12870
|
-
if ((0,
|
|
13054
|
+
if ((0, import_utils35.isUndefined)(subFieldOption)) {
|
|
12871
13055
|
const opOption = getModelOption(modelName, `operationAccess.${op}`);
|
|
12872
13056
|
return this.canActivate(opOption);
|
|
12873
13057
|
}
|
|
@@ -12933,25 +13117,25 @@ function guard(condition) {
|
|
|
12933
13117
|
const permissions = req[PERMISSIONS];
|
|
12934
13118
|
let cond = condition;
|
|
12935
13119
|
let phas = (key) => permissions.has(key);
|
|
12936
|
-
if ((0,
|
|
13120
|
+
if ((0, import_utils36.isPlainObject)(condition)) {
|
|
12937
13121
|
const { modelName, id, condition: _cond } = condition;
|
|
12938
13122
|
const svc = req.macl.getPublicService(modelName);
|
|
12939
13123
|
const select = getModelOption(modelName, `alwaysSelectFields.read`, void 0);
|
|
12940
|
-
let _id = (0,
|
|
12941
|
-
if ((0,
|
|
13124
|
+
let _id = (0, import_utils36.isString)(id) ? id : null;
|
|
13125
|
+
if ((0, import_utils36.isPlainObject)(id)) {
|
|
12942
13126
|
const { type = "param", key } = id;
|
|
12943
13127
|
if (type === "param") {
|
|
12944
13128
|
const paramValue = req.params[key];
|
|
12945
|
-
_id = (0,
|
|
13129
|
+
_id = (0, import_utils36.isArray)(paramValue) ? paramValue[0] ?? null : paramValue ?? null;
|
|
12946
13130
|
} else if (type === "query") {
|
|
12947
13131
|
const _qval = req.query[key];
|
|
12948
|
-
if ((0,
|
|
13132
|
+
if ((0, import_utils36.isArray)(_qval)) _id = _qval.length > 0 ? _qval[0] : null;
|
|
12949
13133
|
else _id = _qval;
|
|
12950
13134
|
} else {
|
|
12951
13135
|
_id = null;
|
|
12952
13136
|
}
|
|
12953
13137
|
}
|
|
12954
|
-
if (!(0,
|
|
13138
|
+
if (!(0, import_utils36.isString)(_id) || !_id) {
|
|
12955
13139
|
return next(new import_express_json_router5.default.clientErrors.BadRequestError());
|
|
12956
13140
|
}
|
|
12957
13141
|
const result2 = await svc._read(_id, { select });
|
|
@@ -12963,11 +13147,11 @@ function guard(condition) {
|
|
|
12963
13147
|
cond = _cond;
|
|
12964
13148
|
}
|
|
12965
13149
|
const { stringHandler, arrayHandler } = createValidator(phas);
|
|
12966
|
-
if ((0,
|
|
13150
|
+
if ((0, import_utils36.isString)(cond)) {
|
|
12967
13151
|
if (stringHandler(cond)) return next();
|
|
12968
|
-
} else if ((0,
|
|
13152
|
+
} else if ((0, import_utils36.isArray)(cond)) {
|
|
12969
13153
|
if (arrayHandler(cond)) return next();
|
|
12970
|
-
} else if ((0,
|
|
13154
|
+
} else if ((0, import_utils36.isFunction)(cond)) {
|
|
12971
13155
|
const result2 = await cond.call(req, permissions);
|
|
12972
13156
|
if (!!result2) return next();
|
|
12973
13157
|
}
|
|
@@ -12980,7 +13164,7 @@ var import_express2 = __toESM(require("express"));
|
|
|
12980
13164
|
|
|
12981
13165
|
// src/routers/model-router.ts
|
|
12982
13166
|
var import_express_json_router8 = __toESM(require("@web-ts-toolkit/express-json-router"));
|
|
12983
|
-
var
|
|
13167
|
+
var import_utils40 = require("@web-ts-toolkit/utils");
|
|
12984
13168
|
init_logger_helpers();
|
|
12985
13169
|
init_runtime();
|
|
12986
13170
|
init_runtime_context();
|
|
@@ -13114,7 +13298,7 @@ init_request_complexity();
|
|
|
13114
13298
|
|
|
13115
13299
|
// src/validation/common.ts
|
|
13116
13300
|
var import_zod2 = require("zod");
|
|
13117
|
-
var
|
|
13301
|
+
var import_utils37 = require("@web-ts-toolkit/utils");
|
|
13118
13302
|
|
|
13119
13303
|
// src/validation/public-admission-schema.ts
|
|
13120
13304
|
init_public_admission();
|
|
@@ -13243,7 +13427,7 @@ var correlatedFilterSchema = import_zod2.z.record(import_zod2.z.string(), import
|
|
|
13243
13427
|
}
|
|
13244
13428
|
});
|
|
13245
13429
|
var correlatedEmptyOptionsSchema = import_zod2.z.unknown().refine(
|
|
13246
|
-
(value) => value === void 0 || (0,
|
|
13430
|
+
(value) => value === void 0 || (0, import_utils37.isPlainObject)(value) && Object.keys(value).length === 0,
|
|
13247
13431
|
"Correlated include options must be absent or empty"
|
|
13248
13432
|
).optional();
|
|
13249
13433
|
var correlatedPathSchema = import_zod2.z.string().min(1).superRefine((path, ctx) => {
|
|
@@ -13280,7 +13464,7 @@ var correlatedListArgsSchema = import_zod2.z.object({
|
|
|
13280
13464
|
include: import_zod2.z.lazy(() => correlatedNestedIncludeSchema).optional()
|
|
13281
13465
|
}).strict().superRefine((args, ctx) => checkArgsMarkers(args.select, args.sort, ctx));
|
|
13282
13466
|
var correlatedCountArgsSchema = import_zod2.z.unknown().refine(
|
|
13283
|
-
(value) => value === void 0 || (0,
|
|
13467
|
+
(value) => value === void 0 || (0, import_utils37.isPlainObject)(value) && Object.keys(value).length === 0,
|
|
13284
13468
|
"Count includes accept no args"
|
|
13285
13469
|
).optional();
|
|
13286
13470
|
var correlatedReadByIdSchema = import_zod2.z.object({
|
|
@@ -13333,7 +13517,7 @@ var correlatedNestedIncludeSchema = import_zod2.z.union([includeItemSchema, impo
|
|
|
13333
13517
|
var rejectDuplicateCorrelatedPaths = (items, ctx) => {
|
|
13334
13518
|
const seen = /* @__PURE__ */ new Set();
|
|
13335
13519
|
items.forEach((item, index) => {
|
|
13336
|
-
if ((0,
|
|
13520
|
+
if ((0, import_utils37.isPlainObject)(item) && item.mode === "correlated" && typeof item.path === "string") {
|
|
13337
13521
|
if (seen.has(item.path)) {
|
|
13338
13522
|
ctx.addIssue({
|
|
13339
13523
|
code: import_zod2.z.ZodIssueCode.custom,
|
|
@@ -14077,8 +14261,7 @@ var rootModelListOptionsSchema = import_zod5.z.object({
|
|
|
14077
14261
|
includePermissions: import_zod5.z.boolean().optional(),
|
|
14078
14262
|
includeFieldPermissions: import_zod5.z.boolean().optional(),
|
|
14079
14263
|
includeCount: import_zod5.z.boolean().optional(),
|
|
14080
|
-
populateAccess: populateAccessSchema.optional()
|
|
14081
|
-
lean: import_zod5.z.boolean().optional()
|
|
14264
|
+
populateAccess: populateAccessSchema.optional()
|
|
14082
14265
|
}).passthrough();
|
|
14083
14266
|
var rootModelReadArgsSchema = import_zod5.z.object({
|
|
14084
14267
|
select: projectionSchema.optional(),
|
|
@@ -14094,8 +14277,7 @@ var rootModelReadOptionsSchema = import_zod5.z.object({
|
|
|
14094
14277
|
includePermissions: import_zod5.z.boolean().optional(),
|
|
14095
14278
|
includeFieldPermissions: import_zod5.z.boolean().optional(),
|
|
14096
14279
|
tryList: import_zod5.z.boolean().optional(),
|
|
14097
|
-
populateAccess: populateAccessSchema.optional()
|
|
14098
|
-
lean: import_zod5.z.boolean().optional()
|
|
14280
|
+
populateAccess: populateAccessSchema.optional()
|
|
14099
14281
|
}).passthrough();
|
|
14100
14282
|
var rootModelCreateArgsSchema = import_zod5.z.object({
|
|
14101
14283
|
select: projectionSchema.optional(),
|
|
@@ -14308,7 +14490,7 @@ var rootQuerySchema = publicBoundarySchema(
|
|
|
14308
14490
|
init_helpers();
|
|
14309
14491
|
|
|
14310
14492
|
// src/routers/shared.ts
|
|
14311
|
-
var
|
|
14493
|
+
var import_utils38 = require("@web-ts-toolkit/utils");
|
|
14312
14494
|
|
|
14313
14495
|
// src/routers/model-router-collection-routes.ts
|
|
14314
14496
|
init_schemas();
|
|
@@ -14339,15 +14521,15 @@ function setModelCollectionRoutes(context) {
|
|
|
14339
14521
|
sort
|
|
14340
14522
|
} = parseQuery(requestSchemas.listQuery, req.query);
|
|
14341
14523
|
const svc = context.getPublicService(req);
|
|
14342
|
-
const includeCount = (0,
|
|
14343
|
-
const includeExtraHeaders = (0,
|
|
14524
|
+
const includeCount = (0, import_utils38.parseBooleanString)(include_count);
|
|
14525
|
+
const includeExtraHeaders = (0, import_utils38.parseBooleanString)(include_extra_headers);
|
|
14344
14526
|
const result2 = await svc._list(
|
|
14345
14527
|
{},
|
|
14346
14528
|
{ select: parseSelectParam(select), sort, skip, limit, page, pageSize: page_size },
|
|
14347
14529
|
{
|
|
14348
|
-
skim: (0,
|
|
14349
|
-
includePermissions: (0,
|
|
14350
|
-
includeFieldPermissions: (0,
|
|
14530
|
+
skim: (0, import_utils38.parseBooleanString)(skim),
|
|
14531
|
+
includePermissions: (0, import_utils38.parseBooleanString)(include_permissions),
|
|
14532
|
+
includeFieldPermissions: (0, import_utils38.parseBooleanString)(include_field_permissions),
|
|
14351
14533
|
includeCount
|
|
14352
14534
|
}
|
|
14353
14535
|
);
|
|
@@ -14407,8 +14589,8 @@ function setModelCollectionRoutes(context) {
|
|
|
14407
14589
|
data,
|
|
14408
14590
|
{},
|
|
14409
14591
|
{
|
|
14410
|
-
includePermissions: (0,
|
|
14411
|
-
includeFieldPermissions: (0,
|
|
14592
|
+
includePermissions: (0, import_utils38.parseBooleanString)(include_permissions),
|
|
14593
|
+
includeFieldPermissions: (0, import_utils38.parseBooleanString)(include_field_permissions)
|
|
14412
14594
|
}
|
|
14413
14595
|
);
|
|
14414
14596
|
handleResultError(result2);
|
|
@@ -14446,8 +14628,8 @@ function setModelCollectionRoutes(context) {
|
|
|
14446
14628
|
finalData,
|
|
14447
14629
|
{ select: finalSelect, populate: finalPopulate, tasks: finalTasks },
|
|
14448
14630
|
{
|
|
14449
|
-
includePermissions: includePermissions ?? (0,
|
|
14450
|
-
includeFieldPermissions: includeFieldPermissions ?? (0,
|
|
14631
|
+
includePermissions: includePermissions ?? (0, import_utils38.parseBooleanString)(include_permissions),
|
|
14632
|
+
includeFieldPermissions: includeFieldPermissions ?? (0, import_utils38.parseBooleanString)(include_field_permissions),
|
|
14451
14633
|
populateAccess
|
|
14452
14634
|
}
|
|
14453
14635
|
);
|
|
@@ -14544,9 +14726,9 @@ function setModelDocumentRoutes(context) {
|
|
|
14544
14726
|
id,
|
|
14545
14727
|
{ select: parseSelectParam(select) },
|
|
14546
14728
|
{
|
|
14547
|
-
includePermissions: (0,
|
|
14548
|
-
includeFieldPermissions: (0,
|
|
14549
|
-
tryList: (0,
|
|
14729
|
+
includePermissions: (0, import_utils38.parseBooleanString)(include_permissions),
|
|
14730
|
+
includeFieldPermissions: (0, import_utils38.parseBooleanString)(include_field_permissions),
|
|
14731
|
+
tryList: (0, import_utils38.parseBooleanString)(try_list)
|
|
14550
14732
|
}
|
|
14551
14733
|
);
|
|
14552
14734
|
handleResultError(result2);
|
|
@@ -14646,9 +14828,9 @@ function setModelDocumentRoutes(context) {
|
|
|
14646
14828
|
data,
|
|
14647
14829
|
{ select: parseSelectParam(select) },
|
|
14648
14830
|
{
|
|
14649
|
-
returningAll: (0,
|
|
14650
|
-
includePermissions: (0,
|
|
14651
|
-
includeFieldPermissions: (0,
|
|
14831
|
+
returningAll: (0, import_utils38.parseBooleanString)(returning_all),
|
|
14832
|
+
includePermissions: (0, import_utils38.parseBooleanString)(include_permissions),
|
|
14833
|
+
includeFieldPermissions: (0, import_utils38.parseBooleanString)(include_field_permissions)
|
|
14652
14834
|
}
|
|
14653
14835
|
);
|
|
14654
14836
|
handleResultError(result2);
|
|
@@ -14697,9 +14879,9 @@ function setModelDocumentRoutes(context) {
|
|
|
14697
14879
|
finalData,
|
|
14698
14880
|
{ select: finalSelect, populate: finalPopulate, tasks: finalTasks },
|
|
14699
14881
|
{
|
|
14700
|
-
returningAll: returningAll ?? (0,
|
|
14701
|
-
includePermissions: includePermissions ?? (0,
|
|
14702
|
-
includeFieldPermissions: includeFieldPermissions ?? (0,
|
|
14882
|
+
returningAll: returningAll ?? (0, import_utils38.parseBooleanString)(returning_all),
|
|
14883
|
+
includePermissions: includePermissions ?? (0, import_utils38.parseBooleanString)(include_permissions),
|
|
14884
|
+
includeFieldPermissions: includeFieldPermissions ?? (0, import_utils38.parseBooleanString)(include_field_permissions),
|
|
14703
14885
|
populateAccess
|
|
14704
14886
|
}
|
|
14705
14887
|
);
|
|
@@ -14730,9 +14912,9 @@ function setModelDocumentRoutes(context) {
|
|
|
14730
14912
|
body,
|
|
14731
14913
|
{},
|
|
14732
14914
|
{
|
|
14733
|
-
returningAll: (0,
|
|
14734
|
-
includePermissions: (0,
|
|
14735
|
-
includeFieldPermissions: (0,
|
|
14915
|
+
returningAll: (0, import_utils38.parseBooleanString)(returning_all),
|
|
14916
|
+
includePermissions: (0, import_utils38.parseBooleanString)(include_permissions),
|
|
14917
|
+
includeFieldPermissions: (0, import_utils38.parseBooleanString)(include_field_permissions)
|
|
14736
14918
|
}
|
|
14737
14919
|
);
|
|
14738
14920
|
handleResultError(result2);
|
|
@@ -14779,9 +14961,9 @@ function setModelDocumentRoutes(context) {
|
|
|
14779
14961
|
finalData,
|
|
14780
14962
|
{ select: finalSelect, populate: finalPopulate, tasks: finalTasks },
|
|
14781
14963
|
{
|
|
14782
|
-
returningAll: returningAll ?? (0,
|
|
14783
|
-
includePermissions: includePermissions ?? (0,
|
|
14784
|
-
includeFieldPermissions: includeFieldPermissions ?? (0,
|
|
14964
|
+
returningAll: returningAll ?? (0, import_utils38.parseBooleanString)(returning_all),
|
|
14965
|
+
includePermissions: includePermissions ?? (0, import_utils38.parseBooleanString)(include_permissions),
|
|
14966
|
+
includeFieldPermissions: includeFieldPermissions ?? (0, import_utils38.parseBooleanString)(include_field_permissions),
|
|
14785
14967
|
populateAccess
|
|
14786
14968
|
}
|
|
14787
14969
|
);
|
|
@@ -15021,11 +15203,11 @@ function setModelSubDocumentRoutes(context) {
|
|
|
15021
15203
|
}
|
|
15022
15204
|
|
|
15023
15205
|
// src/openapi/route-registration.ts
|
|
15024
|
-
var
|
|
15206
|
+
var import_utils39 = require("@web-ts-toolkit/utils");
|
|
15025
15207
|
function registerOpenApiRoute(runtime, basePath, defaultTag, route) {
|
|
15026
15208
|
runtime.registerOpenApiRoute({
|
|
15027
15209
|
...route,
|
|
15028
|
-
path: (0,
|
|
15210
|
+
path: (0, import_utils39.normalizeUrlPath)(basePath + route.path),
|
|
15029
15211
|
tags: route.tags ?? [defaultTag]
|
|
15030
15212
|
});
|
|
15031
15213
|
}
|
|
@@ -15033,8 +15215,8 @@ function registerOpenApiRoute(runtime, basePath, defaultTag, route) {
|
|
|
15033
15215
|
// src/routers/model-router.ts
|
|
15034
15216
|
var clientErrors2 = import_express_json_router8.default.clientErrors;
|
|
15035
15217
|
function setOption(parentKey, optionKey, option) {
|
|
15036
|
-
const key = (0,
|
|
15037
|
-
const value = (0,
|
|
15218
|
+
const key = (0, import_utils40.isUndefined)(option) ? parentKey : `${parentKey}.${optionKey}`;
|
|
15219
|
+
const value = (0, import_utils40.isUndefined)(option) ? optionKey : option;
|
|
15038
15220
|
assertMutableRouterOption("model", key);
|
|
15039
15221
|
this.runtime.setModelOption(
|
|
15040
15222
|
this.modelName,
|
|
@@ -15233,7 +15415,7 @@ var ModelRouter = class _ModelRouter {
|
|
|
15233
15415
|
this.runtime = runtime;
|
|
15234
15416
|
this.runtime.setModelOptions(modelName, initialOptions);
|
|
15235
15417
|
this.options = this.runtime.getModelOptions(modelName);
|
|
15236
|
-
this.fullBasePath = (0,
|
|
15418
|
+
this.fullBasePath = (0, import_utils40.normalizeUrlPath)(this.options.parentPath + this.options.basePath);
|
|
15237
15419
|
this.modelName = modelName;
|
|
15238
15420
|
this.router = new import_express_json_router8.default(this.options.basePath, createSetCore(this.runtime), accessRouterResponseHandler);
|
|
15239
15421
|
this.model = new model_default(modelName, this.runtime);
|
|
@@ -15319,13 +15501,13 @@ var ModelRouter = class _ModelRouter {
|
|
|
15319
15501
|
}
|
|
15320
15502
|
logEndpoints() {
|
|
15321
15503
|
runWithRuntime(this.runtime, () => {
|
|
15322
|
-
(0,
|
|
15323
|
-
logInfoMessage(`${(0,
|
|
15504
|
+
(0, import_utils40.forEach)(this.router.getEndpoints(), ({ method, path }) => {
|
|
15505
|
+
logInfoMessage(`${(0, import_utils40.padEnd)(method, 6)} ${(0, import_utils40.normalizeUrlPath)(this.options.parentPath + path)}`);
|
|
15324
15506
|
});
|
|
15325
15507
|
});
|
|
15326
15508
|
}
|
|
15327
15509
|
set(keyOrOptions, value) {
|
|
15328
|
-
if (arguments.length === 2 && (0,
|
|
15510
|
+
if (arguments.length === 2 && (0, import_utils40.isString)(keyOrOptions)) {
|
|
15329
15511
|
assertMutableRouterOption("model", keyOrOptions);
|
|
15330
15512
|
this.runtime.setModelOption(
|
|
15331
15513
|
this.modelName,
|
|
@@ -15333,7 +15515,7 @@ var ModelRouter = class _ModelRouter {
|
|
|
15333
15515
|
value
|
|
15334
15516
|
);
|
|
15335
15517
|
}
|
|
15336
|
-
if (arguments.length === 1 && (0,
|
|
15518
|
+
if (arguments.length === 1 && (0, import_utils40.isPlainObject)(keyOrOptions)) {
|
|
15337
15519
|
assertMutableRouterOptions("model", keyOrOptions);
|
|
15338
15520
|
this.runtime.setModelOptions(
|
|
15339
15521
|
this.modelName,
|
|
@@ -15361,7 +15543,7 @@ var ModelRouter = class _ModelRouter {
|
|
|
15361
15543
|
|
|
15362
15544
|
// src/routers/root-router.ts
|
|
15363
15545
|
var import_express_json_router9 = __toESM(require("@web-ts-toolkit/express-json-router"));
|
|
15364
|
-
var
|
|
15546
|
+
var import_utils41 = require("@web-ts-toolkit/utils");
|
|
15365
15547
|
|
|
15366
15548
|
// src/core-data.ts
|
|
15367
15549
|
init_options();
|
|
@@ -15667,7 +15849,7 @@ var RootRouter = class {
|
|
|
15667
15849
|
this.setRoutes();
|
|
15668
15850
|
}
|
|
15669
15851
|
registerOpenApiRoute(route) {
|
|
15670
|
-
registerOpenApiRoute(this.runtime, (0,
|
|
15852
|
+
registerOpenApiRoute(this.runtime, (0, import_utils41.normalizeUrlPath)(this.basename), "root", route);
|
|
15671
15853
|
}
|
|
15672
15854
|
wrapResult(index, item, result2) {
|
|
15673
15855
|
return {
|
|
@@ -15727,8 +15909,8 @@ var RootRouter = class {
|
|
|
15727
15909
|
const presentation = ["skim", "includePermissions", "includeFieldPermissions"];
|
|
15728
15910
|
const optionKeys = {
|
|
15729
15911
|
new: presentation,
|
|
15730
|
-
list: [...presentation, "includeCount", "populateAccess"
|
|
15731
|
-
read: [...presentation, "populateAccess", "
|
|
15912
|
+
list: [...presentation, "includeCount", "populateAccess"],
|
|
15913
|
+
read: [...presentation, "populateAccess", "tryList"],
|
|
15732
15914
|
create: [...presentation, "populateAccess"],
|
|
15733
15915
|
update: [...presentation, "populateAccess", "returningAll"],
|
|
15734
15916
|
upsert: [...presentation, "populateAccess", "returningAll"]
|
|
@@ -15776,7 +15958,7 @@ var RootRouter = class {
|
|
|
15776
15958
|
groupItemsByOrder(items) {
|
|
15777
15959
|
const groups = /* @__PURE__ */ new Map();
|
|
15778
15960
|
items.forEach((item, index) => {
|
|
15779
|
-
const order = (0,
|
|
15961
|
+
const order = (0, import_utils41.isNumber)(item.order) ? item.order : 0;
|
|
15780
15962
|
const group = groups.get(order);
|
|
15781
15963
|
if (group) {
|
|
15782
15964
|
group.push({ index, item });
|
|
@@ -15847,7 +16029,7 @@ var RootRouter = class {
|
|
|
15847
16029
|
const arrResult = await this.runGroup(req, groupedItems[x]);
|
|
15848
16030
|
results.push(...arrResult);
|
|
15849
16031
|
}
|
|
15850
|
-
return (0,
|
|
16032
|
+
return (0, import_utils41.orderBy)(results, ["index"], ["asc"]);
|
|
15851
16033
|
});
|
|
15852
16034
|
this.registerOpenApiRoute({
|
|
15853
16035
|
method: "post",
|
|
@@ -15865,14 +16047,14 @@ var RootRouter = class {
|
|
|
15865
16047
|
|
|
15866
16048
|
// src/routers/data-router.ts
|
|
15867
16049
|
var import_express_json_router10 = __toESM(require("@web-ts-toolkit/express-json-router"));
|
|
15868
|
-
var
|
|
16050
|
+
var import_utils42 = require("@web-ts-toolkit/utils");
|
|
15869
16051
|
init_runtime();
|
|
15870
16052
|
init_helpers();
|
|
15871
16053
|
init_schemas();
|
|
15872
16054
|
var clientErrors4 = import_express_json_router10.default.clientErrors;
|
|
15873
16055
|
function setOption2(parentKey, optionKey, option) {
|
|
15874
|
-
const key = (0,
|
|
15875
|
-
const value = (0,
|
|
16056
|
+
const key = (0, import_utils42.isUndefined)(option) ? parentKey : `${parentKey}.${optionKey}`;
|
|
16057
|
+
const value = (0, import_utils42.isUndefined)(option) ? optionKey : option;
|
|
15876
16058
|
assertMutableRouterOption("data", key);
|
|
15877
16059
|
this.runtime.setDataOption(this.dataName, key, value);
|
|
15878
16060
|
return this;
|
|
@@ -15921,7 +16103,7 @@ var DataRouter = class {
|
|
|
15921
16103
|
this.runtime = runtime;
|
|
15922
16104
|
this.runtime.setDataOptions(dataName, initialOptions);
|
|
15923
16105
|
this.options = this.runtime.getDataOptions(dataName);
|
|
15924
|
-
this.fullBasePath = (0,
|
|
16106
|
+
this.fullBasePath = (0, import_utils42.normalizeUrlPath)(this.options.parentPath + this.options.basePath);
|
|
15925
16107
|
this.dataName = dataName;
|
|
15926
16108
|
this.router = new import_express_json_router10.default(this.options.basePath, createSetDataCore(this.runtime), accessRouterResponseHandler);
|
|
15927
16109
|
this.setCollectionRoutes();
|
|
@@ -15954,8 +16136,8 @@ var DataRouter = class {
|
|
|
15954
16136
|
req.query
|
|
15955
16137
|
);
|
|
15956
16138
|
const svc = this.getService(req);
|
|
15957
|
-
const includeCount = (0,
|
|
15958
|
-
const includeExtraHeaders = (0,
|
|
16139
|
+
const includeCount = (0, import_utils38.parseBooleanString)(include_count);
|
|
16140
|
+
const includeExtraHeaders = (0, import_utils38.parseBooleanString)(include_extra_headers);
|
|
15959
16141
|
const result2 = await svc.find(
|
|
15960
16142
|
{},
|
|
15961
16143
|
{ select: parseSelectParam(select), sort, skip, limit, page, pageSize: page_size },
|
|
@@ -16073,7 +16255,7 @@ var DataRouter = class {
|
|
|
16073
16255
|
});
|
|
16074
16256
|
}
|
|
16075
16257
|
set(keyOrOptions, value) {
|
|
16076
|
-
if (arguments.length === 2 && (0,
|
|
16258
|
+
if (arguments.length === 2 && (0, import_utils42.isString)(keyOrOptions)) {
|
|
16077
16259
|
assertMutableRouterOption("data", keyOrOptions);
|
|
16078
16260
|
this.runtime.setDataOption(
|
|
16079
16261
|
this.dataName,
|
|
@@ -16081,7 +16263,7 @@ var DataRouter = class {
|
|
|
16081
16263
|
value
|
|
16082
16264
|
);
|
|
16083
16265
|
}
|
|
16084
|
-
if (arguments.length === 1 && (0,
|
|
16266
|
+
if (arguments.length === 1 && (0, import_utils42.isPlainObject)(keyOrOptions)) {
|
|
16085
16267
|
assertMutableRouterOptions("data", keyOrOptions);
|
|
16086
16268
|
this.runtime.setDataOptions(this.dataName, keyOrOptions);
|
|
16087
16269
|
}
|
|
@@ -16216,7 +16398,7 @@ function createRuntimeApi(runtime) {
|
|
|
16216
16398
|
const wtt2 = runtimeMiddleware;
|
|
16217
16399
|
wtt2.runtime = runtime;
|
|
16218
16400
|
wtt2.createRouter = function(modelName, options) {
|
|
16219
|
-
if ((0,
|
|
16401
|
+
if ((0, import_utils43.isUndefined)(options)) {
|
|
16220
16402
|
return new RootRouter(modelName, runtime);
|
|
16221
16403
|
}
|
|
16222
16404
|
if (typeof modelName === "string") {
|
|
@@ -16237,10 +16419,10 @@ function createRuntimeApi(runtime) {
|
|
|
16237
16419
|
};
|
|
16238
16420
|
wtt2.combineRoutes = combineRoutes;
|
|
16239
16421
|
wtt2.set = function(keyOrOptions, value) {
|
|
16240
|
-
if (arguments.length === 2 && (0,
|
|
16422
|
+
if (arguments.length === 2 && (0, import_utils43.isString)(keyOrOptions)) {
|
|
16241
16423
|
return runtime.setGlobalOption(keyOrOptions, value);
|
|
16242
16424
|
}
|
|
16243
|
-
if (arguments.length === 1 && (0,
|
|
16425
|
+
if (arguments.length === 1 && (0, import_utils43.isPlainObject)(keyOrOptions)) {
|
|
16244
16426
|
return runtime.setGlobalOptions(keyOrOptions);
|
|
16245
16427
|
}
|
|
16246
16428
|
};
|