@web-ts-toolkit/access-router 0.55.0 → 0.57.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 +218 -56
- package/advanced.d.mts +1 -1
- package/advanced.d.ts +1 -1
- package/advanced.js +100 -61
- package/advanced.mjs +67 -28
- package/index.d.mts +2 -2
- package/index.d.ts +2 -2
- package/index.js +624 -533
- package/index.mjs +361 -270
- package/llms.txt +3 -2
- package/package.json +3 -3
- package/{parsers-BrVRL2fg.d.mts → parsers-CngKnVjW.d.mts} +93 -14
- package/{parsers-BrVRL2fg.d.ts → parsers-CngKnVjW.d.ts} +93 -14
package/index.js
CHANGED
|
@@ -2161,9 +2161,34 @@ var init_field_catalog = __esm({
|
|
|
2161
2161
|
}
|
|
2162
2162
|
});
|
|
2163
2163
|
|
|
2164
|
+
// src/acl/populate-target-configuration.ts
|
|
2165
|
+
function capturePopulateTargetConfiguration(runtime, modelName, source, proposedOptions) {
|
|
2166
|
+
const label = `Populate target "${modelName}" for ${source}`;
|
|
2167
|
+
if (!proposedOptions && !runtime.hasModel(modelName))
|
|
2168
|
+
authorizationError(
|
|
2169
|
+
`${label} must be configured first in this runtime; register its Mongoose model and setModelOptions with an object permissionSchema`
|
|
2170
|
+
);
|
|
2171
|
+
const model = runtime.getModelInstance(modelName);
|
|
2172
|
+
if (!model) authorizationError(`${label} requires an actual registered Mongoose model in this runtime`);
|
|
2173
|
+
const options = proposedOptions ?? runtime.getModelOptions(modelName);
|
|
2174
|
+
const permissionSchema = options.permissionSchema === void 0 ? runtime.getDefaultModelOption("permissionSchema") : options.permissionSchema;
|
|
2175
|
+
if (!(0, import_utils15.isPlainObject)(permissionSchema))
|
|
2176
|
+
authorizationError(
|
|
2177
|
+
`${label} requires an effective object permissionSchema; configure the model or runtime model defaults ({} explicitly closes business fields)`
|
|
2178
|
+
);
|
|
2179
|
+
return { model, options: { ...options, permissionSchema } };
|
|
2180
|
+
}
|
|
2181
|
+
var import_utils15;
|
|
2182
|
+
var init_populate_target_configuration = __esm({
|
|
2183
|
+
"src/acl/populate-target-configuration.ts"() {
|
|
2184
|
+
import_utils15 = require("@web-ts-toolkit/utils");
|
|
2185
|
+
init_authorization_snapshot();
|
|
2186
|
+
}
|
|
2187
|
+
});
|
|
2188
|
+
|
|
2164
2189
|
// src/acl/virtual-populate-dependencies.ts
|
|
2165
2190
|
function record(value, label) {
|
|
2166
|
-
if (!(0,
|
|
2191
|
+
if (!(0, import_utils16.isPlainObject)(value)) return fail(label, "entries must be plain { path, select? } objects");
|
|
2167
2192
|
for (const key of Reflect.ownKeys(value)) {
|
|
2168
2193
|
const property = Object.getOwnPropertyDescriptor(value, key);
|
|
2169
2194
|
if (typeof key !== "string" || !property.enumerable || !("value" in property))
|
|
@@ -2251,7 +2276,9 @@ function normalizeSelection(select, catalog, label) {
|
|
|
2251
2276
|
includeId: selection.includes("_id")
|
|
2252
2277
|
};
|
|
2253
2278
|
}
|
|
2254
|
-
function captureVirtualPopulateDependencies(runtime, modelName, options) {
|
|
2279
|
+
function captureVirtualPopulateDependencies(runtime, modelName, options, globalOptions = runtime.getGlobalOptions()) {
|
|
2280
|
+
const requireOperationAccessForPopulateDependencies = globalOptions.requireOperationAccessForPopulateDependencies !== false;
|
|
2281
|
+
const requireOperationAccessForPopulateQueries = globalOptions.requireOperationAccessForPopulateQueries !== false;
|
|
2255
2282
|
const model = runtime.getModelInstance(modelName);
|
|
2256
2283
|
const targets = /* @__PURE__ */ new Map();
|
|
2257
2284
|
const scopes = [];
|
|
@@ -2291,15 +2318,23 @@ function captureVirtualPopulateDependencies(runtime, modelName, options) {
|
|
|
2291
2318
|
label,
|
|
2292
2319
|
`target "${ref}" requires a registered same-connection non-discriminator ObjectId model bound to the source ref`
|
|
2293
2320
|
);
|
|
2294
|
-
const
|
|
2321
|
+
const { options: targetOptions } = capturePopulateTargetConfiguration(
|
|
2322
|
+
runtime,
|
|
2323
|
+
ref,
|
|
2324
|
+
`dependsOnPopulate virtual "${label}"`,
|
|
2325
|
+
ref === modelName ? options : void 0
|
|
2326
|
+
);
|
|
2295
2327
|
const defaults = runtime.getDefaultModelOptions();
|
|
2296
|
-
const readOption = (key) => resolveNestedOption((path2, fallback) => (0,
|
|
2328
|
+
const readOption = (key) => resolveNestedOption((path2, fallback) => (0, import_utils16.get)(targetOptions, path2, fallback), key, (0, import_utils16.get)(defaults, key));
|
|
2297
2329
|
const documentPermissionField = targetOptions.documentPermissionField ?? defaults.documentPermissionField;
|
|
2298
2330
|
const catalog = captureAuthorizationFieldCatalog(targetModel.schema, void 0, documentPermissionField);
|
|
2299
2331
|
const configuration = copyAuthorizationValue(
|
|
2300
2332
|
{
|
|
2301
2333
|
catalog,
|
|
2302
2334
|
documentPermissionField,
|
|
2335
|
+
requireOperationAccessForPopulateDependencies,
|
|
2336
|
+
requireOperationAccessForPopulateQueries,
|
|
2337
|
+
permissionSchema: targetOptions.permissionSchema,
|
|
2303
2338
|
operationAccess: { read: readOption("operationAccess.read") },
|
|
2304
2339
|
baseFilter: { read: readOption("baseFilter.read") },
|
|
2305
2340
|
overrideFilter: { read: readOption("overrideFilter.read") },
|
|
@@ -2348,13 +2383,13 @@ function captureVirtualPopulateDependencies(runtime, modelName, options) {
|
|
|
2348
2383
|
);
|
|
2349
2384
|
continue;
|
|
2350
2385
|
}
|
|
2351
|
-
if (!(0,
|
|
2386
|
+
if (!(0, import_utils16.isPlainObject)(raw)) continue;
|
|
2352
2387
|
const entry = raw;
|
|
2353
2388
|
const label = join(sourcePrefix, name);
|
|
2354
2389
|
captureList(entry.dependsOnPopulate, label);
|
|
2355
2390
|
if (!("get" in entry))
|
|
2356
2391
|
for (const access of accesses) {
|
|
2357
|
-
if ((0,
|
|
2392
|
+
if ((0, import_utils16.isPlainObject)(entry[access]))
|
|
2358
2393
|
captureList(entry[access].dependsOnPopulate, `${label}.${access}`);
|
|
2359
2394
|
}
|
|
2360
2395
|
const byAccess = {};
|
|
@@ -2379,8 +2414,8 @@ function captureVirtualPopulateDependencies(runtime, modelName, options) {
|
|
|
2379
2414
|
visit(options.virtuals ?? {}, model?.schema, "", [], !!model && varyingModel(model));
|
|
2380
2415
|
return Object.freeze({ scopes: Object.freeze(scopes) });
|
|
2381
2416
|
}
|
|
2382
|
-
function captureVirtualPopulateSnapshot(runtime, modelName, options) {
|
|
2383
|
-
const snapshot = captureVirtualPopulateDependencies(runtime, modelName, options);
|
|
2417
|
+
function captureVirtualPopulateSnapshot(runtime, modelName, options, globalOptions = runtime.getGlobalOptions()) {
|
|
2418
|
+
const snapshot = captureVirtualPopulateDependencies(runtime, modelName, options, globalOptions);
|
|
2384
2419
|
const token = () => {
|
|
2385
2420
|
};
|
|
2386
2421
|
snapshots.set(token, snapshot);
|
|
@@ -2404,15 +2439,16 @@ function resolveVirtualPopulateDependencies(configuration, scopePath, virtualNam
|
|
|
2404
2439
|
)
|
|
2405
2440
|
);
|
|
2406
2441
|
}
|
|
2407
|
-
var
|
|
2442
|
+
var import_utils16, elementType, join, within, accesses, fail, varyingSchema, varyingModel, snapshots;
|
|
2408
2443
|
var init_virtual_populate_dependencies = __esm({
|
|
2409
2444
|
"src/acl/virtual-populate-dependencies.ts"() {
|
|
2410
|
-
|
|
2445
|
+
import_utils16 = require("@web-ts-toolkit/utils");
|
|
2411
2446
|
init_query();
|
|
2412
2447
|
init_manager();
|
|
2413
2448
|
init_authorization_snapshot();
|
|
2414
2449
|
init_field_catalog();
|
|
2415
2450
|
init_virtual_descriptor();
|
|
2451
|
+
init_populate_target_configuration();
|
|
2416
2452
|
elementType = (type) => type.$embeddedSchemaType ?? type.embeddedSchemaType ?? type.caster;
|
|
2417
2453
|
join = (prefix, path) => prefix ? `${prefix}.${path}` : path;
|
|
2418
2454
|
within = (path, parent) => path === parent || path.startsWith(`${parent}.`);
|
|
@@ -2427,14 +2463,14 @@ var init_virtual_populate_dependencies = __esm({
|
|
|
2427
2463
|
});
|
|
2428
2464
|
|
|
2429
2465
|
// src/runtime.ts
|
|
2430
|
-
var import_mongoose4, import_mongoose_schema_jsonschema,
|
|
2466
|
+
var import_mongoose4, import_mongoose_schema_jsonschema, import_utils17, 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, isVirtualContainerValue2, virtualFullPath, virtualPathsOverlap, collectStoredTopLevel, getChildSchemaForField, getNestedChildFields, cloneVirtualsForValidation, validateVirtualDependsOn, validateVirtualLeafValue, validateVirtualsScope, validateVirtualsTree, AccessRuntime, defaultRuntime;
|
|
2431
2467
|
var init_runtime = __esm({
|
|
2432
2468
|
"src/runtime.ts"() {
|
|
2433
2469
|
import_mongoose4 = __toESM(require("mongoose"));
|
|
2434
2470
|
init_public_admission();
|
|
2435
2471
|
init_hydration();
|
|
2436
2472
|
import_mongoose_schema_jsonschema = __toESM(require("mongoose-schema-jsonschema"));
|
|
2437
|
-
|
|
2473
|
+
import_utils17 = require("@web-ts-toolkit/utils");
|
|
2438
2474
|
init_helpers();
|
|
2439
2475
|
init_registry();
|
|
2440
2476
|
init_logger_default();
|
|
@@ -2463,44 +2499,44 @@ var init_runtime = __esm({
|
|
|
2463
2499
|
listHardLimit: DEFAULT_LIST_HARD_LIMIT
|
|
2464
2500
|
};
|
|
2465
2501
|
normalizeBasePath = (name, value) => {
|
|
2466
|
-
if ((0,
|
|
2502
|
+
if ((0, import_utils17.isNil)(value)) {
|
|
2467
2503
|
return `/${pluralize(name)}`;
|
|
2468
2504
|
}
|
|
2469
|
-
return (0,
|
|
2505
|
+
return (0, import_utils17.isString)(value) ? (0, import_utils17.addLeadingSlash)(value) : "";
|
|
2470
2506
|
};
|
|
2471
2507
|
hasModelPermission = (value, modelPermissionPrefix) => {
|
|
2472
2508
|
if (!modelPermissionPrefix) {
|
|
2473
2509
|
return true;
|
|
2474
2510
|
}
|
|
2475
|
-
if ((0,
|
|
2511
|
+
if ((0, import_utils17.isString)(value)) {
|
|
2476
2512
|
return value.trim().split(" ").some((item) => item.startsWith(modelPermissionPrefix));
|
|
2477
2513
|
}
|
|
2478
|
-
if ((0,
|
|
2514
|
+
if ((0, import_utils17.isArray)(value)) {
|
|
2479
2515
|
return value.some((item) => {
|
|
2480
|
-
if ((0,
|
|
2516
|
+
if ((0, import_utils17.isString)(item) || (0, import_utils17.isArray)(item)) {
|
|
2481
2517
|
return hasModelPermission(item, modelPermissionPrefix);
|
|
2482
2518
|
}
|
|
2483
2519
|
return true;
|
|
2484
2520
|
});
|
|
2485
2521
|
}
|
|
2486
|
-
return (0,
|
|
2522
|
+
return (0, import_utils17.isFunction)(value);
|
|
2487
2523
|
};
|
|
2488
2524
|
classifyPermissionSchema = (permissionSchema, modelPermissionPrefix) => {
|
|
2489
2525
|
const schemaKeys = Object.keys(permissionSchema);
|
|
2490
2526
|
const globalPermissionKeys = {};
|
|
2491
2527
|
const modelPermissionKeys = {};
|
|
2492
|
-
(0,
|
|
2528
|
+
(0, import_utils17.forEach)(schemaKeys, (schemaKey) => {
|
|
2493
2529
|
const schemaRule = permissionSchema[schemaKey];
|
|
2494
|
-
const ruleEntries = (0,
|
|
2530
|
+
const ruleEntries = (0, import_utils17.isPlainObject)(schemaRule) ? Object.entries(schemaRule) : FIELD_ACCESS_KEYS.map((accessKey) => [accessKey, schemaRule]);
|
|
2495
2531
|
for (let x = 0; x < ruleEntries.length; x++) {
|
|
2496
2532
|
const [accessKey, value] = ruleEntries[x];
|
|
2497
|
-
if (!(0,
|
|
2533
|
+
if (!(0, import_utils17.isArray)(globalPermissionKeys[accessKey])) {
|
|
2498
2534
|
globalPermissionKeys[accessKey] = [];
|
|
2499
2535
|
}
|
|
2500
|
-
if (!(0,
|
|
2536
|
+
if (!(0, import_utils17.isArray)(modelPermissionKeys[accessKey])) {
|
|
2501
2537
|
modelPermissionKeys[accessKey] = [];
|
|
2502
2538
|
}
|
|
2503
|
-
if ((0,
|
|
2539
|
+
if ((0, import_utils17.isBoolean)(value)) {
|
|
2504
2540
|
globalPermissionKeys[accessKey].push(schemaKey);
|
|
2505
2541
|
continue;
|
|
2506
2542
|
}
|
|
@@ -2532,13 +2568,13 @@ var init_runtime = __esm({
|
|
|
2532
2568
|
VIRTUAL_RESERVED_NAMES = /* @__PURE__ */ new Set(["_id", "__v", "id"]);
|
|
2533
2569
|
VIRTUAL_DANGEROUS_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
2534
2570
|
VIRTUAL_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
2535
|
-
isVirtualContainerValue2 = (value) => (0,
|
|
2571
|
+
isVirtualContainerValue2 = (value) => (0, import_utils17.isPlainObject)(value) && "sub" in value;
|
|
2536
2572
|
virtualFullPath = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
2537
2573
|
virtualPathsOverlap = (virtualPath, permissionField) => {
|
|
2538
2574
|
if (!virtualPath || !permissionField) return false;
|
|
2539
2575
|
try {
|
|
2540
|
-
if ((0,
|
|
2541
|
-
if ((0,
|
|
2576
|
+
if ((0, import_utils17.get)((0, import_utils17.set)({}, virtualPath, true), permissionField) !== void 0) return true;
|
|
2577
|
+
if ((0, import_utils17.get)((0, import_utils17.set)({}, permissionField, true), virtualPath) !== void 0) return true;
|
|
2542
2578
|
} catch {
|
|
2543
2579
|
return false;
|
|
2544
2580
|
}
|
|
@@ -2599,12 +2635,12 @@ var init_runtime = __esm({
|
|
|
2599
2635
|
};
|
|
2600
2636
|
validateVirtualDependsOn = (dependsOn, entryLabel, storedFields, siblingVirtualNames) => {
|
|
2601
2637
|
if (dependsOn === void 0) return [];
|
|
2602
|
-
if (!(0,
|
|
2638
|
+
if (!(0, import_utils17.isArray)(dependsOn)) {
|
|
2603
2639
|
throw new Error(`Virtual ${entryLabel}: dependsOn must be an array of top-level persisted field names`);
|
|
2604
2640
|
}
|
|
2605
2641
|
const list = dependsOn;
|
|
2606
2642
|
for (const dep of list) {
|
|
2607
|
-
if (!(0,
|
|
2643
|
+
if (!(0, import_utils17.isString)(dep) || dep.length === 0) {
|
|
2608
2644
|
throw new Error(`Virtual ${entryLabel}: dependsOn entries must be non-empty strings`);
|
|
2609
2645
|
}
|
|
2610
2646
|
if (dep.includes(".")) {
|
|
@@ -2626,12 +2662,12 @@ var init_runtime = __esm({
|
|
|
2626
2662
|
return list;
|
|
2627
2663
|
};
|
|
2628
2664
|
validateVirtualLeafValue = (value, entryLabel, storedFields, siblingVirtualNames, sharedDependsOn) => {
|
|
2629
|
-
if ((0,
|
|
2630
|
-
if (!(0,
|
|
2665
|
+
if ((0, import_utils17.isFunction)(value)) return;
|
|
2666
|
+
if (!(0, import_utils17.isPlainObject)(value)) {
|
|
2631
2667
|
throw new Error(`Virtual ${entryLabel}: descriptor must be a getter function or { get, dependsOn }`);
|
|
2632
2668
|
}
|
|
2633
2669
|
const record3 = value;
|
|
2634
|
-
if (!(0,
|
|
2670
|
+
if (!(0, import_utils17.isFunction)(record3.get)) {
|
|
2635
2671
|
throw new Error(`Virtual ${entryLabel}: descriptor.get must be a callable getter function`);
|
|
2636
2672
|
}
|
|
2637
2673
|
validateVirtualDependsOn(record3.dependsOn ?? sharedDependsOn, entryLabel, storedFields, siblingVirtualNames);
|
|
@@ -2673,7 +2709,7 @@ var init_runtime = __esm({
|
|
|
2673
2709
|
`Virtual ${scopeLabel}${name}: scope-container must only hold "sub" (embedded container "${name}" is not a virtual-leaf collision)`
|
|
2674
2710
|
);
|
|
2675
2711
|
}
|
|
2676
|
-
if (!(0,
|
|
2712
|
+
if (!(0, import_utils17.isPlainObject)(record4.sub)) {
|
|
2677
2713
|
throw new Error(`Virtual ${scopeLabel}${name}: scope-container "sub" must be a plain object`);
|
|
2678
2714
|
}
|
|
2679
2715
|
continue;
|
|
@@ -2683,8 +2719,8 @@ var init_runtime = __esm({
|
|
|
2683
2719
|
`Virtual ${scopeLabel}${name}: collides with a stored path (inspected actual Mongoose schema/child scope; getModelAtt alone is insufficient)`
|
|
2684
2720
|
);
|
|
2685
2721
|
}
|
|
2686
|
-
if ((0,
|
|
2687
|
-
if (!(0,
|
|
2722
|
+
if ((0, import_utils17.isFunction)(raw)) continue;
|
|
2723
|
+
if (!(0, import_utils17.isPlainObject)(raw)) {
|
|
2688
2724
|
throw new Error(
|
|
2689
2725
|
`Virtual ${scopeLabel}${name}: malformed descriptor (expected getter, { get, dependsOn }, or per-access record)`
|
|
2690
2726
|
);
|
|
@@ -2738,7 +2774,7 @@ var init_runtime = __esm({
|
|
|
2738
2774
|
};
|
|
2739
2775
|
validateVirtualsTree = (model, virtuals, documentPermissionField, modelName) => {
|
|
2740
2776
|
if (virtuals === void 0 || virtuals === null) return;
|
|
2741
|
-
if (!(0,
|
|
2777
|
+
if (!(0, import_utils17.isPlainObject)(virtuals)) {
|
|
2742
2778
|
throw new Error(`Virtuals for model "${modelName}": virtuals must be a plain object mapping names to descriptors`);
|
|
2743
2779
|
}
|
|
2744
2780
|
const rootSchema = model?.schema ?? null;
|
|
@@ -2790,7 +2826,8 @@ var init_runtime = __esm({
|
|
|
2790
2826
|
{
|
|
2791
2827
|
requestPermissionField: "_permissions",
|
|
2792
2828
|
globalPermissions: () => ({}),
|
|
2793
|
-
|
|
2829
|
+
requireOperationAccessForPopulateQueries: true,
|
|
2830
|
+
requireOperationAccessForPopulateDependencies: true,
|
|
2794
2831
|
logger: defaultLogger,
|
|
2795
2832
|
requestComplexity: defaultRequestComplexity
|
|
2796
2833
|
},
|
|
@@ -2845,7 +2882,7 @@ var init_runtime = __esm({
|
|
|
2845
2882
|
}
|
|
2846
2883
|
registerOpenApiRoute(route) {
|
|
2847
2884
|
this.openApiRegistry.register(
|
|
2848
|
-
this.openApiPathPrefix ? { ...route, path: (0,
|
|
2885
|
+
this.openApiPathPrefix ? { ...route, path: (0, import_utils17.normalizeUrlPath)(`${this.openApiPathPrefix}/${route.path}`) } : route
|
|
2849
2886
|
);
|
|
2850
2887
|
}
|
|
2851
2888
|
/**
|
|
@@ -2856,7 +2893,7 @@ var init_runtime = __esm({
|
|
|
2856
2893
|
*/
|
|
2857
2894
|
withOpenApiPathPrefix(prefix, build) {
|
|
2858
2895
|
const previous = this.openApiPathPrefix;
|
|
2859
|
-
this.openApiPathPrefix = (0,
|
|
2896
|
+
this.openApiPathPrefix = (0, import_utils17.normalizeUrlPath)(`${previous}/${prefix}`);
|
|
2860
2897
|
try {
|
|
2861
2898
|
return build();
|
|
2862
2899
|
} finally {
|
|
@@ -2963,9 +3000,18 @@ var init_runtime = __esm({
|
|
|
2963
3000
|
}
|
|
2964
3001
|
/** Shallowly replace supplied global values; nested objects such as requestComplexity are not deep-merged. */
|
|
2965
3002
|
setGlobalOptions(options) {
|
|
2966
|
-
|
|
3003
|
+
const next = { ...options };
|
|
3004
|
+
if ("requireOperationAccessForPopulateQueries" in next)
|
|
3005
|
+
next.requireOperationAccessForPopulateQueries = next.requireOperationAccessForPopulateQueries !== false;
|
|
3006
|
+
if ("requireOperationAccessForPopulateDependencies" in next)
|
|
3007
|
+
next.requireOperationAccessForPopulateDependencies = next.requireOperationAccessForPopulateDependencies !== false;
|
|
3008
|
+
this.globalOptions.assign(next);
|
|
2967
3009
|
}
|
|
2968
3010
|
setGlobalOption(key, value) {
|
|
3011
|
+
if (key === "requireOperationAccessForPopulateQueries" || key === "requireOperationAccessForPopulateDependencies") {
|
|
3012
|
+
this.globalOptions.set(key, value !== false);
|
|
3013
|
+
return;
|
|
3014
|
+
}
|
|
2969
3015
|
this.globalOptions.set(key, value);
|
|
2970
3016
|
}
|
|
2971
3017
|
getGlobalOptions() {
|
|
@@ -2992,7 +3038,7 @@ var init_runtime = __esm({
|
|
|
2992
3038
|
if (keyStr === "defaults") assertPublicDefaults(value);
|
|
2993
3039
|
else if (keyStr.startsWith("defaults.")) {
|
|
2994
3040
|
const proposed = {};
|
|
2995
|
-
(0,
|
|
3041
|
+
(0, import_utils17.set)(proposed, keyStr.slice("defaults.".length), value);
|
|
2996
3042
|
assertPublicDefaults(proposed);
|
|
2997
3043
|
}
|
|
2998
3044
|
this.defaultModelOptions.set(key, value);
|
|
@@ -3021,7 +3067,7 @@ var init_runtime = __esm({
|
|
|
3021
3067
|
}).onchange("basePath", function(newval, key, target) {
|
|
3022
3068
|
target[key] = normalizeBasePath(
|
|
3023
3069
|
modelName,
|
|
3024
|
-
(0,
|
|
3070
|
+
(0, import_utils17.isString)(newval) || (0, import_utils17.isNil)(newval) ? newval : void 0
|
|
3025
3071
|
);
|
|
3026
3072
|
}).build();
|
|
3027
3073
|
this.modelJsonSchemas[modelName] = model.jsonSchema();
|
|
@@ -3065,7 +3111,7 @@ var init_runtime = __esm({
|
|
|
3065
3111
|
if (keyStr === "defaults") assertPublicDefaults(value);
|
|
3066
3112
|
else if (keyStr.startsWith("defaults.")) {
|
|
3067
3113
|
const proposed = {};
|
|
3068
|
-
(0,
|
|
3114
|
+
(0, import_utils17.set)(proposed, keyStr.slice("defaults.".length), value);
|
|
3069
3115
|
assertPublicDefaults(proposed);
|
|
3070
3116
|
}
|
|
3071
3117
|
const manager = this.modelOptions[modelName];
|
|
@@ -3086,15 +3132,15 @@ var init_runtime = __esm({
|
|
|
3086
3132
|
const segments = nestedPath.split(".");
|
|
3087
3133
|
let cursor = cloned;
|
|
3088
3134
|
for (let i = 0; i < segments.length - 1; i++) {
|
|
3089
|
-
if (!(0,
|
|
3135
|
+
if (!(0, import_utils17.isPlainObject)(cursor)) break;
|
|
3090
3136
|
cursor = cursor[segments[i]];
|
|
3091
3137
|
}
|
|
3092
|
-
if ((0,
|
|
3138
|
+
if ((0, import_utils17.isPlainObject)(cursor)) {
|
|
3093
3139
|
delete cursor[segments[segments.length - 1]];
|
|
3094
3140
|
}
|
|
3095
3141
|
proposedVirtuals = cloned;
|
|
3096
3142
|
} else {
|
|
3097
|
-
(0,
|
|
3143
|
+
(0, import_utils17.set)(cloned, nestedPath, value);
|
|
3098
3144
|
proposedVirtuals = cloned;
|
|
3099
3145
|
}
|
|
3100
3146
|
}
|
|
@@ -3195,7 +3241,7 @@ var init_runtime = __esm({
|
|
|
3195
3241
|
manager.onchange("basePath", function(newval, key, target) {
|
|
3196
3242
|
target[key] = normalizeBasePath(
|
|
3197
3243
|
dataName,
|
|
3198
|
-
(0,
|
|
3244
|
+
(0, import_utils17.isString)(newval) || (0, import_utils17.isNil)(newval) ? newval : void 0
|
|
3199
3245
|
);
|
|
3200
3246
|
}).build();
|
|
3201
3247
|
return manager;
|
|
@@ -3255,20 +3301,20 @@ var init_runtime = __esm({
|
|
|
3255
3301
|
const schema = model.schema;
|
|
3256
3302
|
this.modelRefs[modelName] = buildRefs(schema.tree);
|
|
3257
3303
|
this.modelSubs[modelName] = buildSubPaths(schema.tree);
|
|
3258
|
-
this.modelAtts[modelName] = (0,
|
|
3304
|
+
this.modelAtts[modelName] = (0, import_utils17.keys)(schema.obj);
|
|
3259
3305
|
}
|
|
3260
3306
|
getModelRef(modelName, refPath) {
|
|
3261
3307
|
this.ensureModelMeta(modelName);
|
|
3262
|
-
const value = (0,
|
|
3263
|
-
return (0,
|
|
3308
|
+
const value = (0, import_utils17.get)(this.modelRefs, `${modelName}.${refPath}`, null);
|
|
3309
|
+
return (0, import_utils17.isString)(value) ? value : null;
|
|
3264
3310
|
}
|
|
3265
3311
|
getModelSub(modelName) {
|
|
3266
3312
|
this.ensureModelMeta(modelName);
|
|
3267
|
-
return (0,
|
|
3313
|
+
return (0, import_utils17.get)(this.modelSubs, modelName, []);
|
|
3268
3314
|
}
|
|
3269
3315
|
getModelAtt(modelName) {
|
|
3270
3316
|
this.ensureModelMeta(modelName);
|
|
3271
|
-
return (0,
|
|
3317
|
+
return (0, import_utils17.get)(this.modelAtts, modelName, []);
|
|
3272
3318
|
}
|
|
3273
3319
|
};
|
|
3274
3320
|
defaultRuntime = new AccessRuntime({ allowGlobalModelLookup: true });
|
|
@@ -3444,10 +3490,10 @@ var init_options = __esm({
|
|
|
3444
3490
|
});
|
|
3445
3491
|
|
|
3446
3492
|
// src/permission.ts
|
|
3447
|
-
var
|
|
3493
|
+
var import_utils18, Permission, permission_default;
|
|
3448
3494
|
var init_permission = __esm({
|
|
3449
3495
|
"src/permission.ts"() {
|
|
3450
|
-
|
|
3496
|
+
import_utils18 = require("@web-ts-toolkit/utils");
|
|
3451
3497
|
Permission = class {
|
|
3452
3498
|
constructor(permissions) {
|
|
3453
3499
|
this.permissions = { ...permissions };
|
|
@@ -3463,7 +3509,7 @@ var init_permission = __esm({
|
|
|
3463
3509
|
return [permissionOrPermissions].concat(permissions);
|
|
3464
3510
|
}
|
|
3465
3511
|
hasKey(permission) {
|
|
3466
|
-
return (0,
|
|
3512
|
+
return (0, import_utils18.hasOwn)(this.permissions, permission);
|
|
3467
3513
|
}
|
|
3468
3514
|
has(permission) {
|
|
3469
3515
|
return this.permissions[permission] === true;
|
|
@@ -3581,7 +3627,6 @@ function normalizePolicy(value, applicability, configuration, targets) {
|
|
|
3581
3627
|
const matches = targets.filter((target2) => target2.path === path);
|
|
3582
3628
|
if (matches.length !== 1) authorizationError(`unused or ambiguous related path: ${path}`);
|
|
3583
3629
|
const target = matches[0];
|
|
3584
|
-
if (target.kind === "passthrough") authorizationError(`related policy requires a registered target: ${path}`);
|
|
3585
3630
|
const child = authorizationRecord(entry, `related.${path}`);
|
|
3586
3631
|
assertAuthorizationKeys(
|
|
3587
3632
|
child,
|
|
@@ -3950,7 +3995,7 @@ function attachIncludeOutput(doc, path, value) {
|
|
|
3950
3995
|
const state = stateFor(doc);
|
|
3951
3996
|
if (!state) throw new Error("Include attachment requires a prepared output row");
|
|
3952
3997
|
state.attachments.push({ path, value });
|
|
3953
|
-
(0,
|
|
3998
|
+
(0, import_utils19.set)(doc, path, deepIsolateValue(value));
|
|
3954
3999
|
}
|
|
3955
4000
|
function getIncludeSource(doc) {
|
|
3956
4001
|
return stateFor(doc)?.source ?? doc;
|
|
@@ -3965,14 +4010,14 @@ function restoreIncludeOutput(doc, output) {
|
|
|
3965
4010
|
for (const { path, value } of attachments) {
|
|
3966
4011
|
const copy = deepIsolateValue(value);
|
|
3967
4012
|
if (copy !== null && typeof copy === "object") origins.set(copy, value);
|
|
3968
|
-
(0,
|
|
4013
|
+
(0, import_utils19.set)(output, path, copy);
|
|
3969
4014
|
}
|
|
3970
4015
|
return origins;
|
|
3971
4016
|
}
|
|
3972
|
-
var
|
|
4017
|
+
var import_utils19, outputs2, stateFor;
|
|
3973
4018
|
var init_include_output = __esm({
|
|
3974
4019
|
"src/output/include-output.ts"() {
|
|
3975
|
-
|
|
4020
|
+
import_utils19 = require("@web-ts-toolkit/utils");
|
|
3976
4021
|
init_document_authorization();
|
|
3977
4022
|
init_document();
|
|
3978
4023
|
outputs2 = /* @__PURE__ */ new WeakMap();
|
|
@@ -4314,10 +4359,10 @@ function planVirtualProjection(args) {
|
|
|
4314
4359
|
relatedPlans
|
|
4315
4360
|
};
|
|
4316
4361
|
}
|
|
4317
|
-
var
|
|
4362
|
+
var import_utils21, getScopedPermissionSchema, resolveAlwaysSelectForAccess, stripVirtualsFromNormalizedSelect, snapshotVirtualPaths, stripLeadingDash, dbPrefixForScope, toDbPath;
|
|
4318
4363
|
var init_virtual_projection = __esm({
|
|
4319
4364
|
"src/acl/virtual-projection.ts"() {
|
|
4320
|
-
|
|
4365
|
+
import_utils21 = require("@web-ts-toolkit/utils");
|
|
4321
4366
|
init_query();
|
|
4322
4367
|
init_field_authorization();
|
|
4323
4368
|
init_output_projection();
|
|
@@ -4325,20 +4370,20 @@ var init_virtual_projection = __esm({
|
|
|
4325
4370
|
init_virtual_populate_dependencies();
|
|
4326
4371
|
init_virtual_descriptor();
|
|
4327
4372
|
getScopedPermissionSchema = (root, scopePath) => {
|
|
4328
|
-
if (!root || !(0,
|
|
4373
|
+
if (!root || !(0, import_utils21.isPlainObject)(root)) return null;
|
|
4329
4374
|
if (scopePath.length === 0) return root;
|
|
4330
|
-
const scoped = (0,
|
|
4331
|
-
return (0,
|
|
4375
|
+
const scoped = (0, import_utils21.get)(root, scopePath.join("."));
|
|
4376
|
+
return (0, import_utils21.isPlainObject)(scoped) ? scoped : null;
|
|
4332
4377
|
};
|
|
4333
4378
|
resolveAlwaysSelectForAccess = (raw, access) => {
|
|
4334
4379
|
if (!raw) return [];
|
|
4335
|
-
if ((0,
|
|
4336
|
-
if ((0,
|
|
4380
|
+
if ((0, import_utils21.isArray)(raw)) return [...raw];
|
|
4381
|
+
if ((0, import_utils21.isPlainObject)(raw)) {
|
|
4337
4382
|
const record3 = raw;
|
|
4338
4383
|
const exact = record3[access];
|
|
4339
|
-
if ((0,
|
|
4384
|
+
if ((0, import_utils21.isArray)(exact)) return [...exact];
|
|
4340
4385
|
const def = record3.default;
|
|
4341
|
-
if ((0,
|
|
4386
|
+
if ((0, import_utils21.isArray)(def)) return [...def];
|
|
4342
4387
|
return [];
|
|
4343
4388
|
}
|
|
4344
4389
|
return [];
|
|
@@ -4603,18 +4648,25 @@ var init_output_projection = __esm({
|
|
|
4603
4648
|
|
|
4604
4649
|
// src/acl/model-output-planning.ts
|
|
4605
4650
|
function getCapturedAuthorizationOption(configuration, key) {
|
|
4606
|
-
const defaultValue = key.startsWith("operationAccess.") ? (0,
|
|
4607
|
-
return resolveNestedOption((path, fallback) => (0,
|
|
4651
|
+
const defaultValue = key.startsWith("operationAccess.") ? (0, import_utils22.get)(configuration.operationAccessDefaults, key.slice("operationAccess.".length)) : void 0;
|
|
4652
|
+
return resolveNestedOption((path, fallback) => (0, import_utils22.get)(configuration, path, fallback), key, defaultValue);
|
|
4608
4653
|
}
|
|
4609
|
-
function captureModelAuthorizationConfiguration(runtime, modelName, options = runtime.getModelOptions(modelName)) {
|
|
4654
|
+
function captureModelAuthorizationConfiguration(runtime, modelName, options = runtime.getModelOptions(modelName), globalOptions = runtime.getGlobalOptions()) {
|
|
4610
4655
|
const model = runtime.getModelInstance(modelName);
|
|
4611
4656
|
if (!model) return authorizationError(`unknown receiving model: ${modelName}`);
|
|
4612
4657
|
const virtuals = options.virtuals;
|
|
4613
4658
|
return copyAuthorizationValue(
|
|
4614
4659
|
{
|
|
4615
4660
|
catalog: captureAuthorizationFieldCatalog(model.schema, virtuals, options.documentPermissionField),
|
|
4616
|
-
virtualPopulateSnapshot: captureVirtualPopulateSnapshot(
|
|
4617
|
-
|
|
4661
|
+
virtualPopulateSnapshot: captureVirtualPopulateSnapshot(
|
|
4662
|
+
runtime,
|
|
4663
|
+
modelName,
|
|
4664
|
+
options,
|
|
4665
|
+
globalOptions
|
|
4666
|
+
),
|
|
4667
|
+
requireOperationAccessForPopulateDependencies: globalOptions.requireOperationAccessForPopulateDependencies !== false,
|
|
4668
|
+
requireOperationAccessForPopulateQueries: globalOptions.requireOperationAccessForPopulateQueries !== false,
|
|
4669
|
+
permissionSchema: options.permissionSchema === void 0 ? runtime.getDefaultModelOption("permissionSchema") : options.permissionSchema,
|
|
4618
4670
|
virtuals,
|
|
4619
4671
|
alwaysSelectFields: options.alwaysSelectFields,
|
|
4620
4672
|
modelPermissionPrefix: options.modelPermissionPrefix,
|
|
@@ -4660,10 +4712,10 @@ function planModelOutputForHelper(args) {
|
|
|
4660
4712
|
requestedSelect: args.select
|
|
4661
4713
|
});
|
|
4662
4714
|
}
|
|
4663
|
-
var
|
|
4715
|
+
var import_utils22;
|
|
4664
4716
|
var init_model_output_planning = __esm({
|
|
4665
4717
|
"src/acl/model-output-planning.ts"() {
|
|
4666
|
-
|
|
4718
|
+
import_utils22 = require("@web-ts-toolkit/utils");
|
|
4667
4719
|
init_manager();
|
|
4668
4720
|
init_field_catalog();
|
|
4669
4721
|
init_authorization_snapshot();
|
|
@@ -4675,10 +4727,10 @@ var init_model_output_planning = __esm({
|
|
|
4675
4727
|
|
|
4676
4728
|
// src/core-shared.ts
|
|
4677
4729
|
function isAndFilter(filter2) {
|
|
4678
|
-
return !!filter2 && (0,
|
|
4730
|
+
return !!filter2 && (0, import_utils23.isPlainObject)(filter2) && Object.keys(filter2).length === 1 && (0, import_utils23.isArray)(filter2.$and);
|
|
4679
4731
|
}
|
|
4680
4732
|
function isMergeableClause(filter2) {
|
|
4681
|
-
return !!filter2 && (0,
|
|
4733
|
+
return !!filter2 && (0, import_utils23.isPlainObject)(filter2) && Object.keys(filter2).every((key) => !key.startsWith("$"));
|
|
4682
4734
|
}
|
|
4683
4735
|
function optimizeAndFilter(clausesInput) {
|
|
4684
4736
|
const clauses = [];
|
|
@@ -4695,11 +4747,11 @@ function optimizeAndFilter(clausesInput) {
|
|
|
4695
4747
|
const dedupeKey = (value) => {
|
|
4696
4748
|
if (value instanceof RegExp) return `regexp:${JSON.stringify([value.source, value.flags])}`;
|
|
4697
4749
|
if (value instanceof Date) return `date:${value.getTime()}`;
|
|
4698
|
-
if ((0,
|
|
4750
|
+
if ((0, import_utils23.isArray)(value)) {
|
|
4699
4751
|
const entries = Array.from(value, dedupeKey);
|
|
4700
4752
|
return entries.every((entry) => entry !== void 0) ? `array:${JSON.stringify(entries)}` : void 0;
|
|
4701
4753
|
}
|
|
4702
|
-
if ((0,
|
|
4754
|
+
if ((0, import_utils23.isPlainObject)(value)) {
|
|
4703
4755
|
const entries = Object.keys(value).sort().map((key) => [key, dedupeKey(value[key])]);
|
|
4704
4756
|
return entries.every(([, entry]) => entry !== void 0) ? `object:${JSON.stringify(entries)}` : void 0;
|
|
4705
4757
|
}
|
|
@@ -4729,7 +4781,7 @@ function optimizeAndFilter(clausesInput) {
|
|
|
4729
4781
|
}
|
|
4730
4782
|
let canMerge = true;
|
|
4731
4783
|
for (const [key, value] of Object.entries(clause)) {
|
|
4732
|
-
if ((0,
|
|
4784
|
+
if ((0, import_utils23.hasOwn)(mergedClause, key) && !(0, import_node_util4.isDeepStrictEqual)(mergedClause[key], value)) {
|
|
4733
4785
|
canMerge = false;
|
|
4734
4786
|
break;
|
|
4735
4787
|
}
|
|
@@ -4740,24 +4792,24 @@ function optimizeAndFilter(clausesInput) {
|
|
|
4740
4792
|
}
|
|
4741
4793
|
Object.assign(mergedClause, clause);
|
|
4742
4794
|
}
|
|
4743
|
-
const finalClauses = (0,
|
|
4795
|
+
const finalClauses = (0, import_utils23.isEmpty)(mergedClause) ? remainingClauses : [mergedClause, ...remainingClauses];
|
|
4744
4796
|
if (finalClauses.length === 0) return null;
|
|
4745
4797
|
if (finalClauses.length === 1) return finalClauses[0];
|
|
4746
4798
|
return { $and: finalClauses };
|
|
4747
4799
|
}
|
|
4748
4800
|
function normalizeFilter(filter2) {
|
|
4749
4801
|
if (filter2 === false) return false;
|
|
4750
|
-
if (!filter2 || !(0,
|
|
4802
|
+
if (!filter2 || !(0, import_utils23.isPlainObject)(filter2) || (0, import_utils23.isEmpty)(filter2)) return null;
|
|
4751
4803
|
if (!isAndFilter(filter2)) {
|
|
4752
4804
|
return filter2;
|
|
4753
4805
|
}
|
|
4754
4806
|
return optimizeAndFilter(filter2.$and);
|
|
4755
4807
|
}
|
|
4756
4808
|
async function resolveIdentifierFilter(req, idField, resolveIdFilter, id) {
|
|
4757
|
-
if ((0,
|
|
4809
|
+
if ((0, import_utils23.isFunction)(resolveIdFilter)) {
|
|
4758
4810
|
return await resolveIdFilter.call(req, id);
|
|
4759
4811
|
}
|
|
4760
|
-
if ((0,
|
|
4812
|
+
if ((0, import_utils23.isString)(idField)) {
|
|
4761
4813
|
return { [idField]: id };
|
|
4762
4814
|
}
|
|
4763
4815
|
return { _id: id };
|
|
@@ -4781,7 +4833,7 @@ async function resolveAccessFilterParts({
|
|
|
4781
4833
|
}
|
|
4782
4834
|
const overrideFilterFn = getOption(`overrideFilter.${access}`, null);
|
|
4783
4835
|
const baseFilterFn = rows2.mode === "request" ? getOption(`baseFilter.${access}`, null) : null;
|
|
4784
|
-
if (nextFilter !== false && (0,
|
|
4836
|
+
if (nextFilter !== false && (0, import_utils23.isFunction)(overrideFilterFn)) {
|
|
4785
4837
|
nextFilter = normalizeFilter(await overrideFilterFn.call(req, nextFilter, permissions));
|
|
4786
4838
|
}
|
|
4787
4839
|
if (nextFilter === false) return { transformed: false, scope: {}, filter: false };
|
|
@@ -4789,7 +4841,7 @@ async function resolveAccessFilterParts({
|
|
|
4789
4841
|
const scope2 = rows2.mode === "scope" ? rows2.filter : {};
|
|
4790
4842
|
return { transformed: nextFilter ?? {}, scope: scope2, filter: intersectFilters(nextFilter, scope2) };
|
|
4791
4843
|
}
|
|
4792
|
-
if (!(0,
|
|
4844
|
+
if (!(0, import_utils23.isFunction)(baseFilterFn)) return { transformed: nextFilter ?? {}, scope: {}, filter: nextFilter ?? {} };
|
|
4793
4845
|
const cached = cache.get(cacheKey);
|
|
4794
4846
|
const reusable = cached?.resolver === baseFilterFn;
|
|
4795
4847
|
const baseFilter = normalizeFilter(
|
|
@@ -4824,34 +4876,34 @@ async function setRequestPermissions(req) {
|
|
|
4824
4876
|
if (owner === activeRuntime) return;
|
|
4825
4877
|
if (hasFieldValue && owner === void 0) return;
|
|
4826
4878
|
const globalPermissions = getGlobalOption("globalPermissions");
|
|
4827
|
-
const permissions = (0,
|
|
4828
|
-
if ((0,
|
|
4829
|
-
else if ((0,
|
|
4830
|
-
else if ((0,
|
|
4879
|
+
const permissions = (0, import_utils23.isFunction)(globalPermissions) ? await globalPermissions.call(req, req) : void 0;
|
|
4880
|
+
if ((0, import_utils23.isPlainObject)(permissions)) req[requestPermissionField] = permissions;
|
|
4881
|
+
else if ((0, import_utils23.isArray)(permissions)) req[requestPermissionField] = (0, import_utils23.arrayToRecord)(permissions);
|
|
4882
|
+
else if ((0, import_utils23.isString)(permissions)) req[requestPermissionField] = { [permissions]: true };
|
|
4831
4883
|
else req[requestPermissionField] = {};
|
|
4832
4884
|
owners.set(requestPermissionField, activeRuntime);
|
|
4833
4885
|
}
|
|
4834
4886
|
async function evaluateRouteGuard(req, permissions, routeGuard) {
|
|
4835
4887
|
const phas = (key) => permissions.has(key);
|
|
4836
4888
|
const { stringHandler, arrayHandler } = createValidator(phas);
|
|
4837
|
-
if ((0,
|
|
4889
|
+
if ((0, import_utils23.isBoolean)(routeGuard)) {
|
|
4838
4890
|
return routeGuard === true;
|
|
4839
4891
|
}
|
|
4840
|
-
if ((0,
|
|
4892
|
+
if ((0, import_utils23.isString)(routeGuard)) {
|
|
4841
4893
|
return stringHandler(routeGuard);
|
|
4842
4894
|
}
|
|
4843
|
-
if ((0,
|
|
4895
|
+
if ((0, import_utils23.isArray)(routeGuard)) {
|
|
4844
4896
|
return arrayHandler(routeGuard);
|
|
4845
4897
|
}
|
|
4846
|
-
if ((0,
|
|
4898
|
+
if ((0, import_utils23.isFunction)(routeGuard)) {
|
|
4847
4899
|
return routeGuard.call(req, permissions);
|
|
4848
4900
|
}
|
|
4849
4901
|
return false;
|
|
4850
4902
|
}
|
|
4851
4903
|
async function callHookChain(req, hook, doc, permissions, context) {
|
|
4852
|
-
const hooks = (0,
|
|
4904
|
+
const hooks = (0, import_utils23.castArray)(hook);
|
|
4853
4905
|
for (let x = 0; x < hooks.length; x++) {
|
|
4854
|
-
if ((0,
|
|
4906
|
+
if ((0, import_utils23.isFunction)(hooks[x])) {
|
|
4855
4907
|
doc = await hooks[x].call(req, doc, permissions, context);
|
|
4856
4908
|
}
|
|
4857
4909
|
}
|
|
@@ -4871,22 +4923,22 @@ async function collectSchemaFields({
|
|
|
4871
4923
|
for (let x = 0; x < keys2.length; x++) {
|
|
4872
4924
|
const key = keys2[x];
|
|
4873
4925
|
const value = extractScopedOutputRule(permissionSchema, key, access);
|
|
4874
|
-
if ((0,
|
|
4926
|
+
if ((0, import_utils23.isBoolean)(value)) {
|
|
4875
4927
|
if (value) fields.push(key);
|
|
4876
|
-
} else if ((0,
|
|
4928
|
+
} else if ((0, import_utils23.isString)(value)) {
|
|
4877
4929
|
if (stringHandler(value)) fields.push(key);
|
|
4878
|
-
} else if ((0,
|
|
4930
|
+
} else if ((0, import_utils23.isArray)(value)) {
|
|
4879
4931
|
if (arrayHandler(value)) fields.push(key);
|
|
4880
|
-
} else if ((0,
|
|
4932
|
+
} else if ((0, import_utils23.isFunction)(value)) {
|
|
4881
4933
|
if (await value.call(req, ...functionArgs)) fields.push(key);
|
|
4882
4934
|
}
|
|
4883
4935
|
}
|
|
4884
4936
|
return fields;
|
|
4885
4937
|
}
|
|
4886
|
-
var
|
|
4938
|
+
var import_utils23, import_node_util4, permissionFieldOwners;
|
|
4887
4939
|
var init_core_shared = __esm({
|
|
4888
4940
|
"src/core-shared.ts"() {
|
|
4889
|
-
|
|
4941
|
+
import_utils23 = require("@web-ts-toolkit/utils");
|
|
4890
4942
|
import_node_util4 = require("util");
|
|
4891
4943
|
init_helpers();
|
|
4892
4944
|
init_options();
|
|
@@ -5255,8 +5307,8 @@ function equivalentVirtualPopulatePredicate(left, right) {
|
|
|
5255
5307
|
}
|
|
5256
5308
|
if (Array.isArray(left) || Array.isArray(right))
|
|
5257
5309
|
return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((entry, index) => equivalentVirtualPopulatePredicate(entry, right[index]));
|
|
5258
|
-
if ((0,
|
|
5259
|
-
if (!(0,
|
|
5310
|
+
if ((0, import_utils27.isPlainObject)(left) || (0, import_utils27.isPlainObject)(right)) {
|
|
5311
|
+
if (!(0, import_utils27.isPlainObject)(left) || !(0, import_utils27.isPlainObject)(right)) return false;
|
|
5260
5312
|
const a = Object.keys(left), b = Object.keys(right);
|
|
5261
5313
|
return a.length === b.length && a.every(
|
|
5262
5314
|
(key, index) => key === b[index] && equivalentVirtualPopulatePredicate(
|
|
@@ -5273,7 +5325,8 @@ function createVirtualPopulateBatch(owner) {
|
|
|
5273
5325
|
owner: { ...owner },
|
|
5274
5326
|
rows: [],
|
|
5275
5327
|
requests: [],
|
|
5276
|
-
rowCache: owner.core && getRequestRowCache(owner.core) || new Cache()
|
|
5328
|
+
rowCache: owner.core && getRequestRowCache(owner.core) || new Cache(),
|
|
5329
|
+
readGuards: /* @__PURE__ */ new Map()
|
|
5277
5330
|
});
|
|
5278
5331
|
return batch;
|
|
5279
5332
|
}
|
|
@@ -5322,7 +5375,12 @@ function captureVirtualPopulateRows(batch, inputs, plan, publicPopulate = [], so
|
|
|
5322
5375
|
}
|
|
5323
5376
|
const record3 = storage(value);
|
|
5324
5377
|
if (!record3) return;
|
|
5325
|
-
const occurrence = {
|
|
5378
|
+
const occurrence = {
|
|
5379
|
+
address,
|
|
5380
|
+
plan: currentPlan,
|
|
5381
|
+
refs: /* @__PURE__ */ new Map(),
|
|
5382
|
+
dependencies: /* @__PURE__ */ new Map()
|
|
5383
|
+
};
|
|
5326
5384
|
row.occurrences.set(addressKey(address), occurrence);
|
|
5327
5385
|
for (const candidate of currentPlan.candidates) {
|
|
5328
5386
|
const dependencies = (candidate.populateDependencies ?? []).map((dependency) => {
|
|
@@ -5388,6 +5446,27 @@ function referenceIds(original) {
|
|
|
5388
5446
|
if (!original.present || original.value == null) return [];
|
|
5389
5447
|
return (Array.isArray(original.value) ? original.value : [original.value]).filter((id) => id != null);
|
|
5390
5448
|
}
|
|
5449
|
+
function targetReadAllowed(state, target) {
|
|
5450
|
+
let pending = state.readGuards.get(target.identity);
|
|
5451
|
+
if (!pending) {
|
|
5452
|
+
const { owner } = state;
|
|
5453
|
+
pending = getRequestWorkState(owner.request, owner.runtime).hookGate.run(
|
|
5454
|
+
() => evaluateRouteGuard(
|
|
5455
|
+
owner.request,
|
|
5456
|
+
owner.permissions,
|
|
5457
|
+
getCapturedAuthorizationOption(target.configuration, "operationAccess.read")
|
|
5458
|
+
)
|
|
5459
|
+
).then(
|
|
5460
|
+
(allowed) => !!allowed,
|
|
5461
|
+
() => {
|
|
5462
|
+
warn("Virtual populated dependency unavailable", { modelName: target.modelName, category: "policy" });
|
|
5463
|
+
return false;
|
|
5464
|
+
}
|
|
5465
|
+
);
|
|
5466
|
+
state.readGuards.set(target.identity, pending);
|
|
5467
|
+
}
|
|
5468
|
+
return pending;
|
|
5469
|
+
}
|
|
5391
5470
|
function executeVirtualPopulateBatch(batch) {
|
|
5392
5471
|
const state = batches.get(batch);
|
|
5393
5472
|
if (!state) throw new Error("Unknown private populate batch");
|
|
@@ -5404,14 +5483,8 @@ async function execute(state) {
|
|
|
5404
5483
|
if (!pending) {
|
|
5405
5484
|
pending = (async () => {
|
|
5406
5485
|
try {
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
owner.request,
|
|
5410
|
-
owner.permissions,
|
|
5411
|
-
getCapturedAuthorizationOption(target.configuration, "operationAccess.read")
|
|
5412
|
-
)
|
|
5413
|
-
);
|
|
5414
|
-
if (!allowed) return void 0;
|
|
5486
|
+
if (target.configuration.requireOperationAccessForPopulateDependencies !== false && !await targetReadAllowed(state, target))
|
|
5487
|
+
return void 0;
|
|
5415
5488
|
const parts = await work.hookGate.run(
|
|
5416
5489
|
() => resolveAccessFilterParts({
|
|
5417
5490
|
req: owner.request,
|
|
@@ -5619,12 +5692,12 @@ async function loadVirtualPopulateOutputRows(owner, inputs, plan, publicPopulate
|
|
|
5619
5692
|
}
|
|
5620
5693
|
return output;
|
|
5621
5694
|
}
|
|
5622
|
-
var import_mongoose7, import_node_util5,
|
|
5695
|
+
var import_mongoose7, import_node_util5, import_utils27, batches, rows, outputRows, fetchedPublicIdentities, publicViewIdentities, familyRawFetches, addressKey, storage, originalRef, copyOriginalValue, readPolicy, compatible, idKey, logUnavailable;
|
|
5623
5696
|
var init_virtual_populate_execution = __esm({
|
|
5624
5697
|
"src/acl/virtual-populate-execution.ts"() {
|
|
5625
5698
|
import_mongoose7 = require("mongoose");
|
|
5626
5699
|
import_node_util5 = require("util");
|
|
5627
|
-
|
|
5700
|
+
import_utils27 = require("@web-ts-toolkit/utils");
|
|
5628
5701
|
init_cache();
|
|
5629
5702
|
init_core_shared();
|
|
5630
5703
|
init_document();
|
|
@@ -5641,7 +5714,7 @@ var init_virtual_populate_execution = __esm({
|
|
|
5641
5714
|
publicViewIdentities = /* @__PURE__ */ new WeakMap();
|
|
5642
5715
|
familyRawFetches = /* @__PURE__ */ new WeakMap();
|
|
5643
5716
|
addressKey = (address) => JSON.stringify(address);
|
|
5644
|
-
storage = (value) => value instanceof import_mongoose7.Document ? value._doc : (0,
|
|
5717
|
+
storage = (value) => value instanceof import_mongoose7.Document ? value._doc : (0, import_utils27.isPlainObject)(value) ? value : void 0;
|
|
5645
5718
|
originalRef = (source, key) => {
|
|
5646
5719
|
const record3 = storage(source);
|
|
5647
5720
|
return {
|
|
@@ -5654,7 +5727,7 @@ var init_virtual_populate_execution = __esm({
|
|
|
5654
5727
|
const option = getCapturedAuthorizationOption(configuration, `${key}.${access}`);
|
|
5655
5728
|
return key === "operationAccess" || typeof option === "function" ? option : void 0;
|
|
5656
5729
|
});
|
|
5657
|
-
compatible = (a, b) => a.binding.runtime === b.binding.runtime && a.binding.model === b.binding.model && a.binding.schema === b.binding.schema && a.access === b.access && a.requestRead === b.requestRead && // Different captures may share only an equivalent terminal persisted binding/policy.
|
|
5730
|
+
compatible = (a, b) => a.binding.runtime === b.binding.runtime && a.binding.model === b.binding.model && a.binding.schema === b.binding.schema && a.access === b.access && a.requestRead === b.requestRead && a.binding.configuration.requireOperationAccessForPopulateDependencies === b.binding.configuration.requireOperationAccessForPopulateDependencies && // Different captures may share only an equivalent terminal persisted binding/policy.
|
|
5658
5731
|
equivalentVirtualPopulatePredicate(
|
|
5659
5732
|
a.binding.configuration.catalog.persistedPaths,
|
|
5660
5733
|
b.binding.configuration.catalog.persistedPaths
|
|
@@ -5681,7 +5754,7 @@ async function resolveOutputDocumentAuthorization(args) {
|
|
|
5681
5754
|
try {
|
|
5682
5755
|
const run = () => hook.call(this, doc, permissions, args.context);
|
|
5683
5756
|
const grants = await getRequestWorkState(binding.request, binding.runtime).hookGate.run(run);
|
|
5684
|
-
return (0,
|
|
5757
|
+
return (0, import_utils28.isPlainObject)(grants) ? grants : {};
|
|
5685
5758
|
} catch (error2) {
|
|
5686
5759
|
warn("docPermissions hook failed; applying empty document permissions", {
|
|
5687
5760
|
modelName: binding.modelName,
|
|
@@ -5796,7 +5869,7 @@ function copyOutputValue(value, plan, path) {
|
|
|
5796
5869
|
const visit = (input, current) => {
|
|
5797
5870
|
if (Array.isArray(input)) return input.map((entry) => visit(entry, current));
|
|
5798
5871
|
if (input instanceof Map) return visit(Object.fromEntries(input), current);
|
|
5799
|
-
if (!(0,
|
|
5872
|
+
if (!(0, import_utils28.isPlainObject)(input)) return deepIsolateValue(input);
|
|
5800
5873
|
const output = {};
|
|
5801
5874
|
for (const [key, entry] of Object.entries(input)) {
|
|
5802
5875
|
const child = `${current}.${key}`;
|
|
@@ -5812,25 +5885,21 @@ function copyOutputValue(value, plan, path) {
|
|
|
5812
5885
|
}
|
|
5813
5886
|
function copyAuthorizedReference(value, plan, path) {
|
|
5814
5887
|
if (Array.isArray(value)) return value.map((entry) => copyAuthorizedReference(entry, plan, path));
|
|
5815
|
-
if (!(0,
|
|
5888
|
+
if (!(0, import_utils28.isPlainObject)(value)) return deepIsolateValue(value);
|
|
5816
5889
|
const handle = getAssociatedDocumentAuthorization(value, plan.authorization);
|
|
5817
5890
|
if (handle) {
|
|
5818
5891
|
const copy = deepIsolateValue(value);
|
|
5819
5892
|
transferDocumentAuthorizationGraph(value, copy);
|
|
5820
5893
|
return copy;
|
|
5821
5894
|
}
|
|
5822
|
-
const { relatedTargets } = readServiceAuthorization(plan.authorization, plan.authorizationBinding);
|
|
5823
|
-
if (relatedTargets.some((target) => target.path === path && target.kind === "passthrough")) {
|
|
5824
|
-
return deepIsolateValue(value);
|
|
5825
|
-
}
|
|
5826
5895
|
return Object.prototype.hasOwnProperty.call(value, "_id") ? deepIsolateValue(value._id) : void 0;
|
|
5827
5896
|
}
|
|
5828
5897
|
function retainOutputMetadata(output, source, configuration, scope2) {
|
|
5829
5898
|
if (scope2.length || configuration.stripPermissionsField) return;
|
|
5830
5899
|
const parts = (configuration.documentPermissionField ?? "_permissions").split(".");
|
|
5831
5900
|
let value = source;
|
|
5832
|
-
for (const part of parts) value = (0,
|
|
5833
|
-
if (!(0,
|
|
5901
|
+
for (const part of parts) value = (0, import_utils28.isPlainObject)(value) ? value[part] : void 0;
|
|
5902
|
+
if (!(0, import_utils28.isPlainObject)(value)) return;
|
|
5834
5903
|
const keys2 = configuration.exposedDocPermissionKeys;
|
|
5835
5904
|
const metadata = Object.fromEntries(
|
|
5836
5905
|
Object.entries(value).filter(
|
|
@@ -5840,7 +5909,7 @@ function retainOutputMetadata(output, source, configuration, scope2) {
|
|
|
5840
5909
|
const copy = { ...output };
|
|
5841
5910
|
let target = copy;
|
|
5842
5911
|
for (const part of parts.slice(0, -1)) {
|
|
5843
|
-
target[part] = (0,
|
|
5912
|
+
target[part] = (0, import_utils28.isPlainObject)(target[part]) ? { ...target[part] } : {};
|
|
5844
5913
|
target = target[part];
|
|
5845
5914
|
}
|
|
5846
5915
|
target[parts[parts.length - 1]] = deepIsolateValue(metadata);
|
|
@@ -5882,7 +5951,7 @@ async function filterExistingOutput(source, plan, handle, associated) {
|
|
|
5882
5951
|
for (const entry of value2) values.push(await one(entry) ?? null);
|
|
5883
5952
|
return values;
|
|
5884
5953
|
}
|
|
5885
|
-
if (!(0,
|
|
5954
|
+
if (!(0, import_utils28.isPlainObject)(value2)) return value2 === null ? null : void 0;
|
|
5886
5955
|
const childHandle = associated ? getAssociatedDocumentAuthorization(value2) : void 0;
|
|
5887
5956
|
let child = scoped;
|
|
5888
5957
|
if (childHandle) {
|
|
@@ -5962,7 +6031,7 @@ async function filterModelOutputForHelper(args) {
|
|
|
5962
6031
|
const plan = helperPlan(normalized.authorization, binding);
|
|
5963
6032
|
if (args.doc == null) return { output: args.doc, fields: [] };
|
|
5964
6033
|
const source = isolateDocForOutput(args.doc);
|
|
5965
|
-
if (!(0,
|
|
6034
|
+
if (!(0, import_utils28.isPlainObject)(source)) return authorizationError("output helper requires one plain or hydrated document");
|
|
5966
6035
|
const knownOutput = !!args.doc && typeof args.doc === "object" && isKnownAuthorizationOutput(args.doc);
|
|
5967
6036
|
const handle = await resolveOutputDocumentAuthorization({
|
|
5968
6037
|
authorization: normalized.authorization,
|
|
@@ -5973,10 +6042,10 @@ async function filterModelOutputForHelper(args) {
|
|
|
5973
6042
|
});
|
|
5974
6043
|
return filterExistingOutput(source, plan, handle, false);
|
|
5975
6044
|
}
|
|
5976
|
-
var
|
|
6045
|
+
var import_utils28, unresolvedDocuments, owningDocuments;
|
|
5977
6046
|
var init_output_field_filter = __esm({
|
|
5978
6047
|
"src/acl/output-field-filter.ts"() {
|
|
5979
|
-
|
|
6048
|
+
import_utils28 = require("@web-ts-toolkit/utils");
|
|
5980
6049
|
init_permissions_alias();
|
|
5981
6050
|
init_document();
|
|
5982
6051
|
init_request_work();
|
|
@@ -6073,8 +6142,8 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6073
6142
|
const privateRow = args.virtualPopulateRow ?? (original && typeof original === "object" ? getVirtualPopulateRow(original) : void 0);
|
|
6074
6143
|
const privateAddress = args.virtualPopulateAddress ?? [];
|
|
6075
6144
|
const isolated = isolateDocForOutput(input);
|
|
6076
|
-
const output = (0,
|
|
6077
|
-
if (captured && (0,
|
|
6145
|
+
const output = (0, import_utils29.isPlainObject)(isolated) ? isolated : {};
|
|
6146
|
+
if (captured && (0, import_utils29.isPlainObject)(input))
|
|
6078
6147
|
for (const key of Object.keys(output)) {
|
|
6079
6148
|
transferDocumentAuthorizationGraph(input[key], output[key]);
|
|
6080
6149
|
}
|
|
@@ -6129,7 +6198,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6129
6198
|
);
|
|
6130
6199
|
continue;
|
|
6131
6200
|
}
|
|
6132
|
-
if (captured && !(0,
|
|
6201
|
+
if (captured && !(0, import_utils29.isPlainObject)(rawContainer) && !Array.isArray(rawContainer)) {
|
|
6133
6202
|
delete output[containerName];
|
|
6134
6203
|
continue;
|
|
6135
6204
|
}
|
|
@@ -6153,7 +6222,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6153
6222
|
const finalizeOneChild = async (rawChild, address) => {
|
|
6154
6223
|
if (captured && Array.isArray(rawChild))
|
|
6155
6224
|
return mapWithConcurrencyLimit(rawChild, limit, (entry, index) => finalizeOneChild(entry, [...address, index]));
|
|
6156
|
-
if (!(0,
|
|
6225
|
+
if (!(0, import_utils29.isPlainObject)(rawChild) && !Array.isArray(rawChild)) return captured ? null : deepIsolateValue(rawChild);
|
|
6157
6226
|
if (args.traversal?.finalizeEmbeddedChildren) {
|
|
6158
6227
|
return args.traversal.finalizeEmbeddedChildren({
|
|
6159
6228
|
containerName,
|
|
@@ -6179,7 +6248,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6179
6248
|
(entry, index) => finalizeOneChild(entry, [...privateAddress, containerName, index])
|
|
6180
6249
|
);
|
|
6181
6250
|
output[containerName] = finalized;
|
|
6182
|
-
} else if ((0,
|
|
6251
|
+
} else if ((0, import_utils29.isPlainObject)(rawContainer)) {
|
|
6183
6252
|
output[containerName] = await finalizeOneChild(rawContainer, [
|
|
6184
6253
|
...privateAddress,
|
|
6185
6254
|
containerName
|
|
@@ -6191,8 +6260,8 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6191
6260
|
let rawRelated;
|
|
6192
6261
|
let originalRelated;
|
|
6193
6262
|
try {
|
|
6194
|
-
rawRelated = target.path.includes(".") ? (0,
|
|
6195
|
-
originalRelated = (0,
|
|
6263
|
+
rawRelated = target.path.includes(".") ? (0, import_utils29.get)(output, target.path) : output[target.path];
|
|
6264
|
+
originalRelated = (0, import_utils29.get)(original, target.path);
|
|
6196
6265
|
} catch {
|
|
6197
6266
|
continue;
|
|
6198
6267
|
}
|
|
@@ -6223,7 +6292,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6223
6292
|
related: target.plan.relatedPlans?.length ? (args.related ?? []).filter((entry) => entry.path.startsWith(`${target.path}.`)) : []
|
|
6224
6293
|
};
|
|
6225
6294
|
const finalizeOneRelated = async (rawChild, originalChild = rawChild) => {
|
|
6226
|
-
if (!(0,
|
|
6295
|
+
if (!(0, import_utils29.isPlainObject)(rawChild) && !Array.isArray(rawChild)) return rawChild;
|
|
6227
6296
|
if (typeof rawChild?._bsontype === "string") return rawChild;
|
|
6228
6297
|
const childOriginal = getIncludeOriginal(originalChild);
|
|
6229
6298
|
const childRow = childOriginal && typeof childOriginal === "object" ? getVirtualPopulateRow(childOriginal) : void 0;
|
|
@@ -6244,13 +6313,13 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6244
6313
|
limit,
|
|
6245
6314
|
(entry, index) => finalizeOneRelated(entry, Array.isArray(originalRelated) ? originalRelated[index] : void 0)
|
|
6246
6315
|
);
|
|
6247
|
-
} else if ((0,
|
|
6316
|
+
} else if ((0, import_utils29.isPlainObject)(rawRelated)) {
|
|
6248
6317
|
finalized = await finalizeOneRelated(rawRelated, originalRelated);
|
|
6249
6318
|
} else {
|
|
6250
6319
|
continue;
|
|
6251
6320
|
}
|
|
6252
6321
|
try {
|
|
6253
|
-
if (target.path.includes(".")) (0,
|
|
6322
|
+
if (target.path.includes(".")) (0, import_utils29.set)(output, target.path, finalized);
|
|
6254
6323
|
else output[target.path] = finalized;
|
|
6255
6324
|
} catch {
|
|
6256
6325
|
}
|
|
@@ -6430,10 +6499,10 @@ async function finalizeModelOutputs(args) {
|
|
|
6430
6499
|
return finalizeSingleDoc(internal, input);
|
|
6431
6500
|
});
|
|
6432
6501
|
}
|
|
6433
|
-
var
|
|
6502
|
+
var import_utils29, isVirtualContainerValue3, getScopeVirtualsObject2, getScopeVirtualNames, getScopedPermissionSchema2, resolveGlobalPermissions, resolveDocPermissions, isAbsentDependency, __finalizeInternals;
|
|
6434
6503
|
var init_finalize_model_output = __esm({
|
|
6435
6504
|
"src/output/finalize-model-output.ts"() {
|
|
6436
|
-
|
|
6505
|
+
import_utils29 = require("@web-ts-toolkit/utils");
|
|
6437
6506
|
init_document();
|
|
6438
6507
|
init_concurrency();
|
|
6439
6508
|
init_request_work();
|
|
@@ -6446,20 +6515,20 @@ var init_finalize_model_output = __esm({
|
|
|
6446
6515
|
init_field_catalog();
|
|
6447
6516
|
init_virtual_populate_execution();
|
|
6448
6517
|
init_include_output();
|
|
6449
|
-
isVirtualContainerValue3 = (value) => (0,
|
|
6518
|
+
isVirtualContainerValue3 = (value) => (0, import_utils29.isPlainObject)(value) && "sub" in value;
|
|
6450
6519
|
getScopeVirtualsObject2 = (rootVirtuals, scopePath) => {
|
|
6451
|
-
if (!rootVirtuals || !(0,
|
|
6520
|
+
if (!rootVirtuals || !(0, import_utils29.isPlainObject)(rootVirtuals)) return null;
|
|
6452
6521
|
if (scopePath.length === 0) return rootVirtuals;
|
|
6453
6522
|
let current = rootVirtuals;
|
|
6454
6523
|
for (let i = 0; i < scopePath.length; i += 2) {
|
|
6455
6524
|
const field = scopePath[i];
|
|
6456
6525
|
const subMarker = scopePath[i + 1];
|
|
6457
6526
|
if (!field || subMarker !== "sub") return null;
|
|
6458
|
-
if (!(0,
|
|
6527
|
+
if (!(0, import_utils29.isPlainObject)(current)) return null;
|
|
6459
6528
|
const container = current[field];
|
|
6460
6529
|
if (!isVirtualContainerValue3(container)) return null;
|
|
6461
6530
|
current = container.sub;
|
|
6462
|
-
if (!(0,
|
|
6531
|
+
if (!(0, import_utils29.isPlainObject)(current)) return null;
|
|
6463
6532
|
}
|
|
6464
6533
|
return current;
|
|
6465
6534
|
};
|
|
@@ -6472,11 +6541,11 @@ var init_finalize_model_output = __esm({
|
|
|
6472
6541
|
return Object.entries(scopeVirtuals).filter(([, v]) => v !== void 0 && !isVirtualContainerValue3(v)).map(([k]) => k);
|
|
6473
6542
|
};
|
|
6474
6543
|
getScopedPermissionSchema2 = (root, scopePath) => {
|
|
6475
|
-
if (!root || !(0,
|
|
6544
|
+
if (!root || !(0, import_utils29.isPlainObject)(root)) return null;
|
|
6476
6545
|
if (scopePath.length === 0) return root;
|
|
6477
6546
|
try {
|
|
6478
|
-
const scoped = (0,
|
|
6479
|
-
return (0,
|
|
6547
|
+
const scoped = (0, import_utils29.get)(root, scopePath.join("."));
|
|
6548
|
+
return (0, import_utils29.isPlainObject)(scoped) ? scoped : null;
|
|
6480
6549
|
} catch {
|
|
6481
6550
|
return null;
|
|
6482
6551
|
}
|
|
@@ -6535,7 +6604,7 @@ var init_finalize_model_output = __esm({
|
|
|
6535
6604
|
const grants = await args.sharedGate.run(
|
|
6536
6605
|
() => hook.call(args.request, isolatedForHook, globalPerms, scopeContext)
|
|
6537
6606
|
);
|
|
6538
|
-
const normalized = (0,
|
|
6607
|
+
const normalized = (0, import_utils29.isPlainObject)(grants) ? grants : {};
|
|
6539
6608
|
scopeContext.docPermissions = normalized;
|
|
6540
6609
|
return normalized;
|
|
6541
6610
|
}
|
|
@@ -6607,40 +6676,20 @@ __export(index_exports, {
|
|
|
6607
6676
|
setModelOptions: () => setModelOptions
|
|
6608
6677
|
});
|
|
6609
6678
|
module.exports = __toCommonJS(index_exports);
|
|
6610
|
-
var
|
|
6679
|
+
var import_utils47 = require("@web-ts-toolkit/utils");
|
|
6611
6680
|
|
|
6612
6681
|
// src/middleware.ts
|
|
6613
6682
|
var import_express_json_router5 = __toESM(require("@web-ts-toolkit/express-json-router"));
|
|
6614
|
-
var
|
|
6683
|
+
var import_utils40 = require("@web-ts-toolkit/utils");
|
|
6615
6684
|
|
|
6616
6685
|
// src/core.ts
|
|
6617
6686
|
init_public_admission();
|
|
6618
|
-
var
|
|
6687
|
+
var import_utils39 = require("@web-ts-toolkit/utils");
|
|
6619
6688
|
init_options();
|
|
6620
|
-
|
|
6621
|
-
// src/meta.ts
|
|
6622
|
-
init_runtime();
|
|
6623
|
-
init_runtime_context();
|
|
6624
|
-
var getRuntime5 = () => getActiveRuntime() ?? defaultRuntime;
|
|
6625
|
-
var getModelRef = (modelName, refPath) => {
|
|
6626
|
-
const direct = getRuntime5().getModelRef(modelName, refPath);
|
|
6627
|
-
if (direct) return direct;
|
|
6628
|
-
if (!refPath.includes(".")) return null;
|
|
6629
|
-
try {
|
|
6630
|
-
const runtime = getRuntime5();
|
|
6631
|
-
const instance = runtime.getModelInstance?.(
|
|
6632
|
-
modelName
|
|
6633
|
-
);
|
|
6634
|
-
const schemaPath = instance?.schema?.path?.(refPath);
|
|
6635
|
-
const ref = schemaPath?.options?.ref ?? schemaPath?.caster?.options?.ref ?? null;
|
|
6636
|
-
return typeof ref === "string" && ref.length > 0 ? ref : null;
|
|
6637
|
-
} catch {
|
|
6638
|
-
return null;
|
|
6639
|
-
}
|
|
6640
|
-
};
|
|
6689
|
+
init_permission();
|
|
6641
6690
|
|
|
6642
6691
|
// src/services/base.ts
|
|
6643
|
-
var
|
|
6692
|
+
var import_utils24 = require("@web-ts-toolkit/utils");
|
|
6644
6693
|
init_options();
|
|
6645
6694
|
init_helpers();
|
|
6646
6695
|
init_document();
|
|
@@ -6766,7 +6815,7 @@ function requestFieldScope(options) {
|
|
|
6766
6815
|
init_public_admission();
|
|
6767
6816
|
|
|
6768
6817
|
// src/correlated-includes.ts
|
|
6769
|
-
var
|
|
6818
|
+
var import_utils20 = require("@web-ts-toolkit/utils");
|
|
6770
6819
|
init_request_complexity();
|
|
6771
6820
|
init_sort_policy();
|
|
6772
6821
|
var PARENT_MARKER_KEY = "$parent";
|
|
@@ -6779,10 +6828,10 @@ var FIELD_SEGMENT_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
|
6779
6828
|
var ARRAY_INDEX_SEGMENT_PATTERN = /^(0|[1-9]\d*)$/;
|
|
6780
6829
|
var ownKeys = (value) => Object.keys(value);
|
|
6781
6830
|
function isParentRefMarker(value) {
|
|
6782
|
-
return (0,
|
|
6831
|
+
return (0, import_utils20.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === PARENT_MARKER_KEY;
|
|
6783
6832
|
}
|
|
6784
6833
|
function isEscapedParentRef(value) {
|
|
6785
|
-
return (0,
|
|
6834
|
+
return (0, import_utils20.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === ESCAPE_WRAPPER_KEY;
|
|
6786
6835
|
}
|
|
6787
6836
|
function hasMarkerKey(value) {
|
|
6788
6837
|
return ownKeys(value).includes(PARENT_MARKER_KEY) || ownKeys(value).includes(ESCAPE_WRAPPER_KEY);
|
|
@@ -6801,12 +6850,12 @@ function containsParentMarkerShape(value) {
|
|
|
6801
6850
|
const seen = /* @__PURE__ */ new Set();
|
|
6802
6851
|
const visit = (current) => {
|
|
6803
6852
|
if (isParentRefMarker(current) || isEscapedParentRef(current)) return true;
|
|
6804
|
-
if ((0,
|
|
6853
|
+
if ((0, import_utils20.isArray)(current)) {
|
|
6805
6854
|
if (seen.has(current)) return false;
|
|
6806
6855
|
seen.add(current);
|
|
6807
6856
|
return current.some(visit);
|
|
6808
6857
|
}
|
|
6809
|
-
if ((0,
|
|
6858
|
+
if ((0, import_utils20.isPlainObject)(current)) {
|
|
6810
6859
|
if (seen.has(current)) return false;
|
|
6811
6860
|
seen.add(current);
|
|
6812
6861
|
if (hasMarkerKey(current)) return true;
|
|
@@ -6836,7 +6885,7 @@ function scanTemplateValueNode(value, path, issues) {
|
|
|
6836
6885
|
}
|
|
6837
6886
|
return;
|
|
6838
6887
|
}
|
|
6839
|
-
if ((0,
|
|
6888
|
+
if ((0, import_utils20.isPlainObject)(value)) {
|
|
6840
6889
|
if (hasMarkerKey(value)) {
|
|
6841
6890
|
issues.push({
|
|
6842
6891
|
message: 'Malformed $parent reference: objects carrying $parent must be exactly { "$parent": "<field>" }',
|
|
@@ -6847,7 +6896,7 @@ function scanTemplateValueNode(value, path, issues) {
|
|
|
6847
6896
|
scanTemplateObjectEntries(value, path, issues);
|
|
6848
6897
|
return;
|
|
6849
6898
|
}
|
|
6850
|
-
if ((0,
|
|
6899
|
+
if ((0, import_utils20.isArray)(value)) {
|
|
6851
6900
|
value.forEach((item, index) => scanTemplateValueNode(item, [...path, index], issues));
|
|
6852
6901
|
}
|
|
6853
6902
|
}
|
|
@@ -6888,7 +6937,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
|
|
|
6888
6937
|
continue;
|
|
6889
6938
|
}
|
|
6890
6939
|
if (LOGICAL_CLAUSE_KEYS.has(key)) {
|
|
6891
|
-
if (!(0,
|
|
6940
|
+
if (!(0, import_utils20.isArray)(child)) {
|
|
6892
6941
|
scanTemplateValueNode(child, childPath, issues);
|
|
6893
6942
|
continue;
|
|
6894
6943
|
}
|
|
@@ -6901,7 +6950,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
|
|
|
6901
6950
|
});
|
|
6902
6951
|
return;
|
|
6903
6952
|
}
|
|
6904
|
-
if ((0,
|
|
6953
|
+
if ((0, import_utils20.isPlainObject)(clause)) {
|
|
6905
6954
|
scanTemplateObjectEntries(clause, clausePath, issues);
|
|
6906
6955
|
}
|
|
6907
6956
|
});
|
|
@@ -6912,7 +6961,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
|
|
|
6912
6961
|
}
|
|
6913
6962
|
function validateCorrelatedFilterTemplate(filter2) {
|
|
6914
6963
|
const issues = [];
|
|
6915
|
-
if (!(0,
|
|
6964
|
+
if (!(0, import_utils20.isPlainObject)(filter2)) {
|
|
6916
6965
|
issues.push({ message: "Correlated include filter must be an object", path: [] });
|
|
6917
6966
|
return issues;
|
|
6918
6967
|
}
|
|
@@ -6955,13 +7004,13 @@ function collectFilterReferencePaths(filter2) {
|
|
|
6955
7004
|
return;
|
|
6956
7005
|
}
|
|
6957
7006
|
if (isEscapedParentRef(value)) return;
|
|
6958
|
-
if ((0,
|
|
7007
|
+
if ((0, import_utils20.isArray)(value)) {
|
|
6959
7008
|
if (seen.has(value)) return;
|
|
6960
7009
|
seen.add(value);
|
|
6961
7010
|
value.forEach(visitValue);
|
|
6962
7011
|
return;
|
|
6963
7012
|
}
|
|
6964
|
-
if ((0,
|
|
7013
|
+
if ((0, import_utils20.isPlainObject)(value)) {
|
|
6965
7014
|
if (seen.has(value)) return;
|
|
6966
7015
|
seen.add(value);
|
|
6967
7016
|
for (const [key, child] of Object.entries(value)) {
|
|
@@ -7007,7 +7056,7 @@ function getOwnPathValue(parent, path) {
|
|
|
7007
7056
|
return current;
|
|
7008
7057
|
}
|
|
7009
7058
|
function cloneSubstitutedValue(value) {
|
|
7010
|
-
if ((0,
|
|
7059
|
+
if ((0, import_utils20.isPlainObject)(value) || (0, import_utils20.isArray)(value)) return (0, import_utils20.cloneDeep)(value);
|
|
7011
7060
|
return value;
|
|
7012
7061
|
}
|
|
7013
7062
|
function literalParentRefObject(path) {
|
|
@@ -7048,7 +7097,7 @@ function resolveObjectEntries(obj, parent) {
|
|
|
7048
7097
|
continue;
|
|
7049
7098
|
}
|
|
7050
7099
|
if (LOGICAL_CLAUSE_KEYS.has(key)) {
|
|
7051
|
-
if (!(0,
|
|
7100
|
+
if (!(0, import_utils20.isArray)(child)) {
|
|
7052
7101
|
out[key] = resolveValueNode(child, parent, false);
|
|
7053
7102
|
continue;
|
|
7054
7103
|
}
|
|
@@ -7056,7 +7105,7 @@ function resolveObjectEntries(obj, parent) {
|
|
|
7056
7105
|
if (isParentRefMarker(clause) || isEscapedParentRef(clause)) {
|
|
7057
7106
|
throw new CorrelatedReferenceError(`Unsupported $parent reference as a direct ${key} clause`);
|
|
7058
7107
|
}
|
|
7059
|
-
if (!(0,
|
|
7108
|
+
if (!(0, import_utils20.isPlainObject)(clause)) return cloneSubstitutedValue(clause);
|
|
7060
7109
|
return resolveObjectEntries(clause, parent);
|
|
7061
7110
|
});
|
|
7062
7111
|
continue;
|
|
@@ -7085,10 +7134,10 @@ function resolveValueNode(template, parent, bare) {
|
|
|
7085
7134
|
}
|
|
7086
7135
|
const value = getOwnPathValue(parent, path);
|
|
7087
7136
|
if (value === void 0 || value === null) throw UNRESOLVABLE;
|
|
7088
|
-
if (bare && (0,
|
|
7137
|
+
if (bare && (0, import_utils20.isPlainObject)(value)) return { $eq: (0, import_utils20.cloneDeep)(value) };
|
|
7089
7138
|
return cloneSubstitutedValue(value);
|
|
7090
7139
|
}
|
|
7091
|
-
if ((0,
|
|
7140
|
+
if ((0, import_utils20.isPlainObject)(template)) {
|
|
7092
7141
|
if (hasMarkerKey(template)) {
|
|
7093
7142
|
throw new CorrelatedReferenceError(
|
|
7094
7143
|
'Malformed $parent reference: objects carrying $parent must be exactly { "$parent": "<field>" }'
|
|
@@ -7096,7 +7145,7 @@ function resolveValueNode(template, parent, bare) {
|
|
|
7096
7145
|
}
|
|
7097
7146
|
return resolveObjectEntries(template, parent);
|
|
7098
7147
|
}
|
|
7099
|
-
if ((0,
|
|
7148
|
+
if ((0, import_utils20.isArray)(template)) {
|
|
7100
7149
|
return template.map((item) => resolveValueNode(item, parent, false));
|
|
7101
7150
|
}
|
|
7102
7151
|
return template;
|
|
@@ -7130,7 +7179,7 @@ function resolveCorrelatedIdTemplate(id, parent) {
|
|
|
7130
7179
|
}
|
|
7131
7180
|
function resolveCorrelatedFilterTemplate(filter2, parent) {
|
|
7132
7181
|
try {
|
|
7133
|
-
if (!(0,
|
|
7182
|
+
if (!(0, import_utils20.isPlainObject)(filter2) || isParentRefMarker(filter2) || isEscapedParentRef(filter2)) {
|
|
7134
7183
|
throw new CorrelatedReferenceError("Correlated include filter must be an object");
|
|
7135
7184
|
}
|
|
7136
7185
|
return { status: "resolved", filter: resolveObjectEntries(filter2, parent) };
|
|
@@ -7145,7 +7194,7 @@ function validateExpandedCorrelatedOperands(expanded, limits) {
|
|
|
7145
7194
|
var MAX_NESTED_INCLUDE_DEPTH = 10;
|
|
7146
7195
|
function validateCorrelatedArgsShape(args, op, depth) {
|
|
7147
7196
|
if (args === void 0) return [];
|
|
7148
|
-
if (!(0,
|
|
7197
|
+
if (!(0, import_utils20.isPlainObject)(args)) return ["Correlated include args must be an object"];
|
|
7149
7198
|
const record3 = args;
|
|
7150
7199
|
const allowed = op === "list" ? /* @__PURE__ */ new Set(["select", "sort", "skip", "limit", "page", "pageSize", "include"]) : /* @__PURE__ */ new Set(["select", "sort", "include"]);
|
|
7151
7200
|
for (const key of Object.keys(record3)) {
|
|
@@ -7167,7 +7216,7 @@ function validateCorrelatedArgsShape(args, op, depth) {
|
|
|
7167
7216
|
return [];
|
|
7168
7217
|
}
|
|
7169
7218
|
function validateCorrelatedIncludeShape(entry, depth = 0) {
|
|
7170
|
-
if (!(0,
|
|
7219
|
+
if (!(0, import_utils20.isPlainObject)(entry)) return ["Correlated include must be an object"];
|
|
7171
7220
|
const record3 = entry;
|
|
7172
7221
|
if (record3.mode !== "correlated") return ['Correlated include mode must be "correlated"'];
|
|
7173
7222
|
if (typeof record3.model !== "string" || record3.model.length === 0)
|
|
@@ -7180,7 +7229,7 @@ function validateCorrelatedIncludeShape(entry, depth = 0) {
|
|
|
7180
7229
|
if ("localField" in record3 || "foreignField" in record3) {
|
|
7181
7230
|
return ["Correlated includes must not carry localField or foreignField"];
|
|
7182
7231
|
}
|
|
7183
|
-
if (record3.options !== void 0 && !((0,
|
|
7232
|
+
if (record3.options !== void 0 && !((0, import_utils20.isPlainObject)(record3.options) && Object.keys(record3.options).length === 0)) {
|
|
7184
7233
|
return ["Correlated include options must be absent or empty"];
|
|
7185
7234
|
}
|
|
7186
7235
|
const hasId = record3.id !== void 0;
|
|
@@ -7202,7 +7251,7 @@ function validateCorrelatedIncludeShape(entry, depth = 0) {
|
|
|
7202
7251
|
return validateCorrelatedArgsShape(record3.args, record3.op, depth);
|
|
7203
7252
|
}
|
|
7204
7253
|
function isCorrelatedInclude(value) {
|
|
7205
|
-
return (0,
|
|
7254
|
+
return (0, import_utils20.isPlainObject)(value) && value.mode === "correlated";
|
|
7206
7255
|
}
|
|
7207
7256
|
|
|
7208
7257
|
// src/services/base.ts
|
|
@@ -7269,6 +7318,11 @@ function modelServiceOptions(receiver, read) {
|
|
|
7269
7318
|
if (call?.receiver !== receiver) return read();
|
|
7270
7319
|
return call.options ??= read();
|
|
7271
7320
|
}
|
|
7321
|
+
function modelServiceGlobalOptions(receiver, runtime) {
|
|
7322
|
+
const call = dispatch.getStore();
|
|
7323
|
+
if (call?.receiver !== receiver) return runtime.getGlobalOptions();
|
|
7324
|
+
return call.globalOptions ??= runtime.getGlobalOptions();
|
|
7325
|
+
}
|
|
7272
7326
|
|
|
7273
7327
|
// src/services/base.ts
|
|
7274
7328
|
init_request_work();
|
|
@@ -7421,9 +7475,31 @@ function castCountGroups(input, values) {
|
|
|
7421
7475
|
// src/services/base.ts
|
|
7422
7476
|
init_service_authorization();
|
|
7423
7477
|
|
|
7478
|
+
// src/meta.ts
|
|
7479
|
+
init_runtime();
|
|
7480
|
+
init_runtime_context();
|
|
7481
|
+
var getRuntime5 = () => getActiveRuntime() ?? defaultRuntime;
|
|
7482
|
+
var getModelRef = (modelName, refPath, runtime = getRuntime5()) => {
|
|
7483
|
+
const direct = runtime.getModelRef(modelName, refPath);
|
|
7484
|
+
if (direct) return direct;
|
|
7485
|
+
if (!refPath.includes(".")) return null;
|
|
7486
|
+
try {
|
|
7487
|
+
const instance = runtime.getModelInstance?.(
|
|
7488
|
+
modelName
|
|
7489
|
+
);
|
|
7490
|
+
const schemaPath = instance?.schema?.path?.(refPath);
|
|
7491
|
+
const element = schemaPath?.$embeddedSchemaType ?? schemaPath?.embeddedSchemaType ?? schemaPath?.caster;
|
|
7492
|
+
const ref = schemaPath?.options?.ref ?? element?.options?.ref ?? null;
|
|
7493
|
+
return typeof ref === "string" && ref.length > 0 ? ref : null;
|
|
7494
|
+
} catch {
|
|
7495
|
+
return null;
|
|
7496
|
+
}
|
|
7497
|
+
};
|
|
7498
|
+
|
|
7424
7499
|
// src/acl/related-execution.ts
|
|
7425
7500
|
init_public_admission();
|
|
7426
7501
|
init_model_output_planning();
|
|
7502
|
+
init_populate_target_configuration();
|
|
7427
7503
|
init_authorization_snapshot();
|
|
7428
7504
|
|
|
7429
7505
|
// src/acl/service-execution.ts
|
|
@@ -7709,7 +7785,7 @@ function staticObjectIdReference(runtime, source, path, target) {
|
|
|
7709
7785
|
const scalar = type?.instance === "Array" ? type.$embeddedSchemaType ?? type.embeddedSchemaType ?? type.caster : type;
|
|
7710
7786
|
return scalar?.instance === "ObjectId" && (type?.options?.ref ?? scalar.options?.ref) === target && type?.options?.refPath === void 0 && scalar.options?.refPath === void 0;
|
|
7711
7787
|
}
|
|
7712
|
-
function captureRelatedTargets(runtime, modelName, args = {}, depth = 0) {
|
|
7788
|
+
function captureRelatedTargets(runtime, modelName, args = {}, depth = 0, globalOptions = runtime.getGlobalOptions()) {
|
|
7713
7789
|
if (depth > 32) authorizationError("related descriptor depth exceeded");
|
|
7714
7790
|
assertPublicAdmission(args.populate, "populate");
|
|
7715
7791
|
assertPublicAdmission(args.include, "include");
|
|
@@ -7718,21 +7794,20 @@ function captureRelatedTargets(runtime, modelName, args = {}, depth = 0) {
|
|
|
7718
7794
|
for (const entry of entries(args.populate)) {
|
|
7719
7795
|
const path = typeof entry === "string" ? entry : entry.path;
|
|
7720
7796
|
if (typeof entry !== "string") assertPopulateAccess(entry.access);
|
|
7721
|
-
const model = getModelRef(modelName, path);
|
|
7722
|
-
if (model
|
|
7797
|
+
const model = getModelRef(modelName, path, runtime);
|
|
7798
|
+
if (model) {
|
|
7799
|
+
const target = capturePopulateTargetConfiguration(runtime, model, `${modelName}.${path}`);
|
|
7723
7800
|
targets.push({
|
|
7724
7801
|
path,
|
|
7725
7802
|
modelName: model,
|
|
7726
|
-
configuration: captureModelAuthorizationConfiguration(runtime, model),
|
|
7803
|
+
configuration: captureModelAuthorizationConfiguration(runtime, model, target.options, globalOptions),
|
|
7727
7804
|
staticObjectIdReference: staticObjectIdReference(runtime, modelName, path, model)
|
|
7728
7805
|
});
|
|
7729
|
-
else if (model && !runtime.getGlobalOption("requireRegisteredPopulateModels", true)) {
|
|
7730
|
-
targets.push({ path, modelName: model, kind: "passthrough", configuration: { catalog: { paths: [] } } });
|
|
7731
7806
|
}
|
|
7732
7807
|
}
|
|
7733
7808
|
for (const entry of entries(args.include)) {
|
|
7734
7809
|
if (!runtime.hasModel(entry.model)) authorizationError(`Model ${entry.model} not found`);
|
|
7735
|
-
const configuration = captureModelAuthorizationConfiguration(runtime, entry.model);
|
|
7810
|
+
const configuration = captureModelAuthorizationConfiguration(runtime, entry.model, void 0, globalOptions);
|
|
7736
7811
|
const queryIntent = entry.op === "count" ? void 0 : captureModelServiceIntent(
|
|
7737
7812
|
{
|
|
7738
7813
|
defaults: configuration.defaults ?? {},
|
|
@@ -7758,7 +7833,13 @@ function captureRelatedTargets(runtime, modelName, args = {}, depth = 0) {
|
|
|
7758
7833
|
configuration,
|
|
7759
7834
|
queryIntent,
|
|
7760
7835
|
operationGuard: runtime.getModelOption(entry.model, `operationAccess.${entry.op}`),
|
|
7761
|
-
relatedTargets: captureRelatedTargets(
|
|
7836
|
+
relatedTargets: captureRelatedTargets(
|
|
7837
|
+
runtime,
|
|
7838
|
+
entry.model,
|
|
7839
|
+
queryIntent?.args ?? entry.args ?? {},
|
|
7840
|
+
depth + 1,
|
|
7841
|
+
globalOptions
|
|
7842
|
+
)
|
|
7762
7843
|
});
|
|
7763
7844
|
}
|
|
7764
7845
|
if (new Set(targets.map((target) => target.path)).size !== targets.length)
|
|
@@ -7907,20 +7988,20 @@ var copyAuthorizedOutput = (value) => {
|
|
|
7907
7988
|
transferDocumentAuthorizationGraph(value, copy);
|
|
7908
7989
|
return copy;
|
|
7909
7990
|
};
|
|
7910
|
-
var isVirtualContainerValueForGuard = (value) => (0,
|
|
7991
|
+
var isVirtualContainerValueForGuard = (value) => (0, import_utils24.isPlainObject)(value) && "sub" in value;
|
|
7911
7992
|
var getScopeVirtualsForGuard = (rootVirtuals, scopePath) => {
|
|
7912
|
-
if (!rootVirtuals || !(0,
|
|
7993
|
+
if (!rootVirtuals || !(0, import_utils24.isPlainObject)(rootVirtuals)) return null;
|
|
7913
7994
|
if (scopePath.length === 0) return rootVirtuals;
|
|
7914
7995
|
let current = rootVirtuals;
|
|
7915
7996
|
for (let i = 0; i < scopePath.length; i += 2) {
|
|
7916
7997
|
const field = scopePath[i];
|
|
7917
7998
|
const subMarker = scopePath[i + 1];
|
|
7918
7999
|
if (!field || subMarker !== "sub") return null;
|
|
7919
|
-
if (!(0,
|
|
8000
|
+
if (!(0, import_utils24.isPlainObject)(current)) return null;
|
|
7920
8001
|
const container = current[field];
|
|
7921
8002
|
if (!isVirtualContainerValueForGuard(container)) return null;
|
|
7922
8003
|
current = container.sub;
|
|
7923
|
-
if (!(0,
|
|
8004
|
+
if (!(0, import_utils24.isPlainObject)(current)) return null;
|
|
7924
8005
|
}
|
|
7925
8006
|
return current;
|
|
7926
8007
|
};
|
|
@@ -7986,7 +8067,7 @@ var sanitizeSubScopeVirtualKeys = (data, snapshot, sub) => {
|
|
|
7986
8067
|
for (const entry of value) stripScope(entry, currentScope);
|
|
7987
8068
|
return;
|
|
7988
8069
|
}
|
|
7989
|
-
if (!(0,
|
|
8070
|
+
if (!(0, import_utils24.isPlainObject)(value)) return;
|
|
7990
8071
|
const record3 = value;
|
|
7991
8072
|
const leaves = getScopeVirtualLeafNames(snapshot, currentScope);
|
|
7992
8073
|
for (const leaf of leaves) {
|
|
@@ -7999,7 +8080,7 @@ var sanitizeSubScopeVirtualKeys = (data, snapshot, sub) => {
|
|
|
7999
8080
|
for (const key of Object.keys(record3)) {
|
|
8000
8081
|
if (leaves.has(key) || containers.has(key)) continue;
|
|
8001
8082
|
const child = record3[key];
|
|
8002
|
-
if (Array.isArray(child) || (0,
|
|
8083
|
+
if (Array.isArray(child) || (0, import_utils24.isPlainObject)(child)) {
|
|
8003
8084
|
stripScope(child, currentScope);
|
|
8004
8085
|
}
|
|
8005
8086
|
}
|
|
@@ -8011,7 +8092,7 @@ var LOGICAL_FILTER_KEYS = /* @__PURE__ */ new Set(["$and", "$or", "$nor"]);
|
|
|
8011
8092
|
var isOperatorKey = (key) => key.startsWith("$");
|
|
8012
8093
|
var REMOVED_VIRTUAL_FILTER = /* @__PURE__ */ Symbol("removed virtual filter clause");
|
|
8013
8094
|
var rewriteFilterObject = (value, visit) => {
|
|
8014
|
-
if (!(0,
|
|
8095
|
+
if (!(0, import_utils24.isPlainObject)(value)) return value;
|
|
8015
8096
|
let changed = false;
|
|
8016
8097
|
const entries = [];
|
|
8017
8098
|
for (const [key, child] of Object.entries(value)) {
|
|
@@ -8042,7 +8123,7 @@ var resolveVirtualFilterField = (path, scope2) => {
|
|
|
8042
8123
|
if (!Object.hasOwn(scope2, segment) || scope2[segment] === void 0) return null;
|
|
8043
8124
|
const definition = scope2[segment];
|
|
8044
8125
|
if (!isVirtualContainerValueForGuard(definition)) return REMOVED_VIRTUAL_FILTER;
|
|
8045
|
-
scope2 = (0,
|
|
8126
|
+
scope2 = (0, import_utils24.isPlainObject)(definition.sub) ? definition.sub : null;
|
|
8046
8127
|
inContainer = true;
|
|
8047
8128
|
}
|
|
8048
8129
|
return scope2;
|
|
@@ -8054,7 +8135,7 @@ var stripVirtualFilterOperator = (key, value, scope2) => {
|
|
|
8054
8135
|
}
|
|
8055
8136
|
if (key === "$all") {
|
|
8056
8137
|
return rewriteFilterClauses(value, (entry) => {
|
|
8057
|
-
if (!(0,
|
|
8138
|
+
if (!(0, import_utils24.isPlainObject)(entry) || Object.keys(entry).length !== 1 || !Object.hasOwn(entry, "$elemMatch")) return entry;
|
|
8058
8139
|
return rewriteFilterObject(entry, (operator, operand) => stripVirtualFilterOperator(operator, operand, scope2));
|
|
8059
8140
|
});
|
|
8060
8141
|
}
|
|
@@ -8069,7 +8150,7 @@ var stripVirtualFilterQuery = (value, scope2, element = false) => {
|
|
|
8069
8150
|
if (isOperatorKey(key)) return element ? stripVirtualFilterOperator(key, child, scope2) : child;
|
|
8070
8151
|
const fieldScope = resolveVirtualFilterField(key, scope2);
|
|
8071
8152
|
if (fieldScope === REMOVED_VIRTUAL_FILTER) return REMOVED_VIRTUAL_FILTER;
|
|
8072
|
-
if (!fieldScope || !(0,
|
|
8153
|
+
if (!fieldScope || !(0, import_utils24.isPlainObject)(child)) return child;
|
|
8073
8154
|
if (Object.keys(child).some(isOperatorKey)) {
|
|
8074
8155
|
return rewriteFilterObject(
|
|
8075
8156
|
child,
|
|
@@ -8091,9 +8172,9 @@ var stripSubVirtualKeysFromFilter = (filter2, snapshot, sub) => {
|
|
|
8091
8172
|
function getCorrelatedTemplateDepth(includes) {
|
|
8092
8173
|
let max = 0;
|
|
8093
8174
|
const visit = (entries, depth) => {
|
|
8094
|
-
const list = (0,
|
|
8175
|
+
const list = (0, import_utils24.castArray)(entries).filter(Boolean);
|
|
8095
8176
|
for (const entry of list) {
|
|
8096
|
-
if (!(0,
|
|
8177
|
+
if (!(0, import_utils24.isPlainObject)(entry)) continue;
|
|
8097
8178
|
max = Math.max(max, depth);
|
|
8098
8179
|
const nested = entry.args?.include;
|
|
8099
8180
|
if (nested !== void 0) {
|
|
@@ -8118,11 +8199,11 @@ function validateClientFilter(filter2) {
|
|
|
8118
8199
|
}
|
|
8119
8200
|
const blockedOperators = /* @__PURE__ */ new Set(["$where", "$expr", "$function", "$accumulator"]);
|
|
8120
8201
|
const visit = (value, path) => {
|
|
8121
|
-
if ((0,
|
|
8202
|
+
if ((0, import_utils24.isArray)(value)) {
|
|
8122
8203
|
value.forEach((item, index) => visit(item, `${path}[${index}]`));
|
|
8123
8204
|
return;
|
|
8124
8205
|
}
|
|
8125
|
-
if (!(0,
|
|
8206
|
+
if (!(0, import_utils24.isPlainObject)(value)) return;
|
|
8126
8207
|
Object.entries(value).forEach(([key, child]) => {
|
|
8127
8208
|
const nextPath = path ? `${path}.${key}` : key;
|
|
8128
8209
|
if (blockedOperators.has(key)) {
|
|
@@ -8327,7 +8408,7 @@ var Base = class {
|
|
|
8327
8408
|
}
|
|
8328
8409
|
processInclude(include, authorization) {
|
|
8329
8410
|
assertPublicAdmission(include, "include");
|
|
8330
|
-
const items = (0,
|
|
8411
|
+
const items = (0, import_utils24.compact)((0, import_utils24.castArray)(include));
|
|
8331
8412
|
const legacy = [];
|
|
8332
8413
|
const correlated = [];
|
|
8333
8414
|
const correlatedReferenceFields = [];
|
|
@@ -8363,23 +8444,23 @@ var Base = class {
|
|
|
8363
8444
|
else this.assertIncludeOutputPaths([...legacy, ...correlated]);
|
|
8364
8445
|
let includeLocalFields = [];
|
|
8365
8446
|
let includePaths = [];
|
|
8366
|
-
(0,
|
|
8447
|
+
(0, import_utils24.forEach)(legacy, (inc) => {
|
|
8367
8448
|
includeLocalFields.push(inc.localField);
|
|
8368
8449
|
includePaths.push(inc.path);
|
|
8369
8450
|
});
|
|
8370
|
-
includeLocalFields = (0,
|
|
8371
|
-
includePaths = (0,
|
|
8451
|
+
includeLocalFields = (0, import_utils24.uniq)((0, import_utils24.compact)(includeLocalFields));
|
|
8452
|
+
includePaths = (0, import_utils24.uniq)((0, import_utils24.compact)(includePaths));
|
|
8372
8453
|
return {
|
|
8373
8454
|
includes: legacy,
|
|
8374
8455
|
correlatedIncludes: correlated,
|
|
8375
8456
|
includeLocalFields,
|
|
8376
8457
|
includePaths,
|
|
8377
|
-
correlatedReferenceFields: (0,
|
|
8458
|
+
correlatedReferenceFields: (0, import_utils24.uniq)((0, import_utils24.compact)(correlatedReferenceFields))
|
|
8378
8459
|
};
|
|
8379
8460
|
}
|
|
8380
8461
|
validateIncludeOutputPath(path, modelName, configuration) {
|
|
8381
8462
|
const permissionField = configuration ? configuration.documentPermissionField ?? "_permissions" : getModelOption(modelName, "documentPermissionField");
|
|
8382
|
-
if ((0,
|
|
8463
|
+
if ((0, import_utils24.get)((0, import_utils24.set)({}, path, true), permissionField) !== void 0 || (0, import_utils24.get)((0, import_utils24.set)({}, permissionField, true), path) !== void 0) {
|
|
8383
8464
|
this.throwClientRequestError(
|
|
8384
8465
|
"bad_request" /* BadRequest */,
|
|
8385
8466
|
`Include output path ${path} overlaps document permission field ${permissionField} on model ${modelName}`
|
|
@@ -8404,9 +8485,9 @@ var Base = class {
|
|
|
8404
8485
|
const walk = (node, prefix) => {
|
|
8405
8486
|
for (const [key, value] of Object.entries(node)) {
|
|
8406
8487
|
if (value === void 0) continue;
|
|
8407
|
-
if ((0,
|
|
8488
|
+
if ((0, import_utils24.isPlainObject)(value) && "sub" in value) {
|
|
8408
8489
|
const sub = value.sub;
|
|
8409
|
-
if ((0,
|
|
8490
|
+
if ((0, import_utils24.isPlainObject)(sub)) walk(sub, prefix ? `${prefix}.${key}` : key);
|
|
8410
8491
|
continue;
|
|
8411
8492
|
}
|
|
8412
8493
|
out.push(prefix ? `${prefix}.${key}` : key);
|
|
@@ -8459,7 +8540,7 @@ var Base = class {
|
|
|
8459
8540
|
this.throwClientRequestError("bad_request" /* BadRequest */, `Model ${modelName} not found`);
|
|
8460
8541
|
}
|
|
8461
8542
|
for (const entry of entries) {
|
|
8462
|
-
if (!(0,
|
|
8543
|
+
if (!(0, import_utils24.isPlainObject)(entry)) continue;
|
|
8463
8544
|
const models = visited.get(entry) ?? /* @__PURE__ */ new Set();
|
|
8464
8545
|
if (models.has(modelName)) continue;
|
|
8465
8546
|
models.add(modelName);
|
|
@@ -8472,7 +8553,7 @@ var Base = class {
|
|
|
8472
8553
|
const target = targets?.find((target2) => target2.path === entry.path);
|
|
8473
8554
|
if (nested)
|
|
8474
8555
|
pending.push({
|
|
8475
|
-
entries: (0,
|
|
8556
|
+
entries: (0, import_utils24.compact)((0, import_utils24.castArray)(nested)),
|
|
8476
8557
|
modelName: entry.model,
|
|
8477
8558
|
configuration: target?.configuration,
|
|
8478
8559
|
targets: target?.relatedTargets
|
|
@@ -8482,7 +8563,7 @@ var Base = class {
|
|
|
8482
8563
|
}
|
|
8483
8564
|
}
|
|
8484
8565
|
getForeignKeyValues(value) {
|
|
8485
|
-
return (0,
|
|
8566
|
+
return (0, import_utils24.flatten)((0, import_utils24.castArray)(value));
|
|
8486
8567
|
}
|
|
8487
8568
|
getForeignKey(value) {
|
|
8488
8569
|
return String(value);
|
|
@@ -8490,7 +8571,7 @@ var Base = class {
|
|
|
8490
8571
|
buildForeignKeyIndex(rows2, foreignField) {
|
|
8491
8572
|
const index = /* @__PURE__ */ new Map();
|
|
8492
8573
|
for (const row of rows2) {
|
|
8493
|
-
for (const value of this.getForeignKeyValues((0,
|
|
8574
|
+
for (const value of this.getForeignKeyValues((0, import_utils24.get)(row, foreignField))) {
|
|
8494
8575
|
const key = this.getForeignKey(value);
|
|
8495
8576
|
const values = index.get(key);
|
|
8496
8577
|
if (values) values.push(row);
|
|
@@ -8526,9 +8607,9 @@ var Base = class {
|
|
|
8526
8607
|
async includeDocs(docs, include, parentAuthorization) {
|
|
8527
8608
|
assertPublicAdmission(include, "include");
|
|
8528
8609
|
if (!include) return docs;
|
|
8529
|
-
const includes = (0,
|
|
8610
|
+
const includes = (0, import_utils24.compact)((0, import_utils24.castArray)(include));
|
|
8530
8611
|
if (includes.length === 0) return docs;
|
|
8531
|
-
const isSingle = !(0,
|
|
8612
|
+
const isSingle = !(0, import_utils24.isArray)(docs);
|
|
8532
8613
|
let docList = (isSingle ? [docs] : docs).map(prepareIncludeOutput);
|
|
8533
8614
|
for (let x = 0; x < includes.length; x++) {
|
|
8534
8615
|
const include2 = includes[x];
|
|
@@ -8558,7 +8639,7 @@ var Base = class {
|
|
|
8558
8639
|
const svc = await this.getAuthorizedTargetService(model, "read", path, parentAuthorization);
|
|
8559
8640
|
for (let y = 0; y < docs.length; y++) {
|
|
8560
8641
|
const doc = docs[y];
|
|
8561
|
-
const localValue = (0,
|
|
8642
|
+
const localValue = (0, import_utils24.get)(doc, localField);
|
|
8562
8643
|
const execution = this.relatedExecution(svc, include, parentAuthorization);
|
|
8563
8644
|
const prepared = await prepareModelQuery(
|
|
8564
8645
|
svc,
|
|
@@ -8593,15 +8674,15 @@ var Base = class {
|
|
|
8593
8674
|
const { model, op, path, localField, foreignField, filter: _filters, args = {}, options = {} } = include;
|
|
8594
8675
|
const svc = await this.getAuthorizedTargetService(model, op, path, parentAuthorization);
|
|
8595
8676
|
const includeLocalValues = [];
|
|
8596
|
-
(0,
|
|
8597
|
-
includeLocalValues.push(...this.getForeignKeyValues((0,
|
|
8677
|
+
(0, import_utils24.forEach)(docs, (doc) => {
|
|
8678
|
+
includeLocalValues.push(...this.getForeignKeyValues((0, import_utils24.get)(doc, localField)));
|
|
8598
8679
|
});
|
|
8599
8680
|
const execution = this.relatedExecution(svc, include, parentAuthorization);
|
|
8600
8681
|
const prepared = await prepareModelQuery(
|
|
8601
8682
|
svc,
|
|
8602
8683
|
execution,
|
|
8603
8684
|
{ kind: "client-read", filter: _filters ?? {} },
|
|
8604
|
-
{ [foreignField]: { $in: (0,
|
|
8685
|
+
{ [foreignField]: { $in: (0, import_utils24.flatten)(includeLocalValues) } },
|
|
8605
8686
|
true
|
|
8606
8687
|
);
|
|
8607
8688
|
const trustedArgs = this.sanitizeIncludeArgs(args, "list");
|
|
@@ -8644,7 +8725,7 @@ var Base = class {
|
|
|
8644
8725
|
}
|
|
8645
8726
|
for (let y = 0; y < docs.length; y++) {
|
|
8646
8727
|
const doc = docs[y];
|
|
8647
|
-
const matches = this.getIndexedMatches(index, (0,
|
|
8728
|
+
const matches = this.getIndexedMatches(index, (0, import_utils24.get)(doc, localField));
|
|
8648
8729
|
const isolated = matches.map((m) => copyAuthorizedOutput(m));
|
|
8649
8730
|
attachIncludeOutput(doc, path, op === "list" ? isolated : isolated[0]);
|
|
8650
8731
|
}
|
|
@@ -8653,7 +8734,7 @@ var Base = class {
|
|
|
8653
8734
|
async includeDocsCount(docs, include, parentAuthorization) {
|
|
8654
8735
|
const { model, path, localField, foreignField, filter: _filters } = include;
|
|
8655
8736
|
const svc = await this.getAuthorizedTargetService(model, "count", path, parentAuthorization);
|
|
8656
|
-
const groups = prepareCountGroups(docs, (doc) => (0,
|
|
8737
|
+
const groups = prepareCountGroups(docs, (doc) => (0, import_utils24.get)(doc, localField));
|
|
8657
8738
|
const execution = this.relatedExecution(svc, include, parentAuthorization);
|
|
8658
8739
|
const prepared = await prepareModelQuery(
|
|
8659
8740
|
svc,
|
|
@@ -8707,7 +8788,7 @@ var Base = class {
|
|
|
8707
8788
|
}
|
|
8708
8789
|
const state = this.getCorrelatedExecState();
|
|
8709
8790
|
docs = docs.map(prepareIncludeOutput);
|
|
8710
|
-
const resolvedSnapshots = snapshots2 ?? docs.map((doc) => (0,
|
|
8791
|
+
const resolvedSnapshots = snapshots2 ?? docs.map((doc) => (0, import_utils24.cloneDeep)(toObject(getIncludeSource(doc))));
|
|
8711
8792
|
for (const include of correlatedIncludes) {
|
|
8712
8793
|
switch (include.op) {
|
|
8713
8794
|
case "read":
|
|
@@ -9056,10 +9137,10 @@ var Base = class {
|
|
|
9056
9137
|
}
|
|
9057
9138
|
let ret = result2.data;
|
|
9058
9139
|
if (sqOptions.path) {
|
|
9059
|
-
ret = (0,
|
|
9140
|
+
ret = (0, import_utils24.isArray)(ret) ? (0, import_utils24.flatten)(ret.map((v) => (0, import_utils24.get)(v, sqOptions.path))) : (0, import_utils24.get)(ret, sqOptions.path);
|
|
9060
9141
|
}
|
|
9061
9142
|
if (sqOptions.compact) {
|
|
9062
|
-
ret = (0,
|
|
9143
|
+
ret = (0, import_utils24.compact)((0, import_utils24.castArray)(ret));
|
|
9063
9144
|
}
|
|
9064
9145
|
return ret;
|
|
9065
9146
|
}
|
|
@@ -9071,11 +9152,11 @@ var Base = class {
|
|
|
9071
9152
|
};
|
|
9072
9153
|
|
|
9073
9154
|
// src/services/service.ts
|
|
9074
|
-
var
|
|
9155
|
+
var import_utils35 = require("@web-ts-toolkit/utils");
|
|
9075
9156
|
var import_just_diff = require("just-diff");
|
|
9076
9157
|
|
|
9077
9158
|
// src/model.ts
|
|
9078
|
-
var
|
|
9159
|
+
var import_utils25 = require("@web-ts-toolkit/utils");
|
|
9079
9160
|
init_runtime_context();
|
|
9080
9161
|
init_runtime();
|
|
9081
9162
|
function admitModelPersistence(adapter, scheduler) {
|
|
@@ -9151,7 +9232,7 @@ var Model = class {
|
|
|
9151
9232
|
}
|
|
9152
9233
|
/** Cast a copy using this model's query schema/setters, without executing query middleware or persistence. */
|
|
9153
9234
|
castFilter(filter2) {
|
|
9154
|
-
const query = this.mongooseModel.countDocuments((0,
|
|
9235
|
+
const query = this.mongooseModel.countDocuments((0, import_utils25.cloneDeep)(filter2));
|
|
9155
9236
|
return query.cast(this.mongooseModel);
|
|
9156
9237
|
}
|
|
9157
9238
|
// see https://mongoosejs.com/docs/api.html#model_Model.distinct
|
|
@@ -9165,7 +9246,7 @@ var Model = class {
|
|
|
9165
9246
|
var model_default = Model;
|
|
9166
9247
|
|
|
9167
9248
|
// src/acl/distinct-field-authorization.ts
|
|
9168
|
-
var
|
|
9249
|
+
var import_utils26 = require("@web-ts-toolkit/utils");
|
|
9169
9250
|
init_field_authorization();
|
|
9170
9251
|
init_field_catalog();
|
|
9171
9252
|
var schemaVariants = (schema) => Object.values(schema.discriminators ?? {});
|
|
@@ -9247,8 +9328,8 @@ function isDistinctFieldAuthorized(args) {
|
|
|
9247
9328
|
if (path !== field && !path.startsWith(`${field}.`) && !field.startsWith(`${path}.`)) continue;
|
|
9248
9329
|
if (path.startsWith(`${field}.`) && (!eligible(path) || !schemaShape(schema, path) || !granted(path)))
|
|
9249
9330
|
return false;
|
|
9250
|
-
if ((0,
|
|
9251
|
-
if (!(0,
|
|
9331
|
+
if ((0, import_utils26.isPlainObject)(raw) && raw.sub !== void 0) {
|
|
9332
|
+
if (!(0, import_utils26.isPlainObject)(raw.sub) || !declaredRulesSafe(raw.sub, path, next)) return false;
|
|
9252
9333
|
}
|
|
9253
9334
|
}
|
|
9254
9335
|
return true;
|
|
@@ -9330,7 +9411,9 @@ function prepareSubdocumentOutput(service, sub, operation, virtualAccess, output
|
|
|
9330
9411
|
captureRelatedTargets(
|
|
9331
9412
|
getServiceExecutors(service).binding().runtime,
|
|
9332
9413
|
service.getServiceModelName(),
|
|
9333
|
-
{ populate }
|
|
9414
|
+
{ populate },
|
|
9415
|
+
0,
|
|
9416
|
+
configuration
|
|
9334
9417
|
),
|
|
9335
9418
|
void 0,
|
|
9336
9419
|
configuration,
|
|
@@ -9423,7 +9506,7 @@ init_document();
|
|
|
9423
9506
|
init_populate_target();
|
|
9424
9507
|
|
|
9425
9508
|
// src/helpers/apply-update.ts
|
|
9426
|
-
var
|
|
9509
|
+
var import_utils30 = require("@web-ts-toolkit/utils");
|
|
9427
9510
|
init_lib();
|
|
9428
9511
|
function applyUpdate(target, data, allowedFields) {
|
|
9429
9512
|
const wholeFields = /* @__PURE__ */ new Set();
|
|
@@ -9439,17 +9522,17 @@ function applyUpdate(target, data, allowedFields) {
|
|
|
9439
9522
|
}
|
|
9440
9523
|
};
|
|
9441
9524
|
for (const field of allowedFields) {
|
|
9442
|
-
collectBoundary((0,
|
|
9525
|
+
collectBoundary((0, import_utils30.set)({}, field, true));
|
|
9443
9526
|
}
|
|
9444
9527
|
const apply = (values, prefix = "") => {
|
|
9445
9528
|
for (const [key, value] of Object.entries(values)) {
|
|
9446
9529
|
const path = prefix ? `${prefix}.${key}` : key;
|
|
9447
|
-
if (partialContainers.has(path) && !wholeFields.has(path) && ((0,
|
|
9530
|
+
if (partialContainers.has(path) && !wholeFields.has(path) && ((0, import_utils30.isPlainObject)(value) || Array.isArray(value))) {
|
|
9448
9531
|
apply(value, path);
|
|
9449
9532
|
} else if (isDocument2(target)) {
|
|
9450
9533
|
target.set(path, value);
|
|
9451
9534
|
} else {
|
|
9452
|
-
(0,
|
|
9535
|
+
(0, import_utils30.set)(target, path, value);
|
|
9453
9536
|
}
|
|
9454
9537
|
}
|
|
9455
9538
|
};
|
|
@@ -9457,7 +9540,7 @@ function applyUpdate(target, data, allowedFields) {
|
|
|
9457
9540
|
}
|
|
9458
9541
|
|
|
9459
9542
|
// src/acl/model-input-admission.ts
|
|
9460
|
-
var
|
|
9543
|
+
var import_utils32 = require("@web-ts-toolkit/utils");
|
|
9461
9544
|
var import_mongoose8 = require("mongoose");
|
|
9462
9545
|
init_document();
|
|
9463
9546
|
init_request_work();
|
|
@@ -9465,7 +9548,7 @@ init_logger_helpers();
|
|
|
9465
9548
|
init_request_complexity();
|
|
9466
9549
|
|
|
9467
9550
|
// src/acl/select-resolution.ts
|
|
9468
|
-
var
|
|
9551
|
+
var import_utils31 = require("@web-ts-toolkit/utils");
|
|
9469
9552
|
init_core_shared();
|
|
9470
9553
|
init_helpers();
|
|
9471
9554
|
async function collectAllowedFieldsForRequest({
|
|
@@ -9539,15 +9622,15 @@ async function resolveSelectForRequest({
|
|
|
9539
9622
|
const excludeall = normalizedSelect.every((v) => v.startsWith("-"));
|
|
9540
9623
|
if (excludeall) {
|
|
9541
9624
|
normalizedSelect = normalizedSelect.map((v) => v.substring(1));
|
|
9542
|
-
fields = (0,
|
|
9625
|
+
fields = (0, import_utils31.difference)(fields, normalizedSelect);
|
|
9543
9626
|
if (excludeid) fields.push("-_id");
|
|
9544
9627
|
} else {
|
|
9545
|
-
fields = (0,
|
|
9628
|
+
fields = (0, import_utils31.intersection)(normalizedSelect, fields.concat(excludeid ? "-_id" : "_id"));
|
|
9546
9629
|
}
|
|
9547
9630
|
}
|
|
9548
9631
|
return fields.concat(strippedAlways);
|
|
9549
9632
|
}
|
|
9550
|
-
return (0,
|
|
9633
|
+
return (0, import_utils31.intersection)(normalizedSelect, fields);
|
|
9551
9634
|
}
|
|
9552
9635
|
function stripVirtuals(fields, virtualNames) {
|
|
9553
9636
|
const set13 = virtualNames instanceof Set ? virtualNames : new Set(virtualNames ?? []);
|
|
@@ -9578,7 +9661,7 @@ init_field_catalog();
|
|
|
9578
9661
|
init_service_authorization();
|
|
9579
9662
|
var own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
9580
9663
|
var inside = (path, root) => path === root || path.startsWith(`${root}.`);
|
|
9581
|
-
var record2 = (value) => (0,
|
|
9664
|
+
var record2 = (value) => (0, import_utils32.isPlainObject)(value);
|
|
9582
9665
|
function inputValue(value) {
|
|
9583
9666
|
if (typeof value === "function" || typeof value === "symbol") {
|
|
9584
9667
|
authorizationError("input values must be persisted data, not functions or symbols");
|
|
@@ -9647,7 +9730,7 @@ function requestBoundaries(fields) {
|
|
|
9647
9730
|
else visit(value, path);
|
|
9648
9731
|
}
|
|
9649
9732
|
};
|
|
9650
|
-
for (const field of fields) visit((0,
|
|
9733
|
+
for (const field of fields) visit((0, import_utils32.set)({}, field, true));
|
|
9651
9734
|
return [...new Set(result2)];
|
|
9652
9735
|
}
|
|
9653
9736
|
function ownValue(data, parts) {
|
|
@@ -9777,7 +9860,7 @@ function admitModelInput(args) {
|
|
|
9777
9860
|
if (forbidden(catalog, path, requested)) continue;
|
|
9778
9861
|
const supplied = ownValue(data, parts);
|
|
9779
9862
|
if (!supplied) continue;
|
|
9780
|
-
(0,
|
|
9863
|
+
(0, import_utils32.set)(allowedData, field, copyInputValue(supplied.value, path, catalog, scopedRequests, logicalPath(field)));
|
|
9781
9864
|
selected.push(field);
|
|
9782
9865
|
}
|
|
9783
9866
|
return { allowedData, allowedFields };
|
|
@@ -9789,7 +9872,7 @@ async function requestInputFields(args) {
|
|
|
9789
9872
|
const prefix = configuration.modelPermissionPrefix ?? "";
|
|
9790
9873
|
return collectModelRequestFields({
|
|
9791
9874
|
req: args.binding.request,
|
|
9792
|
-
permissionSchema: args.scopePath ? (0,
|
|
9875
|
+
permissionSchema: args.scopePath ? (0, import_utils32.get)(configuration.permissionSchema, [args.scopePath, "sub"]) : configuration.permissionSchema,
|
|
9793
9876
|
access: args.access,
|
|
9794
9877
|
permissions,
|
|
9795
9878
|
grants,
|
|
@@ -9833,13 +9916,13 @@ init_logger_helpers();
|
|
|
9833
9916
|
init_lib();
|
|
9834
9917
|
|
|
9835
9918
|
// src/services/model-subdocument-service.ts
|
|
9836
|
-
var
|
|
9919
|
+
var import_utils34 = require("@web-ts-toolkit/utils");
|
|
9837
9920
|
init_helpers();
|
|
9838
9921
|
init_document();
|
|
9839
9922
|
init_public_admission();
|
|
9840
9923
|
|
|
9841
9924
|
// src/acl/subdocument-authorization.ts
|
|
9842
|
-
var
|
|
9925
|
+
var import_utils33 = require("@web-ts-toolkit/utils");
|
|
9843
9926
|
init_helpers();
|
|
9844
9927
|
init_document();
|
|
9845
9928
|
init_core_shared();
|
|
@@ -10028,8 +10111,8 @@ async function subdocumentGateAllowed(service, gate) {
|
|
|
10028
10111
|
let guard2;
|
|
10029
10112
|
if (access.startsWith("subs.")) {
|
|
10030
10113
|
const [, sub, op] = access.split(".");
|
|
10031
|
-
guard2 = (0,
|
|
10032
|
-
if (guard2 === void 0) guard2 = (0,
|
|
10114
|
+
guard2 = (0, import_utils33.get)(configuration, `operationAccess.${access}`);
|
|
10115
|
+
if (guard2 === void 0) guard2 = (0, import_utils33.get)(configuration, `operationAccess.subs.${sub}`);
|
|
10033
10116
|
if (guard2 === void 0) guard2 = getCapturedAuthorizationOption(configuration, `operationAccess.${op}`);
|
|
10034
10117
|
} else guard2 = getCapturedAuthorizationOption(configuration, `operationAccess.${access}`);
|
|
10035
10118
|
return evaluateRouteGuard(
|
|
@@ -10160,7 +10243,7 @@ async function visibleMutationRows(service, call, parentId, rows2) {
|
|
|
10160
10243
|
const read = await subdocumentRows(service, visibility.child, selected, selected, call.sub);
|
|
10161
10244
|
const list = visibility.list ? await subdocumentRows(service, visibility.list, {}, {}, call.sub) : {};
|
|
10162
10245
|
if (read === false || list === false) return [];
|
|
10163
|
-
const visible = filterCollection((0,
|
|
10246
|
+
const visible = filterCollection((0, import_utils34.get)(parent, call.sub), intersectFilters(read, list));
|
|
10164
10247
|
return await finalizeSubdocumentRows(service, call.output, parent, visible);
|
|
10165
10248
|
} catch {
|
|
10166
10249
|
return [];
|
|
@@ -10185,7 +10268,7 @@ async function listSub(service, id, sub, options) {
|
|
|
10185
10268
|
populate: []
|
|
10186
10269
|
});
|
|
10187
10270
|
if (!parent) return denied2("not_found" /* NotFound */);
|
|
10188
|
-
const rows2 = filterCollection((0,
|
|
10271
|
+
const rows2 = filterCollection((0, import_utils34.get)(parent, sub), childFilter);
|
|
10189
10272
|
const data = await finalizeSubdocumentRows(service, call.output, parent, rows2);
|
|
10190
10273
|
return { success: true, kind: "list", code: "success" /* Success */, data, count: data.length };
|
|
10191
10274
|
});
|
|
@@ -10209,7 +10292,7 @@ async function readSub(service, id, sub, subId, options) {
|
|
|
10209
10292
|
});
|
|
10210
10293
|
if (!parent) return denied2("not_found" /* NotFound */);
|
|
10211
10294
|
const row = findElement(
|
|
10212
|
-
(0,
|
|
10295
|
+
(0, import_utils34.get)(capture ? parent : copySubdocumentParent(parent), sub),
|
|
10213
10296
|
childFilter
|
|
10214
10297
|
);
|
|
10215
10298
|
if (!row) return denied2("not_found" /* NotFound */);
|
|
@@ -10230,7 +10313,7 @@ async function updateSub(service, persist, id, sub, subId, data, options) {
|
|
|
10230
10313
|
const identity = { _id: subId };
|
|
10231
10314
|
const filter2 = await subdocumentRows(service, call.child, identity, identity, sub);
|
|
10232
10315
|
if (filter2 === false) return denied2();
|
|
10233
|
-
const row = findElement((0,
|
|
10316
|
+
const row = findElement((0, import_utils34.get)(parent, sub), filter2);
|
|
10234
10317
|
if (!row) return denied2("not_found" /* NotFound */);
|
|
10235
10318
|
const original = isolateDocForOutput(row);
|
|
10236
10319
|
const admit = await inputAdmission(service, call, parent);
|
|
@@ -10257,7 +10340,7 @@ async function bulkUpdateSub(service, persist, id, sub, data, options) {
|
|
|
10257
10340
|
const selected = { _id: { $in: data.map((row) => row._id) } };
|
|
10258
10341
|
const filter2 = await subdocumentRows(service, call.child, selected, selected, sub);
|
|
10259
10342
|
if (filter2 === false) return denied2();
|
|
10260
|
-
const rows2 = filterCollection((0,
|
|
10343
|
+
const rows2 = filterCollection((0, import_utils34.get)(parent, sub), filter2);
|
|
10261
10344
|
const originals = rows2.map((row) => isolateDocForOutput(row));
|
|
10262
10345
|
const admit = await inputAdmission(service, call, parent);
|
|
10263
10346
|
for (const [index, row] of rows2.entries()) {
|
|
@@ -10286,7 +10369,7 @@ async function createSub(service, persist, id, sub, data, options) {
|
|
|
10286
10369
|
const lookup = await mutationParent(service, id, call);
|
|
10287
10370
|
if ("error" in lookup) return lookup.error;
|
|
10288
10371
|
const { parent } = lookup;
|
|
10289
|
-
const rows2 = (0,
|
|
10372
|
+
const rows2 = (0, import_utils34.get)(parent, sub);
|
|
10290
10373
|
const admit = await inputAdmission(service, call, parent);
|
|
10291
10374
|
const allowed = (Array.isArray(data) ? data : [data]).map((row) => admit(row).allowedData);
|
|
10292
10375
|
if (addFirst) rows2.unshift(...allowed);
|
|
@@ -10307,7 +10390,7 @@ async function deleteSub(service, persist, id, sub, subId, options) {
|
|
|
10307
10390
|
const identity = { _id: subId };
|
|
10308
10391
|
const filter2 = await subdocumentRows(service, call.child, identity, identity, sub);
|
|
10309
10392
|
if (filter2 === false) return denied2();
|
|
10310
|
-
const row = findElement((0,
|
|
10393
|
+
const row = findElement((0, import_utils34.get)(parent, sub), filter2);
|
|
10311
10394
|
if (!row) return denied2("not_found" /* NotFound */);
|
|
10312
10395
|
await ("deleteOne" in row ? row.deleteOne?.() : row.remove?.());
|
|
10313
10396
|
await persist(() => parent.save());
|
|
@@ -10369,10 +10452,12 @@ var Service = class extends Base {
|
|
|
10369
10452
|
model: this.model.mongooseModel,
|
|
10370
10453
|
modelName: this.modelName
|
|
10371
10454
|
}),
|
|
10372
|
-
configuration: () => this.requestRuntime.getModelInstance(this.modelName) ? captureModelAuthorizationConfiguration(
|
|
10373
|
-
|
|
10374
|
-
|
|
10375
|
-
|
|
10455
|
+
configuration: () => this.requestRuntime.getModelInstance(this.modelName) ? captureModelAuthorizationConfiguration(
|
|
10456
|
+
this.requestRuntime,
|
|
10457
|
+
this.modelName,
|
|
10458
|
+
{ ...this.options, defaults: this.defaults },
|
|
10459
|
+
modelServiceGlobalOptions(this, this.requestRuntime)
|
|
10460
|
+
) : { catalog: { paths: [] }, ...this.options },
|
|
10376
10461
|
permissions: () => this.requestCore.getPermissions?.() ?? new permission_default({}),
|
|
10377
10462
|
parse: (filter2) => this.parseClientData(filter2, this.getCorrelatedExecState().scheduler),
|
|
10378
10463
|
validate: (filter2, expanded) => {
|
|
@@ -10619,20 +10704,20 @@ var Service = class extends Base {
|
|
|
10619
10704
|
const field = configuration.documentPermissionField ?? "_permissions";
|
|
10620
10705
|
unsetDocPath(output, field);
|
|
10621
10706
|
if (!configuration.stripPermissionsField) {
|
|
10622
|
-
(0,
|
|
10707
|
+
(0, import_utils35.set)(output, field, args.includePermissions || args.includeFieldPermissions ? deepIsolateValue(grants) : {});
|
|
10623
10708
|
if (args.includeFieldPermissions && !configuration.disableFieldPermissions) {
|
|
10624
10709
|
const rowAccess = this.asServiceHookContext(context).fieldPermissionAccess ?? await this.getFieldPermissionAccess([snapshot._id]);
|
|
10625
10710
|
const id = String(snapshot._id);
|
|
10626
10711
|
const views = rowAccess.readIds?.has(id) ? await requestOutputFieldPaths(handle, binding, "read") : [];
|
|
10627
10712
|
const edits = rowAccess.updateIds?.has(id) ? await requestOutputFieldPaths(handle, binding, "update") : [];
|
|
10628
10713
|
const map2 = (paths) => paths.length ? Object.fromEntries(paths.map((path) => [path, true])) : { $: "_" };
|
|
10629
|
-
(0,
|
|
10630
|
-
(0,
|
|
10631
|
-
} else if (!args.includePermissions) (0,
|
|
10714
|
+
(0, import_utils35.set)(output, `${field}._view`, map2(views));
|
|
10715
|
+
(0, import_utils35.set)(output, `${field}._edit`, map2(edits));
|
|
10716
|
+
} else if (!args.includePermissions) (0, import_utils35.set)(output, field, { _view: { $: "_" }, _edit: { $: "_" } });
|
|
10632
10717
|
const exposed = configuration.exposedDocPermissionKeys;
|
|
10633
10718
|
if (exposed) {
|
|
10634
|
-
const metadata = (0,
|
|
10635
|
-
(0,
|
|
10719
|
+
const metadata = (0, import_utils35.get)(output, field);
|
|
10720
|
+
(0, import_utils35.set)(
|
|
10636
10721
|
output,
|
|
10637
10722
|
field,
|
|
10638
10723
|
Object.fromEntries(
|
|
@@ -10893,7 +10978,7 @@ var Service = class extends Base {
|
|
|
10893
10978
|
return docs.map((doc) => {
|
|
10894
10979
|
try {
|
|
10895
10980
|
const plain = toObject(doc);
|
|
10896
|
-
const val = (0,
|
|
10981
|
+
const val = (0, import_utils35.get)(plain, associationField);
|
|
10897
10982
|
return deepIsolateValue(val);
|
|
10898
10983
|
} catch {
|
|
10899
10984
|
return void 0;
|
|
@@ -10901,12 +10986,13 @@ var Service = class extends Base {
|
|
|
10901
10986
|
});
|
|
10902
10987
|
}
|
|
10903
10988
|
captureRelated(args, defaults) {
|
|
10989
|
+
const globalOptions = modelServiceGlobalOptions(this, this.requestRuntime);
|
|
10904
10990
|
const effective = { populate: args?.populate ?? defaults?.populate, include: args?.include ?? defaults?.include };
|
|
10905
10991
|
if (effective.include) {
|
|
10906
10992
|
const processed = this.processInclude(effective.include);
|
|
10907
10993
|
effective.include = [...processed.includes, ...processed.correlatedIncludes];
|
|
10908
10994
|
}
|
|
10909
|
-
return captureRelatedTargets(this.requestRuntime, this.modelName, effective);
|
|
10995
|
+
return captureRelatedTargets(this.requestRuntime, this.modelName, effective, 0, globalOptions);
|
|
10910
10996
|
}
|
|
10911
10997
|
/** Canonical population uses the target's retained policy for both fetch and output. */
|
|
10912
10998
|
async genExecutionPopulate(execution, access, populate) {
|
|
@@ -10928,14 +11014,9 @@ var Service = class extends Base {
|
|
|
10928
11014
|
modelPermissionPrefix: captured.configuration.modelPermissionPrefix
|
|
10929
11015
|
});
|
|
10930
11016
|
if (sourceState === "denied") continue;
|
|
10931
|
-
const
|
|
11017
|
+
const target = captured.relatedTargets.find((target2) => target2.path === descriptor.path);
|
|
11018
|
+
const modelName = target?.modelName;
|
|
10932
11019
|
if (!modelName) continue;
|
|
10933
|
-
if (!this.requestRuntime.hasModel(modelName)) {
|
|
10934
|
-
if (captured.relatedTargets.some((target) => target.path === descriptor.path && target.kind === "passthrough")) {
|
|
10935
|
-
result2.push({ path: descriptor.path, select: descriptor.select });
|
|
10936
|
-
}
|
|
10937
|
-
continue;
|
|
10938
|
-
}
|
|
10939
11020
|
const policy = relatedPolicy(state.authorization, state.binding, descriptor.path);
|
|
10940
11021
|
const svc = this.requestCore.getPublicService(modelName);
|
|
10941
11022
|
const child = createRelatedExecution(
|
|
@@ -10954,7 +11035,7 @@ var Service = class extends Base {
|
|
|
10954
11035
|
if (isExecutionRowDenied(svc, child)) continue;
|
|
10955
11036
|
const childState = readServiceExecution(svc, child);
|
|
10956
11037
|
const targetConfiguration = readServiceAuthorization(childState.authorization, childState.binding).configuration;
|
|
10957
|
-
if (policy?.operation.mode !== "grant" && !await this.hookGate.run(
|
|
11038
|
+
if (targetConfiguration.requireOperationAccessForPopulateQueries !== false && policy?.operation.mode !== "grant" && !await this.hookGate.run(
|
|
10958
11039
|
() => evaluateRouteGuard(
|
|
10959
11040
|
this.req,
|
|
10960
11041
|
getAuthorizationPermissions(childState.authorization, childState.binding),
|
|
@@ -10986,7 +11067,7 @@ var Service = class extends Base {
|
|
|
10986
11067
|
schema: childState.binding.model.schema,
|
|
10987
11068
|
configuration: targetConfiguration,
|
|
10988
11069
|
requestRead: targetAccess === "read" && policy?.operation.mode !== "grant" && readServiceAuthorization(childState.authorization, childState.binding).authorization.rows.mode === "request",
|
|
10989
|
-
staticObjectIdReference: captured.relatedTargets.find((
|
|
11070
|
+
staticObjectIdReference: captured.relatedTargets.find((target2) => target2.path === descriptor.path)?.staticObjectIdReference
|
|
10990
11071
|
}
|
|
10991
11072
|
});
|
|
10992
11073
|
result2.push(ret);
|
|
@@ -11006,7 +11087,7 @@ var Service = class extends Base {
|
|
|
11006
11087
|
if (this.isScalarPopulateValue(rawTarget)) return rawTarget;
|
|
11007
11088
|
const isDoc = (() => {
|
|
11008
11089
|
try {
|
|
11009
|
-
if ((0,
|
|
11090
|
+
if ((0, import_utils35.isPlainObject)(rawTarget)) return true;
|
|
11010
11091
|
const maybe = rawTarget;
|
|
11011
11092
|
if (maybe && typeof maybe === "object" && "_doc" in maybe) return true;
|
|
11012
11093
|
if (maybe && typeof maybe.toObject === "function") return true;
|
|
@@ -11030,15 +11111,13 @@ var Service = class extends Base {
|
|
|
11030
11111
|
transferDocumentAuthorizationGraph(source, copy2);
|
|
11031
11112
|
return copy2;
|
|
11032
11113
|
}
|
|
11033
|
-
let targetMongooseModel;
|
|
11034
|
-
|
|
11035
|
-
|
|
11036
|
-
meta.targetModelName
|
|
11037
|
-
|
|
11038
|
-
|
|
11039
|
-
|
|
11040
|
-
} catch {
|
|
11041
|
-
targetMongooseModel = parentContext.mongooseModel;
|
|
11114
|
+
let targetMongooseModel = meta.fetchBinding?.model;
|
|
11115
|
+
if (!targetMongooseModel) {
|
|
11116
|
+
try {
|
|
11117
|
+
targetMongooseModel = this.requestRuntime.getModelInstance(meta.targetModelName);
|
|
11118
|
+
} catch {
|
|
11119
|
+
targetMongooseModel = parentContext.mongooseModel;
|
|
11120
|
+
}
|
|
11042
11121
|
}
|
|
11043
11122
|
const targetContext = {
|
|
11044
11123
|
mongooseModel: targetMongooseModel ?? parentContext.mongooseModel,
|
|
@@ -11096,7 +11175,7 @@ var Service = class extends Base {
|
|
|
11096
11175
|
child = getDocValue(current, key);
|
|
11097
11176
|
if (child === void 0) {
|
|
11098
11177
|
try {
|
|
11099
|
-
child = (0,
|
|
11178
|
+
child = (0, import_utils35.get)(current, key);
|
|
11100
11179
|
} catch {
|
|
11101
11180
|
return;
|
|
11102
11181
|
}
|
|
@@ -11331,7 +11410,7 @@ var Service = class extends Base {
|
|
|
11331
11410
|
originalDocumentSnapshot: toObject(doc),
|
|
11332
11411
|
resolvedQuery: query
|
|
11333
11412
|
};
|
|
11334
|
-
const correlatedSnapshots = [(0,
|
|
11413
|
+
const correlatedSnapshots = [(0, import_utils35.cloneDeep)(toObject(doc))];
|
|
11335
11414
|
try {
|
|
11336
11415
|
doc = await this.includeDocs(doc, includes, state.authorization);
|
|
11337
11416
|
if (correlatedIncludes.length > 0) {
|
|
@@ -11513,7 +11592,7 @@ var Service = class extends Base {
|
|
|
11513
11592
|
const findAssociationField = this.getAssociationFieldFromOptions(options);
|
|
11514
11593
|
const withAssocSelect = findAssociationField && !finalSelect.includes(findAssociationField) ? [...finalSelect, findAssociationField] : finalSelect;
|
|
11515
11594
|
const dbSelect = this.buildDbSelectForAssociation(withAssocSelect, findAssociationField);
|
|
11516
|
-
const filteredPopulate = (0,
|
|
11595
|
+
const filteredPopulate = (0, import_utils35.isArray)(withAssocSelect) && (0, import_utils35.isArray)(_populate) ? _populate.filter(
|
|
11517
11596
|
(p) => [
|
|
11518
11597
|
...virtualPlan.publicPersistedFetchSelection,
|
|
11519
11598
|
...findAssociationField ? [findAssociationField] : []
|
|
@@ -11573,7 +11652,7 @@ var Service = class extends Base {
|
|
|
11573
11652
|
findAssociationField ? [findAssociationField] : []
|
|
11574
11653
|
);
|
|
11575
11654
|
const capturedAssociation = findAssociationField ? this.captureAssociationValues(docs, findAssociationField) : void 0;
|
|
11576
|
-
const correlatedSnapshots = docs.map((doc) => (0,
|
|
11655
|
+
const correlatedSnapshots = docs.map((doc) => (0, import_utils35.cloneDeep)(toObject(doc)));
|
|
11577
11656
|
try {
|
|
11578
11657
|
docs = await this.includeDocs(docs, includes, state.authorization);
|
|
11579
11658
|
if (correlatedIncludes.length > 0) {
|
|
@@ -11772,12 +11851,12 @@ var Service = class extends Base {
|
|
|
11772
11851
|
context.allowedFields = allowedFields;
|
|
11773
11852
|
context.allowedData = allowedData;
|
|
11774
11853
|
const validated = await this.validate(allowedData, "create", context);
|
|
11775
|
-
if ((0,
|
|
11854
|
+
if ((0, import_utils35.isBoolean)(validated)) {
|
|
11776
11855
|
if (!validated) {
|
|
11777
11856
|
validationErrors.push({ index, errors: [] });
|
|
11778
11857
|
return void 0;
|
|
11779
11858
|
}
|
|
11780
|
-
} else if ((0,
|
|
11859
|
+
} else if ((0, import_utils35.isArray)(validated)) {
|
|
11781
11860
|
if (validated.length > 0) {
|
|
11782
11861
|
validationErrors.push({
|
|
11783
11862
|
index,
|
|
@@ -11988,7 +12067,7 @@ var Service = class extends Base {
|
|
|
11988
12067
|
}
|
|
11989
12068
|
let doc = await this.model.findOne({
|
|
11990
12069
|
filter: _filter,
|
|
11991
|
-
select: (0,
|
|
12070
|
+
select: (0, import_utils35.uniq)([...updatePlan.persistedFetchSelection, ...inputFetchPaths(captured.configuration.catalog)]).map(
|
|
11992
12071
|
(path) => `+${path}`
|
|
11993
12072
|
)
|
|
11994
12073
|
});
|
|
@@ -12027,12 +12106,12 @@ var Service = class extends Base {
|
|
|
12027
12106
|
context.allowedFields = allowedFields;
|
|
12028
12107
|
context.allowedData = allowedData;
|
|
12029
12108
|
const validated = await this.validate(allowedData, "update", context);
|
|
12030
|
-
if ((0,
|
|
12109
|
+
if ((0, import_utils35.isBoolean)(validated)) {
|
|
12031
12110
|
if (!validated) {
|
|
12032
12111
|
this.completeOp("updateOne", startedAt, "bad_request" /* BadRequest */, _filter);
|
|
12033
12112
|
return { success: false, kind: "error", code: "bad_request" /* BadRequest */ };
|
|
12034
12113
|
}
|
|
12035
|
-
} else if ((0,
|
|
12114
|
+
} else if ((0, import_utils35.isArray)(validated)) {
|
|
12036
12115
|
if (validated.length > 0) {
|
|
12037
12116
|
this.completeOp("updateOne", startedAt, "bad_request" /* BadRequest */, _filter);
|
|
12038
12117
|
return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: validated };
|
|
@@ -12052,10 +12131,10 @@ var Service = class extends Base {
|
|
|
12052
12131
|
const diffExcludeFields = [this.options.documentPermissionField, "__v"];
|
|
12053
12132
|
this.asServiceHookContext(context).diff = (d) => {
|
|
12054
12133
|
context.changes = (0, import_just_diff.diff)(
|
|
12055
|
-
(0,
|
|
12056
|
-
(0,
|
|
12134
|
+
(0, import_utils35.omit)(context.originalDocumentSnapshot, diffExcludeFields),
|
|
12135
|
+
(0, import_utils35.omit)(d.toObject({ virtuals: false }), diffExcludeFields)
|
|
12057
12136
|
) || [];
|
|
12058
|
-
context.modifiedPaths = (0,
|
|
12137
|
+
context.modifiedPaths = (0, import_utils35.uniq)(context.changes.map((di) => di.path.length > 0 ? String(di.path[0]) : ""));
|
|
12059
12138
|
};
|
|
12060
12139
|
doc = assertModelDocument(await this.afterPersist(doc, "update", context), this.modelName, "afterPersist");
|
|
12061
12140
|
context.currentDocument = doc;
|
|
@@ -12143,7 +12222,7 @@ var Service = class extends Base {
|
|
|
12143
12222
|
const upsertOptions = this.resolveUpsertOptions(options);
|
|
12144
12223
|
const updateIntent = captureModelServiceIntent(this, "updateOne", upsertArgs, upsertOptions);
|
|
12145
12224
|
const createIntent = captureModelServiceIntent(this, "create", upsertArgs, upsertOptions);
|
|
12146
|
-
const related = (0,
|
|
12225
|
+
const related = (0, import_utils35.uniqBy)(
|
|
12147
12226
|
[...this.captureRelated(updateIntent.args), ...this.captureRelated(createIntent.args)],
|
|
12148
12227
|
(target) => target.path
|
|
12149
12228
|
);
|
|
@@ -12584,7 +12663,7 @@ var Service = class extends Base {
|
|
|
12584
12663
|
return resolveExistsOptions(this, options);
|
|
12585
12664
|
}
|
|
12586
12665
|
async getFieldPermissionAccess(ids) {
|
|
12587
|
-
const uniqueIds = (0,
|
|
12666
|
+
const uniqueIds = (0, import_utils35.compact)((0, import_utils35.uniqBy)(ids, (id) => String(id)).map((id) => String(id)));
|
|
12588
12667
|
if (uniqueIds.length === 0) {
|
|
12589
12668
|
return {
|
|
12590
12669
|
readIds: /* @__PURE__ */ new Set(),
|
|
@@ -12630,7 +12709,7 @@ var Service = class extends Base {
|
|
|
12630
12709
|
* (direct/root-entry 200); count measures visible rows, not all updated rows.
|
|
12631
12710
|
*/
|
|
12632
12711
|
async bulkUpdateSub(id, sub, data, options) {
|
|
12633
|
-
return bulkUpdateSub(this, this.persist, id, sub, (0,
|
|
12712
|
+
return bulkUpdateSub(this, this.persist, id, sub, (0, import_utils35.castArray)(data), options);
|
|
12634
12713
|
}
|
|
12635
12714
|
/**
|
|
12636
12715
|
* Append/prepend admitted rows, then return the visible full array (including when
|
|
@@ -12654,7 +12733,7 @@ var Service = class extends Base {
|
|
|
12654
12733
|
};
|
|
12655
12734
|
|
|
12656
12735
|
// src/services/public-service.ts
|
|
12657
|
-
var
|
|
12736
|
+
var import_utils36 = require("@web-ts-toolkit/utils");
|
|
12658
12737
|
init_helpers();
|
|
12659
12738
|
init_permissions_alias();
|
|
12660
12739
|
init_document();
|
|
@@ -12780,7 +12859,7 @@ var PublicService = class extends Service {
|
|
|
12780
12859
|
let d = toObject(doc);
|
|
12781
12860
|
d = await this.decorate(d, "create", context);
|
|
12782
12861
|
d = this.runTasks(d, tasks);
|
|
12783
|
-
if (select) d = copyPermissionsAlias(d, (0,
|
|
12862
|
+
if (select) d = copyPermissionsAlias(d, (0, import_utils36.pick)(d, [...normalizeSelect(select), ...this.baseFieldsExt]));
|
|
12784
12863
|
return d;
|
|
12785
12864
|
}
|
|
12786
12865
|
);
|
|
@@ -12999,8 +13078,8 @@ var PublicService = class extends Service {
|
|
|
12999
13078
|
let d = toObject(doc);
|
|
13000
13079
|
d = await this.decorate(d, "update", context);
|
|
13001
13080
|
d = this.runTasks(d, tasks);
|
|
13002
|
-
if (select) d = copyPermissionsAlias(d, (0,
|
|
13003
|
-
else if (!returningAll) d = copyPermissionsAlias(d, (0,
|
|
13081
|
+
if (select) d = copyPermissionsAlias(d, (0, import_utils36.pick)(d, [...normalizeSelect(select), ...this.baseFieldsExt]));
|
|
13082
|
+
else if (!returningAll) d = copyPermissionsAlias(d, (0, import_utils36.pick)(d, returningKeys));
|
|
13004
13083
|
return d;
|
|
13005
13084
|
}
|
|
13006
13085
|
);
|
|
@@ -13083,8 +13162,8 @@ var PublicService = class extends Service {
|
|
|
13083
13162
|
let d = toObject(doc);
|
|
13084
13163
|
d = await this.decorate(d, "update", context);
|
|
13085
13164
|
d = this.runTasks(d, tasks2);
|
|
13086
|
-
if (select) d = copyPermissionsAlias(d, (0,
|
|
13087
|
-
else if (!returningAll) d = copyPermissionsAlias(d, (0,
|
|
13165
|
+
if (select) d = copyPermissionsAlias(d, (0, import_utils36.pick)(d, [...normalizeSelect(select), ...this.baseFieldsExt]));
|
|
13166
|
+
else if (!returningAll) d = copyPermissionsAlias(d, (0, import_utils36.pick)(d, returningKeys));
|
|
13088
13167
|
return d;
|
|
13089
13168
|
}
|
|
13090
13169
|
);
|
|
@@ -13109,7 +13188,7 @@ var PublicService = class extends Service {
|
|
|
13109
13188
|
d = await this.decorate(d, "create", context);
|
|
13110
13189
|
d = this.runTasks(d, tasks);
|
|
13111
13190
|
if (createSelect)
|
|
13112
|
-
d = copyPermissionsAlias(d, (0,
|
|
13191
|
+
d = copyPermissionsAlias(d, (0, import_utils36.pick)(d, [...normalizeSelect(createSelect), ...this.baseFieldsExt]));
|
|
13113
13192
|
return d;
|
|
13114
13193
|
}
|
|
13115
13194
|
);
|
|
@@ -13254,7 +13333,7 @@ var PublicService = class extends Service {
|
|
|
13254
13333
|
init_options();
|
|
13255
13334
|
init_data_values();
|
|
13256
13335
|
init_helpers();
|
|
13257
|
-
var
|
|
13336
|
+
var import_utils37 = require("@web-ts-toolkit/utils");
|
|
13258
13337
|
init_request_complexity();
|
|
13259
13338
|
init_runtime_context();
|
|
13260
13339
|
init_runtime();
|
|
@@ -13283,7 +13362,7 @@ var DataService = class {
|
|
|
13283
13362
|
let doc = await findElement(this.data, _filter);
|
|
13284
13363
|
if (!doc) return { success: false, kind: "error", code: "not_found" /* NotFound */, query };
|
|
13285
13364
|
doc = await this.trimOutputFields(doc, access);
|
|
13286
|
-
if (_select.length > 0) doc = (0,
|
|
13365
|
+
if (_select.length > 0) doc = (0, import_utils37.pick)(doc, _select);
|
|
13287
13366
|
return {
|
|
13288
13367
|
success: true,
|
|
13289
13368
|
kind: "single",
|
|
@@ -13329,13 +13408,13 @@ var DataService = class {
|
|
|
13329
13408
|
const totalCount = docs.length;
|
|
13330
13409
|
if (sort) {
|
|
13331
13410
|
const normalizedSort = normalizeSortForOrderBy(sort);
|
|
13332
|
-
docs = (0,
|
|
13411
|
+
docs = (0, import_utils37.orderBy)(docs, normalizedSort.fields, normalizedSort.orders);
|
|
13333
13412
|
}
|
|
13334
13413
|
const pagedDocs = docs.slice(query.skip, query.limit && query.skip + query.limit);
|
|
13335
13414
|
const { maxHookConcurrency } = this.getRequestComplexity();
|
|
13336
13415
|
const trimmed = await mapWithConcurrencyLimit(pagedDocs, maxHookConcurrency, async (doc) => {
|
|
13337
13416
|
doc = await this.trimOutputFields(doc, "list");
|
|
13338
|
-
if (_select.length > 0) doc = (0,
|
|
13417
|
+
if (_select.length > 0) doc = (0, import_utils37.pick)(doc, _select);
|
|
13339
13418
|
return copyDataValue(doc);
|
|
13340
13419
|
});
|
|
13341
13420
|
if (!hasExplicitLimit && trimmed.length === totalCount) {
|
|
@@ -13410,10 +13489,10 @@ var DataService = class {
|
|
|
13410
13489
|
init_helpers();
|
|
13411
13490
|
|
|
13412
13491
|
// src/processors.ts
|
|
13413
|
-
var
|
|
13492
|
+
var import_utils38 = require("@web-ts-toolkit/utils");
|
|
13414
13493
|
init_permissions_alias();
|
|
13415
13494
|
function cloneProcessorValue(value) {
|
|
13416
|
-
const copy = (0,
|
|
13495
|
+
const copy = (0, import_utils38.cloneDeep)(value);
|
|
13417
13496
|
copyPermissionsAliasGraph(value, copy);
|
|
13418
13497
|
return copy;
|
|
13419
13498
|
}
|
|
@@ -13451,10 +13530,10 @@ function resolveLeafParents(obj, src) {
|
|
|
13451
13530
|
for (let ind = 0; ind < segs.length - 1; ind += 1) {
|
|
13452
13531
|
const seg = segs[ind];
|
|
13453
13532
|
targets = targets.reduce((ret, target) => {
|
|
13454
|
-
if (!(0,
|
|
13533
|
+
if (!(0, import_utils38.isPlainObject)(target)) return ret;
|
|
13455
13534
|
const targetObject = target;
|
|
13456
13535
|
const next = targetObject[seg];
|
|
13457
|
-
if ((0,
|
|
13536
|
+
if ((0, import_utils38.isArray)(next)) {
|
|
13458
13537
|
for (const item of next) {
|
|
13459
13538
|
ret.push(item);
|
|
13460
13539
|
}
|
|
@@ -13464,8 +13543,8 @@ function resolveLeafParents(obj, src) {
|
|
|
13464
13543
|
}
|
|
13465
13544
|
const leaf = segs[segs.length - 1];
|
|
13466
13545
|
const pairs = [];
|
|
13467
|
-
(0,
|
|
13468
|
-
if (!(0,
|
|
13546
|
+
(0, import_utils38.forEach)(targets, (target) => {
|
|
13547
|
+
if (!(0, import_utils38.isPlainObject)(target)) return;
|
|
13469
13548
|
pairs.push({ parent: target, leaf });
|
|
13470
13549
|
});
|
|
13471
13550
|
return pairs;
|
|
@@ -13474,7 +13553,7 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
13474
13553
|
const mutable = options.mutable !== false;
|
|
13475
13554
|
const idField = options.idField ?? "_id";
|
|
13476
13555
|
const obj = mutable ? docObject : cloneProcessorValue(docObject);
|
|
13477
|
-
(0,
|
|
13556
|
+
(0, import_utils38.forEach)(Array.isArray(operations) ? operations : [], (op) => {
|
|
13478
13557
|
if (!op || typeof op.src !== "string" || typeof op.dest !== "string") return;
|
|
13479
13558
|
const src = op.src;
|
|
13480
13559
|
const dest = op.dest;
|
|
@@ -13483,19 +13562,19 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
13483
13562
|
assertSafePath(dest);
|
|
13484
13563
|
let targets = [obj];
|
|
13485
13564
|
const segs = src.split(".");
|
|
13486
|
-
(0,
|
|
13565
|
+
(0, import_utils38.forEach)(segs, (seg, ind) => {
|
|
13487
13566
|
if (segs.length === ind + 1) {
|
|
13488
|
-
(0,
|
|
13489
|
-
if (!(0,
|
|
13567
|
+
(0, import_utils38.forEach)(targets, (target) => {
|
|
13568
|
+
if (!(0, import_utils38.isPlainObject)(target)) return;
|
|
13490
13569
|
const targetObject = target;
|
|
13491
13570
|
const leaf = targetObject[seg];
|
|
13492
13571
|
const sourceForDest = leaf;
|
|
13493
13572
|
let depopulated;
|
|
13494
|
-
if ((0,
|
|
13573
|
+
if ((0, import_utils38.isArray)(leaf)) {
|
|
13495
13574
|
if (leaf.length === 0) {
|
|
13496
13575
|
depopulated = [];
|
|
13497
|
-
} else if (leaf.every((item) => (0,
|
|
13498
|
-
depopulated = (0,
|
|
13576
|
+
} else if (leaf.every((item) => (0, import_utils38.isPlainObject)(item))) {
|
|
13577
|
+
depopulated = (0, import_utils38.map)(leaf, idField).map((id, i) => {
|
|
13499
13578
|
if (id === void 0) {
|
|
13500
13579
|
failMissingId(`${src}[${i}]`);
|
|
13501
13580
|
}
|
|
@@ -13504,8 +13583,8 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
13504
13583
|
} else {
|
|
13505
13584
|
return;
|
|
13506
13585
|
}
|
|
13507
|
-
} else if ((0,
|
|
13508
|
-
const id = (0,
|
|
13586
|
+
} else if ((0, import_utils38.isPlainObject)(leaf)) {
|
|
13587
|
+
const id = (0, import_utils38.get)(leaf, idField);
|
|
13509
13588
|
if (id === void 0) {
|
|
13510
13589
|
failMissingId(src);
|
|
13511
13590
|
}
|
|
@@ -13513,15 +13592,15 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
13513
13592
|
} else {
|
|
13514
13593
|
return;
|
|
13515
13594
|
}
|
|
13516
|
-
(0,
|
|
13517
|
-
(0,
|
|
13595
|
+
(0, import_utils38.set)(targetObject, dest, sourceForDest);
|
|
13596
|
+
(0, import_utils38.set)(targetObject, seg, depopulated);
|
|
13518
13597
|
});
|
|
13519
13598
|
} else {
|
|
13520
13599
|
targets = targets.reduce((ret, target) => {
|
|
13521
|
-
if (!(0,
|
|
13600
|
+
if (!(0, import_utils38.isPlainObject)(target)) return ret;
|
|
13522
13601
|
const targetObject = target;
|
|
13523
13602
|
const next = targetObject[seg];
|
|
13524
|
-
if ((0,
|
|
13603
|
+
if ((0, import_utils38.isArray)(next)) {
|
|
13525
13604
|
for (const item of next) {
|
|
13526
13605
|
ret.push(item);
|
|
13527
13606
|
}
|
|
@@ -13536,7 +13615,7 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
13536
13615
|
var copyPaths = (docObject, operations, options = { mutable: true }) => {
|
|
13537
13616
|
const mutable = options.mutable !== false;
|
|
13538
13617
|
const obj = mutable ? docObject : cloneProcessorValue(docObject);
|
|
13539
|
-
(0,
|
|
13618
|
+
(0, import_utils38.forEach)(Array.isArray(operations) ? operations : [], (op) => {
|
|
13540
13619
|
if (!op || typeof op.src !== "string" || typeof op.dest !== "string") return;
|
|
13541
13620
|
const src = op.src;
|
|
13542
13621
|
const dest = op.dest;
|
|
@@ -13544,9 +13623,9 @@ var copyPaths = (docObject, operations, options = { mutable: true }) => {
|
|
|
13544
13623
|
assertSafePath(src, "copyPaths");
|
|
13545
13624
|
assertSafePath(dest, "copyPaths");
|
|
13546
13625
|
if (src === dest) return;
|
|
13547
|
-
(0,
|
|
13548
|
-
if (!(0,
|
|
13549
|
-
(0,
|
|
13626
|
+
(0, import_utils38.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
|
|
13627
|
+
if (!(0, import_utils38.hasOwn)(parent, leaf)) return;
|
|
13628
|
+
(0, import_utils38.set)(parent, dest, cloneProcessorValue(parent[leaf]));
|
|
13550
13629
|
});
|
|
13551
13630
|
});
|
|
13552
13631
|
return obj;
|
|
@@ -13554,7 +13633,7 @@ var copyPaths = (docObject, operations, options = { mutable: true }) => {
|
|
|
13554
13633
|
var movePaths = (docObject, operations, options = { mutable: true }) => {
|
|
13555
13634
|
const mutable = options.mutable !== false;
|
|
13556
13635
|
const obj = mutable ? docObject : cloneProcessorValue(docObject);
|
|
13557
|
-
(0,
|
|
13636
|
+
(0, import_utils38.forEach)(Array.isArray(operations) ? operations : [], (op) => {
|
|
13558
13637
|
if (!op || typeof op.src !== "string" || typeof op.dest !== "string") return;
|
|
13559
13638
|
const src = op.src;
|
|
13560
13639
|
const dest = op.dest;
|
|
@@ -13562,10 +13641,10 @@ var movePaths = (docObject, operations, options = { mutable: true }) => {
|
|
|
13562
13641
|
assertSafePath(src, "movePaths");
|
|
13563
13642
|
assertSafePath(dest, "movePaths");
|
|
13564
13643
|
if (src === dest) return;
|
|
13565
|
-
(0,
|
|
13566
|
-
if (!(0,
|
|
13644
|
+
(0, import_utils38.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
|
|
13645
|
+
if (!(0, import_utils38.hasOwn)(parent, leaf)) return;
|
|
13567
13646
|
const value = cloneProcessorValue(parent[leaf]);
|
|
13568
|
-
(0,
|
|
13647
|
+
(0, import_utils38.set)(parent, dest, value);
|
|
13569
13648
|
if (dest === leaf || dest.startsWith(`${leaf}.`)) return;
|
|
13570
13649
|
delete parent[leaf];
|
|
13571
13650
|
});
|
|
@@ -13577,7 +13656,7 @@ var sliceArrays = (docObject, operations, options = { mutable: true, maxSlice: D
|
|
|
13577
13656
|
const maxSlice = options.maxSlice ?? DEFAULT_MAX_SLICE;
|
|
13578
13657
|
assertNonNegativeSafeInteger(maxSlice, "maxSlice", "sliceArrays");
|
|
13579
13658
|
const obj = mutable ? docObject : cloneProcessorValue(docObject);
|
|
13580
|
-
(0,
|
|
13659
|
+
(0, import_utils38.forEach)(Array.isArray(operations) ? operations : [], (op) => {
|
|
13581
13660
|
if (!op || typeof op.src !== "string") return;
|
|
13582
13661
|
const src = op.src;
|
|
13583
13662
|
if (src.length === 0) return;
|
|
@@ -13594,15 +13673,15 @@ var sliceArrays = (docObject, operations, options = { mutable: true, maxSlice: D
|
|
|
13594
13673
|
assertNonNegativeSafeInteger(op.limit, "limit", "sliceArrays");
|
|
13595
13674
|
limit = Math.min(op.limit, maxSlice);
|
|
13596
13675
|
}
|
|
13597
|
-
(0,
|
|
13676
|
+
(0, import_utils38.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
|
|
13598
13677
|
const leafValue = parent[leaf];
|
|
13599
|
-
if (!(0,
|
|
13678
|
+
if (!(0, import_utils38.isArray)(leafValue)) return;
|
|
13600
13679
|
const end = typeof limit === "undefined" ? void 0 : skip + limit;
|
|
13601
13680
|
const window = leafValue.slice(skip, end);
|
|
13602
13681
|
if (typeof rawDest === "undefined") {
|
|
13603
|
-
(0,
|
|
13682
|
+
(0, import_utils38.set)(parent, leaf, window);
|
|
13604
13683
|
} else {
|
|
13605
|
-
(0,
|
|
13684
|
+
(0, import_utils38.set)(parent, rawDest, window);
|
|
13606
13685
|
}
|
|
13607
13686
|
});
|
|
13608
13687
|
});
|
|
@@ -13611,27 +13690,27 @@ var sliceArrays = (docObject, operations, options = { mutable: true, maxSlice: D
|
|
|
13611
13690
|
var countPaths = (docObject, operations, options = { mutable: true }) => {
|
|
13612
13691
|
const mutable = options.mutable !== false;
|
|
13613
13692
|
const obj = mutable ? docObject : cloneProcessorValue(docObject);
|
|
13614
|
-
(0,
|
|
13693
|
+
(0, import_utils38.forEach)(Array.isArray(operations) ? operations : [], (op) => {
|
|
13615
13694
|
if (!op || typeof op.src !== "string" || typeof op.dest !== "string") return;
|
|
13616
13695
|
const src = op.src;
|
|
13617
13696
|
const dest = op.dest;
|
|
13618
13697
|
if (src.length === 0 || dest.length === 0) return;
|
|
13619
13698
|
assertSafePath(src, "countPaths");
|
|
13620
13699
|
assertSafePath(dest, "countPaths");
|
|
13621
|
-
(0,
|
|
13622
|
-
if (!(0,
|
|
13700
|
+
(0, import_utils38.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
|
|
13701
|
+
if (!(0, import_utils38.hasOwn)(parent, leaf)) return;
|
|
13623
13702
|
const leafValue = parent[leaf];
|
|
13624
13703
|
let count;
|
|
13625
|
-
if ((0,
|
|
13704
|
+
if ((0, import_utils38.isArray)(leafValue)) {
|
|
13626
13705
|
count = leafValue.length;
|
|
13627
|
-
} else if ((0,
|
|
13706
|
+
} else if ((0, import_utils38.isPlainObject)(leafValue)) {
|
|
13628
13707
|
count = Object.keys(leafValue).length;
|
|
13629
13708
|
} else if (leafValue === null || typeof leafValue === "undefined") {
|
|
13630
13709
|
count = 0;
|
|
13631
13710
|
} else {
|
|
13632
13711
|
count = 1;
|
|
13633
13712
|
}
|
|
13634
|
-
(0,
|
|
13713
|
+
(0, import_utils38.set)(parent, dest, count);
|
|
13635
13714
|
});
|
|
13636
13715
|
});
|
|
13637
13716
|
return obj;
|
|
@@ -13639,15 +13718,15 @@ var countPaths = (docObject, operations, options = { mutable: true }) => {
|
|
|
13639
13718
|
var maskPaths = (docObject, operations, options = { mutable: true }) => {
|
|
13640
13719
|
const mutable = options.mutable !== false;
|
|
13641
13720
|
const obj = mutable ? docObject : cloneProcessorValue(docObject);
|
|
13642
|
-
(0,
|
|
13721
|
+
(0, import_utils38.forEach)(Array.isArray(operations) ? operations : [], (op) => {
|
|
13643
13722
|
if (!op || typeof op.src !== "string") return;
|
|
13644
13723
|
const src = op.src;
|
|
13645
13724
|
if (src.length === 0) return;
|
|
13646
13725
|
assertSafePath(src, "maskPaths");
|
|
13647
13726
|
const replacement = Object.prototype.hasOwnProperty.call(op, "replacement") ? op.replacement : DEFAULT_MASK_REPLACEMENT;
|
|
13648
|
-
(0,
|
|
13649
|
-
if (!(0,
|
|
13650
|
-
(0,
|
|
13727
|
+
(0, import_utils38.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
|
|
13728
|
+
if (!(0, import_utils38.hasOwn)(parent, leaf)) return;
|
|
13729
|
+
(0, import_utils38.set)(parent, leaf, replacement);
|
|
13651
13730
|
});
|
|
13652
13731
|
});
|
|
13653
13732
|
return obj;
|
|
@@ -13702,6 +13781,8 @@ init_core_shared();
|
|
|
13702
13781
|
init_virtual_projection();
|
|
13703
13782
|
init_populate_target();
|
|
13704
13783
|
init_model_output_planning();
|
|
13784
|
+
init_authorization_snapshot();
|
|
13785
|
+
init_document();
|
|
13705
13786
|
init_output_field_filter();
|
|
13706
13787
|
init_request_work();
|
|
13707
13788
|
var emptyPermissionLeaf = () => ({ $: "_" });
|
|
@@ -13719,10 +13800,10 @@ var Core = class {
|
|
|
13719
13800
|
getIdentifier(modelName) {
|
|
13720
13801
|
const resolveIdFilter = getModelOption(modelName, "resolveIdFilter");
|
|
13721
13802
|
const idField = getModelOption(modelName, "idField");
|
|
13722
|
-
if ((0,
|
|
13803
|
+
if ((0, import_utils39.isFunction)(resolveIdFilter)) {
|
|
13723
13804
|
return null;
|
|
13724
13805
|
}
|
|
13725
|
-
if ((0,
|
|
13806
|
+
if ((0, import_utils39.isString)(idField)) {
|
|
13726
13807
|
return idField;
|
|
13727
13808
|
}
|
|
13728
13809
|
return "_id";
|
|
@@ -13812,17 +13893,11 @@ var Core = class {
|
|
|
13812
13893
|
return this.genSelect(modelName, access, targetFields, options);
|
|
13813
13894
|
}
|
|
13814
13895
|
/** Persisted request-only populate admission; fetch planning is not field authority. */
|
|
13815
|
-
async requestPopulateSelect(
|
|
13896
|
+
async requestPopulateSelect(configuration, permissions, access, targetFields = null, scopePath = []) {
|
|
13816
13897
|
const subPaths = scopePath.flatMap((part) => [part, "sub"]);
|
|
13817
|
-
const permissionSchema =
|
|
13818
|
-
const
|
|
13819
|
-
|
|
13820
|
-
try {
|
|
13821
|
-
const runtime = getActiveRuntime() ?? defaultRuntime;
|
|
13822
|
-
virtualNames = runtime.getVirtualNames(modelName, subPaths);
|
|
13823
|
-
} catch {
|
|
13824
|
-
virtualNames = [];
|
|
13825
|
-
}
|
|
13898
|
+
const permissionSchema = (0, import_utils39.get)(configuration, ["permissionSchema", ...subPaths]);
|
|
13899
|
+
const prefix = scopePath.length ? `${scopePath.join(".")}.` : "";
|
|
13900
|
+
const virtualNames = (configuration.catalog.virtualPaths ?? []).filter((path) => path.startsWith(prefix)).map((path) => path.slice(prefix.length)).filter((path) => !path.includes("."));
|
|
13826
13901
|
return resolveSelectForRequest({
|
|
13827
13902
|
req: this.req,
|
|
13828
13903
|
permissionSchema,
|
|
@@ -13841,17 +13916,25 @@ var Core = class {
|
|
|
13841
13916
|
assertPublicAdmission(_populate, "populate");
|
|
13842
13917
|
assertPopulateAccess(access);
|
|
13843
13918
|
if (!_populate) return [];
|
|
13844
|
-
|
|
13845
|
-
for (const p of
|
|
13846
|
-
if (!(0,
|
|
13847
|
-
}
|
|
13848
|
-
|
|
13919
|
+
const descriptors = copyAuthorizationValue(Array.isArray(_populate) ? _populate : [_populate], true);
|
|
13920
|
+
for (const p of descriptors) {
|
|
13921
|
+
if (!(0, import_utils39.isString)(p)) assertPopulateAccess(p.access);
|
|
13922
|
+
}
|
|
13923
|
+
const runtime = this.requestRuntime;
|
|
13924
|
+
const globalOptions = modelServiceGlobalOptions(this, runtime);
|
|
13925
|
+
const relatedTargets = captureRelatedTargets(runtime, modelName, { populate: descriptors }, 0, globalOptions);
|
|
13926
|
+
const sourceConfiguration = captureModelAuthorizationConfiguration(runtime, modelName, void 0, globalOptions);
|
|
13927
|
+
const originalPermissions = this.getGlobalPermissions();
|
|
13928
|
+
const permissions = new permission_default(
|
|
13929
|
+
Object.fromEntries(originalPermissions.keys.map((key) => [key, originalPermissions.has(key)]))
|
|
13930
|
+
);
|
|
13931
|
+
const populate = (0, import_utils39.compact)(
|
|
13849
13932
|
await Promise.all(
|
|
13850
|
-
|
|
13851
|
-
const populateAccess = !(0,
|
|
13933
|
+
descriptors.map(async (p) => {
|
|
13934
|
+
const populateAccess = !(0, import_utils39.isString)(p) && p.access ? p.access : access;
|
|
13852
13935
|
assertPopulateAccess(populateAccess);
|
|
13853
|
-
const originalSelect = (0,
|
|
13854
|
-
const ret = (0,
|
|
13936
|
+
const originalSelect = (0, import_utils39.isString)(p) ? void 0 : p.select;
|
|
13937
|
+
const ret = (0, import_utils39.isString)(p) ? { path: p } : {
|
|
13855
13938
|
path: p.path,
|
|
13856
13939
|
select: normalizeSelect(p.select)
|
|
13857
13940
|
};
|
|
@@ -13859,78 +13942,86 @@ var Core = class {
|
|
|
13859
13942
|
const pathForSourcePermission = scopePrefix && ret.path.startsWith(`${scopePrefix}.`) ? ret.path.slice(scopePrefix.length + 1) : ret.path;
|
|
13860
13943
|
const parentPath = pathForSourcePermission.includes(".") ? pathForSourcePermission.split(".")[0] : pathForSourcePermission;
|
|
13861
13944
|
const allowedParentPaths = await this.requestPopulateSelect(
|
|
13862
|
-
|
|
13945
|
+
sourceConfiguration,
|
|
13946
|
+
permissions,
|
|
13863
13947
|
populateAccess,
|
|
13864
13948
|
[parentPath],
|
|
13865
13949
|
scopePath
|
|
13866
13950
|
);
|
|
13867
13951
|
if (!allowedParentPaths.includes(parentPath)) return null;
|
|
13868
|
-
const
|
|
13869
|
-
if (!
|
|
13870
|
-
const
|
|
13871
|
-
|
|
13872
|
-
|
|
13873
|
-
|
|
13874
|
-
|
|
13875
|
-
|
|
13876
|
-
|
|
13877
|
-
|
|
13952
|
+
const target = relatedTargets.find((entry) => entry.path === ret.path);
|
|
13953
|
+
if (!target) return null;
|
|
13954
|
+
const refModelName = target.modelName;
|
|
13955
|
+
const targetConfiguration = target.configuration;
|
|
13956
|
+
if (targetConfiguration.requireOperationAccessForPopulateQueries !== false && !await withCapturedModelOperationGuard(
|
|
13957
|
+
this,
|
|
13958
|
+
refModelName,
|
|
13959
|
+
populateAccess,
|
|
13960
|
+
getCapturedAuthorizationOption(targetConfiguration, `operationAccess.${populateAccess}`),
|
|
13961
|
+
permissions,
|
|
13962
|
+
() => this.isAllowed(refModelName, populateAccess)
|
|
13963
|
+
)) {
|
|
13878
13964
|
return null;
|
|
13879
13965
|
}
|
|
13880
|
-
ret.select = await this.requestPopulateSelect(
|
|
13881
|
-
|
|
13882
|
-
|
|
13883
|
-
|
|
13966
|
+
ret.select = await this.requestPopulateSelect(
|
|
13967
|
+
targetConfiguration,
|
|
13968
|
+
permissions,
|
|
13969
|
+
populateAccess,
|
|
13970
|
+
ret.select
|
|
13971
|
+
);
|
|
13972
|
+
const hookInputs = resolveAlwaysSelectForAccess(
|
|
13973
|
+
targetConfiguration.alwaysSelectFields,
|
|
13974
|
+
populateAccess
|
|
13975
|
+
);
|
|
13976
|
+
ret.select = (0, import_utils39.uniq)([
|
|
13977
|
+
...ret.select,
|
|
13978
|
+
...stripVirtuals(hookInputs, [...targetConfiguration.catalog.virtualPaths ?? []])
|
|
13979
|
+
]);
|
|
13980
|
+
const match = (0, import_utils39.isString)(p) ? {} : p.match ?? {};
|
|
13981
|
+
const filter2 = await resolveAccessFilterForRequest({
|
|
13982
|
+
req: this.req,
|
|
13983
|
+
permissions,
|
|
13984
|
+
cache: this.caches.baseFilter,
|
|
13985
|
+
cacheKey: `${refModelName}_baseFilter_${populateAccess}`,
|
|
13986
|
+
access: populateAccess,
|
|
13987
|
+
filter: deepIsolateValue(match),
|
|
13988
|
+
getOption: (key) => getCapturedAuthorizationOption(targetConfiguration, key)
|
|
13989
|
+
});
|
|
13884
13990
|
if (filter2 === false) return null;
|
|
13885
|
-
ret.match = filter2;
|
|
13886
|
-
|
|
13887
|
-
|
|
13888
|
-
|
|
13889
|
-
|
|
13890
|
-
|
|
13891
|
-
|
|
13892
|
-
|
|
13893
|
-
|
|
13894
|
-
|
|
13895
|
-
|
|
13896
|
-
|
|
13897
|
-
|
|
13898
|
-
|
|
13899
|
-
|
|
13900
|
-
|
|
13901
|
-
|
|
13902
|
-
|
|
13903
|
-
|
|
13904
|
-
|
|
13905
|
-
|
|
13906
|
-
|
|
13907
|
-
|
|
13908
|
-
|
|
13909
|
-
|
|
13910
|
-
|
|
13911
|
-
|
|
13912
|
-
|
|
13913
|
-
|
|
13914
|
-
|
|
13915
|
-
|
|
13916
|
-
|
|
13917
|
-
|
|
13918
|
-
|
|
13919
|
-
(t) => t !== "-_id" && !t.includes(".sub.")
|
|
13920
|
-
);
|
|
13921
|
-
if (!merged.includes("_id")) merged.push("_id");
|
|
13922
|
-
ret.select = merged;
|
|
13923
|
-
setPopulateTargetMeta(ret, {
|
|
13924
|
-
targetModelName: refModelName,
|
|
13925
|
-
virtualAccess: planAccess,
|
|
13926
|
-
outputAccess: planAccess,
|
|
13927
|
-
docPermissionsAccess: planAccess,
|
|
13928
|
-
requestedSelect: originalSelect,
|
|
13929
|
-
plan: targetPlan,
|
|
13930
|
-
snapshot: targetSnapshot
|
|
13931
|
-
});
|
|
13932
|
-
} catch {
|
|
13933
|
-
}
|
|
13991
|
+
ret.match = deepIsolateValue(intersectFilters(match, filter2));
|
|
13992
|
+
const planAccess = populateAccess;
|
|
13993
|
+
const targetSnapshot = targetConfiguration;
|
|
13994
|
+
const targetPlan = planVirtualProjection({
|
|
13995
|
+
receivingModelName: refModelName,
|
|
13996
|
+
snapshot: {
|
|
13997
|
+
permissionSchema: targetSnapshot.permissionSchema,
|
|
13998
|
+
virtuals: targetSnapshot.virtuals,
|
|
13999
|
+
alwaysSelectFields: targetSnapshot.alwaysSelectFields,
|
|
14000
|
+
modelPermissionPrefix: targetSnapshot.modelPermissionPrefix,
|
|
14001
|
+
requireExplicitSelect: targetSnapshot.requireExplicitSelect,
|
|
14002
|
+
documentPermissionField: targetSnapshot.documentPermissionField
|
|
14003
|
+
},
|
|
14004
|
+
virtualAccess: planAccess,
|
|
14005
|
+
outputAccess: planAccess,
|
|
14006
|
+
docPermissionsAccess: planAccess,
|
|
14007
|
+
requestedSelect: originalSelect,
|
|
14008
|
+
internalFetch: { baseFields: ["_id"] },
|
|
14009
|
+
globalPermissions: permissions
|
|
14010
|
+
});
|
|
14011
|
+
const merged = (0, import_utils39.uniq)([...normalizeSelect(ret.select), ...targetPlan.virtualOnlyDeps ?? []]).filter(
|
|
14012
|
+
(t) => t !== "-_id" && !t.includes(".sub.")
|
|
14013
|
+
);
|
|
14014
|
+
if (!merged.includes("_id")) merged.push("_id");
|
|
14015
|
+
ret.select = merged;
|
|
14016
|
+
setPopulateTargetMeta(ret, {
|
|
14017
|
+
targetModelName: refModelName,
|
|
14018
|
+
virtualAccess: planAccess,
|
|
14019
|
+
outputAccess: planAccess,
|
|
14020
|
+
docPermissionsAccess: planAccess,
|
|
14021
|
+
requestedSelect: originalSelect,
|
|
14022
|
+
plan: targetPlan,
|
|
14023
|
+
snapshot: targetSnapshot
|
|
14024
|
+
});
|
|
13934
14025
|
return ret;
|
|
13935
14026
|
})
|
|
13936
14027
|
)
|
|
@@ -13939,10 +14030,10 @@ var Core = class {
|
|
|
13939
14030
|
}
|
|
13940
14031
|
async validate(modelName, allowedData, access, context) {
|
|
13941
14032
|
const validate = getModelOption(modelName, `validate.${access}`, null);
|
|
13942
|
-
if ((0,
|
|
14033
|
+
if ((0, import_utils39.isFunction)(validate)) {
|
|
13943
14034
|
const permissions = this.getGlobalPermissions();
|
|
13944
14035
|
return validate.call(this.req, allowedData, permissions, context);
|
|
13945
|
-
} else if ((0,
|
|
14036
|
+
} else if ((0, import_utils39.isBoolean)(validate) || (0, import_utils39.isArray)(validate)) {
|
|
13946
14037
|
return validate;
|
|
13947
14038
|
} else {
|
|
13948
14039
|
return true;
|
|
@@ -13967,7 +14058,7 @@ var Core = class {
|
|
|
13967
14058
|
const changeOptions = getModelOption(modelName, `onChange`, {});
|
|
13968
14059
|
for (let x = 0; x < context.modifiedPaths.length; x++) {
|
|
13969
14060
|
const mpath = context.modifiedPaths[x];
|
|
13970
|
-
if ((0,
|
|
14061
|
+
if ((0, import_utils39.isFunction)(changeOptions[mpath])) {
|
|
13971
14062
|
await changeOptions[mpath].call(
|
|
13972
14063
|
this.req,
|
|
13973
14064
|
context.originalDocumentSnapshot[mpath],
|
|
@@ -13991,7 +14082,7 @@ var Core = class {
|
|
|
13991
14082
|
async genDocPermissions(modelName, doc, access, context) {
|
|
13992
14083
|
const docPermissionsFn = getModelOption(modelName, `docPermissions.${access}`, null);
|
|
13993
14084
|
let docPermissions = {};
|
|
13994
|
-
if ((0,
|
|
14085
|
+
if ((0, import_utils39.isFunction)(docPermissionsFn)) {
|
|
13995
14086
|
const permissions = this.getGlobalPermissions();
|
|
13996
14087
|
try {
|
|
13997
14088
|
docPermissions = await getRequestWorkState(this.req, this.requestRuntime).hookGate.run(
|
|
@@ -14075,7 +14166,7 @@ var Core = class {
|
|
|
14075
14166
|
readExists ? requestFields("read") : [],
|
|
14076
14167
|
updateExists ? requestFields("update") : []
|
|
14077
14168
|
]);
|
|
14078
|
-
const viewObj = (0,
|
|
14169
|
+
const viewObj = (0, import_utils39.reduce)(
|
|
14079
14170
|
views,
|
|
14080
14171
|
(ret, view) => {
|
|
14081
14172
|
ret[view] = true;
|
|
@@ -14083,7 +14174,7 @@ var Core = class {
|
|
|
14083
14174
|
},
|
|
14084
14175
|
{}
|
|
14085
14176
|
);
|
|
14086
|
-
const editObj = (0,
|
|
14177
|
+
const editObj = (0, import_utils39.reduce)(
|
|
14087
14178
|
edits,
|
|
14088
14179
|
(ret, view) => {
|
|
14089
14180
|
ret[view] = true;
|
|
@@ -14114,9 +14205,9 @@ var Core = class {
|
|
|
14114
14205
|
});
|
|
14115
14206
|
}
|
|
14116
14207
|
runTasks(modelName, docObject, task) {
|
|
14117
|
-
const tasks = (0,
|
|
14208
|
+
const tasks = (0, import_utils39.compact)((0, import_utils39.castArray)(task));
|
|
14118
14209
|
if (tasks.length === 0) return docObject;
|
|
14119
|
-
(0,
|
|
14210
|
+
(0, import_utils39.forEach)(tasks, (task2) => {
|
|
14120
14211
|
const { type, args, options } = task2;
|
|
14121
14212
|
switch (type) {
|
|
14122
14213
|
case "COPY_AND_DEPOPULATE":
|
|
@@ -14186,9 +14277,9 @@ var Core = class {
|
|
|
14186
14277
|
}
|
|
14187
14278
|
const [, field, op] = keys2;
|
|
14188
14279
|
const subOption = getExactModelOption(modelName, `operationAccess.${access}`);
|
|
14189
|
-
if ((0,
|
|
14280
|
+
if ((0, import_utils39.isUndefined)(subOption)) {
|
|
14190
14281
|
const subFieldOption = getExactModelOption(modelName, `operationAccess.subs.${field}`);
|
|
14191
|
-
if ((0,
|
|
14282
|
+
if ((0, import_utils39.isUndefined)(subFieldOption)) {
|
|
14192
14283
|
const opOption = getModelOption(modelName, `operationAccess.${op}`);
|
|
14193
14284
|
return this.canActivate(opOption);
|
|
14194
14285
|
}
|
|
@@ -14254,25 +14345,25 @@ function guard(condition) {
|
|
|
14254
14345
|
const permissions = req[PERMISSIONS];
|
|
14255
14346
|
let cond = condition;
|
|
14256
14347
|
let phas = (key) => permissions.has(key);
|
|
14257
|
-
if ((0,
|
|
14348
|
+
if ((0, import_utils40.isPlainObject)(condition)) {
|
|
14258
14349
|
const { modelName, id, condition: _cond } = condition;
|
|
14259
14350
|
const svc = req.macl.getPublicService(modelName);
|
|
14260
14351
|
const select = getModelOption(modelName, `alwaysSelectFields.read`, void 0);
|
|
14261
|
-
let _id = (0,
|
|
14262
|
-
if ((0,
|
|
14352
|
+
let _id = (0, import_utils40.isString)(id) ? id : null;
|
|
14353
|
+
if ((0, import_utils40.isPlainObject)(id)) {
|
|
14263
14354
|
const { type = "param", key } = id;
|
|
14264
14355
|
if (type === "param") {
|
|
14265
14356
|
const paramValue = req.params[key];
|
|
14266
|
-
_id = (0,
|
|
14357
|
+
_id = (0, import_utils40.isArray)(paramValue) ? paramValue[0] ?? null : paramValue ?? null;
|
|
14267
14358
|
} else if (type === "query") {
|
|
14268
14359
|
const _qval = req.query[key];
|
|
14269
|
-
if ((0,
|
|
14360
|
+
if ((0, import_utils40.isArray)(_qval)) _id = _qval.length > 0 ? _qval[0] : null;
|
|
14270
14361
|
else _id = _qval;
|
|
14271
14362
|
} else {
|
|
14272
14363
|
_id = null;
|
|
14273
14364
|
}
|
|
14274
14365
|
}
|
|
14275
|
-
if (!(0,
|
|
14366
|
+
if (!(0, import_utils40.isString)(_id) || !_id) {
|
|
14276
14367
|
return next(new import_express_json_router5.default.clientErrors.BadRequestError());
|
|
14277
14368
|
}
|
|
14278
14369
|
const result2 = await svc._read(_id, { select });
|
|
@@ -14284,11 +14375,11 @@ function guard(condition) {
|
|
|
14284
14375
|
cond = _cond;
|
|
14285
14376
|
}
|
|
14286
14377
|
const { stringHandler, arrayHandler } = createValidator(phas);
|
|
14287
|
-
if ((0,
|
|
14378
|
+
if ((0, import_utils40.isString)(cond)) {
|
|
14288
14379
|
if (stringHandler(cond)) return next();
|
|
14289
|
-
} else if ((0,
|
|
14380
|
+
} else if ((0, import_utils40.isArray)(cond)) {
|
|
14290
14381
|
if (arrayHandler(cond)) return next();
|
|
14291
|
-
} else if ((0,
|
|
14382
|
+
} else if ((0, import_utils40.isFunction)(cond)) {
|
|
14292
14383
|
const result2 = await cond.call(req, permissions);
|
|
14293
14384
|
if (!!result2) return next();
|
|
14294
14385
|
}
|
|
@@ -14301,7 +14392,7 @@ var import_express2 = __toESM(require("express"));
|
|
|
14301
14392
|
|
|
14302
14393
|
// src/routers/model-router.ts
|
|
14303
14394
|
var import_express_json_router8 = __toESM(require("@web-ts-toolkit/express-json-router"));
|
|
14304
|
-
var
|
|
14395
|
+
var import_utils44 = require("@web-ts-toolkit/utils");
|
|
14305
14396
|
init_logger_helpers();
|
|
14306
14397
|
init_runtime();
|
|
14307
14398
|
init_runtime_context();
|
|
@@ -14435,7 +14526,7 @@ init_request_complexity();
|
|
|
14435
14526
|
|
|
14436
14527
|
// src/validation/common.ts
|
|
14437
14528
|
var import_zod2 = require("zod");
|
|
14438
|
-
var
|
|
14529
|
+
var import_utils41 = require("@web-ts-toolkit/utils");
|
|
14439
14530
|
|
|
14440
14531
|
// src/validation/public-admission-schema.ts
|
|
14441
14532
|
init_public_admission();
|
|
@@ -14564,7 +14655,7 @@ var correlatedFilterSchema = import_zod2.z.record(import_zod2.z.string(), import
|
|
|
14564
14655
|
}
|
|
14565
14656
|
});
|
|
14566
14657
|
var correlatedEmptyOptionsSchema = import_zod2.z.unknown().refine(
|
|
14567
|
-
(value) => value === void 0 || (0,
|
|
14658
|
+
(value) => value === void 0 || (0, import_utils41.isPlainObject)(value) && Object.keys(value).length === 0,
|
|
14568
14659
|
"Correlated include options must be absent or empty"
|
|
14569
14660
|
).optional();
|
|
14570
14661
|
var correlatedPathSchema = import_zod2.z.string().min(1).superRefine((path, ctx) => {
|
|
@@ -14601,7 +14692,7 @@ var correlatedListArgsSchema = import_zod2.z.object({
|
|
|
14601
14692
|
include: import_zod2.z.lazy(() => correlatedNestedIncludeSchema).optional()
|
|
14602
14693
|
}).strict().superRefine((args, ctx) => checkArgsMarkers(args.select, args.sort, ctx));
|
|
14603
14694
|
var correlatedCountArgsSchema = import_zod2.z.unknown().refine(
|
|
14604
|
-
(value) => value === void 0 || (0,
|
|
14695
|
+
(value) => value === void 0 || (0, import_utils41.isPlainObject)(value) && Object.keys(value).length === 0,
|
|
14605
14696
|
"Count includes accept no args"
|
|
14606
14697
|
).optional();
|
|
14607
14698
|
var correlatedReadByIdSchema = import_zod2.z.object({
|
|
@@ -14654,7 +14745,7 @@ var correlatedNestedIncludeSchema = import_zod2.z.union([includeItemSchema, impo
|
|
|
14654
14745
|
var rejectDuplicateCorrelatedPaths = (items, ctx) => {
|
|
14655
14746
|
const seen = /* @__PURE__ */ new Set();
|
|
14656
14747
|
items.forEach((item, index) => {
|
|
14657
|
-
if ((0,
|
|
14748
|
+
if ((0, import_utils41.isPlainObject)(item) && item.mode === "correlated" && typeof item.path === "string") {
|
|
14658
14749
|
if (seen.has(item.path)) {
|
|
14659
14750
|
ctx.addIssue({
|
|
14660
14751
|
code: import_zod2.z.ZodIssueCode.custom,
|
|
@@ -15627,7 +15718,7 @@ var rootQuerySchema = publicBoundarySchema(
|
|
|
15627
15718
|
init_helpers();
|
|
15628
15719
|
|
|
15629
15720
|
// src/routers/shared.ts
|
|
15630
|
-
var
|
|
15721
|
+
var import_utils42 = require("@web-ts-toolkit/utils");
|
|
15631
15722
|
|
|
15632
15723
|
// src/routers/model-router-collection-routes.ts
|
|
15633
15724
|
init_schemas();
|
|
@@ -15658,15 +15749,15 @@ function setModelCollectionRoutes(context) {
|
|
|
15658
15749
|
sort
|
|
15659
15750
|
} = parseQuery(requestSchemas.listQuery, req.query);
|
|
15660
15751
|
const svc = context.getPublicService(req);
|
|
15661
|
-
const includeCount = (0,
|
|
15662
|
-
const includeExtraHeaders = (0,
|
|
15752
|
+
const includeCount = (0, import_utils42.parseBooleanString)(include_count);
|
|
15753
|
+
const includeExtraHeaders = (0, import_utils42.parseBooleanString)(include_extra_headers);
|
|
15663
15754
|
const result2 = await svc._list(
|
|
15664
15755
|
{},
|
|
15665
15756
|
{ select: parseSelectParam(select), sort, skip, limit, page, pageSize: page_size },
|
|
15666
15757
|
{
|
|
15667
|
-
skim: (0,
|
|
15668
|
-
includePermissions: (0,
|
|
15669
|
-
includeFieldPermissions: (0,
|
|
15758
|
+
skim: (0, import_utils42.parseBooleanString)(skim),
|
|
15759
|
+
includePermissions: (0, import_utils42.parseBooleanString)(include_permissions),
|
|
15760
|
+
includeFieldPermissions: (0, import_utils42.parseBooleanString)(include_field_permissions),
|
|
15670
15761
|
includeCount
|
|
15671
15762
|
}
|
|
15672
15763
|
);
|
|
@@ -15726,8 +15817,8 @@ function setModelCollectionRoutes(context) {
|
|
|
15726
15817
|
data,
|
|
15727
15818
|
{},
|
|
15728
15819
|
{
|
|
15729
|
-
includePermissions: (0,
|
|
15730
|
-
includeFieldPermissions: (0,
|
|
15820
|
+
includePermissions: (0, import_utils42.parseBooleanString)(include_permissions),
|
|
15821
|
+
includeFieldPermissions: (0, import_utils42.parseBooleanString)(include_field_permissions)
|
|
15731
15822
|
}
|
|
15732
15823
|
);
|
|
15733
15824
|
handleResultError(result2);
|
|
@@ -15765,8 +15856,8 @@ function setModelCollectionRoutes(context) {
|
|
|
15765
15856
|
finalData,
|
|
15766
15857
|
{ select: finalSelect, populate: finalPopulate, tasks: finalTasks },
|
|
15767
15858
|
{
|
|
15768
|
-
includePermissions: includePermissions ?? (0,
|
|
15769
|
-
includeFieldPermissions: includeFieldPermissions ?? (0,
|
|
15859
|
+
includePermissions: includePermissions ?? (0, import_utils42.parseBooleanString)(include_permissions),
|
|
15860
|
+
includeFieldPermissions: includeFieldPermissions ?? (0, import_utils42.parseBooleanString)(include_field_permissions),
|
|
15770
15861
|
populateAccess
|
|
15771
15862
|
}
|
|
15772
15863
|
);
|
|
@@ -15863,9 +15954,9 @@ function setModelDocumentRoutes(context) {
|
|
|
15863
15954
|
id,
|
|
15864
15955
|
{ select: parseSelectParam(select) },
|
|
15865
15956
|
{
|
|
15866
|
-
includePermissions: (0,
|
|
15867
|
-
includeFieldPermissions: (0,
|
|
15868
|
-
tryList: (0,
|
|
15957
|
+
includePermissions: (0, import_utils42.parseBooleanString)(include_permissions),
|
|
15958
|
+
includeFieldPermissions: (0, import_utils42.parseBooleanString)(include_field_permissions),
|
|
15959
|
+
tryList: (0, import_utils42.parseBooleanString)(try_list)
|
|
15869
15960
|
}
|
|
15870
15961
|
);
|
|
15871
15962
|
handleResultError(result2);
|
|
@@ -15965,9 +16056,9 @@ function setModelDocumentRoutes(context) {
|
|
|
15965
16056
|
data,
|
|
15966
16057
|
{ select: parseSelectParam(select) },
|
|
15967
16058
|
{
|
|
15968
|
-
returningAll: (0,
|
|
15969
|
-
includePermissions: (0,
|
|
15970
|
-
includeFieldPermissions: (0,
|
|
16059
|
+
returningAll: (0, import_utils42.parseBooleanString)(returning_all),
|
|
16060
|
+
includePermissions: (0, import_utils42.parseBooleanString)(include_permissions),
|
|
16061
|
+
includeFieldPermissions: (0, import_utils42.parseBooleanString)(include_field_permissions)
|
|
15971
16062
|
}
|
|
15972
16063
|
);
|
|
15973
16064
|
handleResultError(result2);
|
|
@@ -16016,9 +16107,9 @@ function setModelDocumentRoutes(context) {
|
|
|
16016
16107
|
finalData,
|
|
16017
16108
|
{ select: finalSelect, populate: finalPopulate, tasks: finalTasks },
|
|
16018
16109
|
{
|
|
16019
|
-
returningAll: returningAll ?? (0,
|
|
16020
|
-
includePermissions: includePermissions ?? (0,
|
|
16021
|
-
includeFieldPermissions: includeFieldPermissions ?? (0,
|
|
16110
|
+
returningAll: returningAll ?? (0, import_utils42.parseBooleanString)(returning_all),
|
|
16111
|
+
includePermissions: includePermissions ?? (0, import_utils42.parseBooleanString)(include_permissions),
|
|
16112
|
+
includeFieldPermissions: includeFieldPermissions ?? (0, import_utils42.parseBooleanString)(include_field_permissions),
|
|
16022
16113
|
populateAccess
|
|
16023
16114
|
}
|
|
16024
16115
|
);
|
|
@@ -16049,9 +16140,9 @@ function setModelDocumentRoutes(context) {
|
|
|
16049
16140
|
body,
|
|
16050
16141
|
{},
|
|
16051
16142
|
{
|
|
16052
|
-
returningAll: (0,
|
|
16053
|
-
includePermissions: (0,
|
|
16054
|
-
includeFieldPermissions: (0,
|
|
16143
|
+
returningAll: (0, import_utils42.parseBooleanString)(returning_all),
|
|
16144
|
+
includePermissions: (0, import_utils42.parseBooleanString)(include_permissions),
|
|
16145
|
+
includeFieldPermissions: (0, import_utils42.parseBooleanString)(include_field_permissions)
|
|
16055
16146
|
}
|
|
16056
16147
|
);
|
|
16057
16148
|
handleResultError(result2);
|
|
@@ -16098,9 +16189,9 @@ function setModelDocumentRoutes(context) {
|
|
|
16098
16189
|
finalData,
|
|
16099
16190
|
{ select: finalSelect, populate: finalPopulate, tasks: finalTasks },
|
|
16100
16191
|
{
|
|
16101
|
-
returningAll: returningAll ?? (0,
|
|
16102
|
-
includePermissions: includePermissions ?? (0,
|
|
16103
|
-
includeFieldPermissions: includeFieldPermissions ?? (0,
|
|
16192
|
+
returningAll: returningAll ?? (0, import_utils42.parseBooleanString)(returning_all),
|
|
16193
|
+
includePermissions: includePermissions ?? (0, import_utils42.parseBooleanString)(include_permissions),
|
|
16194
|
+
includeFieldPermissions: includeFieldPermissions ?? (0, import_utils42.parseBooleanString)(include_field_permissions),
|
|
16104
16195
|
populateAccess
|
|
16105
16196
|
}
|
|
16106
16197
|
);
|
|
@@ -16340,11 +16431,11 @@ function setModelSubDocumentRoutes(context) {
|
|
|
16340
16431
|
}
|
|
16341
16432
|
|
|
16342
16433
|
// src/openapi/route-registration.ts
|
|
16343
|
-
var
|
|
16434
|
+
var import_utils43 = require("@web-ts-toolkit/utils");
|
|
16344
16435
|
function registerOpenApiRoute(runtime, basePath, defaultTag, route) {
|
|
16345
16436
|
runtime.registerOpenApiRoute({
|
|
16346
16437
|
...route,
|
|
16347
|
-
path: (0,
|
|
16438
|
+
path: (0, import_utils43.normalizeUrlPath)(basePath + route.path),
|
|
16348
16439
|
tags: route.tags ?? [defaultTag]
|
|
16349
16440
|
});
|
|
16350
16441
|
}
|
|
@@ -16352,8 +16443,8 @@ function registerOpenApiRoute(runtime, basePath, defaultTag, route) {
|
|
|
16352
16443
|
// src/routers/model-router.ts
|
|
16353
16444
|
var clientErrors2 = import_express_json_router8.default.clientErrors;
|
|
16354
16445
|
function setOption(parentKey, optionKey, option) {
|
|
16355
|
-
const key = (0,
|
|
16356
|
-
const value = (0,
|
|
16446
|
+
const key = (0, import_utils44.isUndefined)(option) ? parentKey : `${parentKey}.${optionKey}`;
|
|
16447
|
+
const value = (0, import_utils44.isUndefined)(option) ? optionKey : option;
|
|
16357
16448
|
assertMutableRouterOption("model", key);
|
|
16358
16449
|
this.runtime.setModelOption(
|
|
16359
16450
|
this.modelName,
|
|
@@ -16555,7 +16646,7 @@ var ModelRouter = class _ModelRouter {
|
|
|
16555
16646
|
this.runtime = runtime;
|
|
16556
16647
|
this.runtime.setModelOptions(modelName, initialOptions);
|
|
16557
16648
|
this.options = this.runtime.getModelOptions(modelName);
|
|
16558
|
-
this.fullBasePath = (0,
|
|
16649
|
+
this.fullBasePath = (0, import_utils44.normalizeUrlPath)(this.options.parentPath + this.options.basePath);
|
|
16559
16650
|
this.modelName = modelName;
|
|
16560
16651
|
this.router = new import_express_json_router8.default(this.options.basePath, createSetCore(this.runtime), accessRouterResponseHandler);
|
|
16561
16652
|
this.model = new model_default(modelName, this.runtime);
|
|
@@ -16641,13 +16732,13 @@ var ModelRouter = class _ModelRouter {
|
|
|
16641
16732
|
}
|
|
16642
16733
|
logEndpoints() {
|
|
16643
16734
|
runWithRuntime(this.runtime, () => {
|
|
16644
|
-
(0,
|
|
16645
|
-
logInfoMessage(`${(0,
|
|
16735
|
+
(0, import_utils44.forEach)(this.router.getEndpoints(), ({ method, path }) => {
|
|
16736
|
+
logInfoMessage(`${(0, import_utils44.padEnd)(method, 6)} ${(0, import_utils44.normalizeUrlPath)(this.options.parentPath + path)}`);
|
|
16646
16737
|
});
|
|
16647
16738
|
});
|
|
16648
16739
|
}
|
|
16649
16740
|
set(keyOrOptions, value) {
|
|
16650
|
-
if (arguments.length === 2 && (0,
|
|
16741
|
+
if (arguments.length === 2 && (0, import_utils44.isString)(keyOrOptions)) {
|
|
16651
16742
|
assertMutableRouterOption("model", keyOrOptions);
|
|
16652
16743
|
this.runtime.setModelOption(
|
|
16653
16744
|
this.modelName,
|
|
@@ -16655,7 +16746,7 @@ var ModelRouter = class _ModelRouter {
|
|
|
16655
16746
|
value
|
|
16656
16747
|
);
|
|
16657
16748
|
}
|
|
16658
|
-
if (arguments.length === 1 && (0,
|
|
16749
|
+
if (arguments.length === 1 && (0, import_utils44.isPlainObject)(keyOrOptions)) {
|
|
16659
16750
|
assertMutableRouterOptions("model", keyOrOptions);
|
|
16660
16751
|
this.runtime.setModelOptions(
|
|
16661
16752
|
this.modelName,
|
|
@@ -16683,7 +16774,7 @@ var ModelRouter = class _ModelRouter {
|
|
|
16683
16774
|
|
|
16684
16775
|
// src/routers/root-router.ts
|
|
16685
16776
|
var import_express_json_router9 = __toESM(require("@web-ts-toolkit/express-json-router"));
|
|
16686
|
-
var
|
|
16777
|
+
var import_utils45 = require("@web-ts-toolkit/utils");
|
|
16687
16778
|
|
|
16688
16779
|
// src/core-data.ts
|
|
16689
16780
|
init_options();
|
|
@@ -16991,7 +17082,7 @@ var RootRouter = class {
|
|
|
16991
17082
|
this.setRoutes();
|
|
16992
17083
|
}
|
|
16993
17084
|
registerOpenApiRoute(route) {
|
|
16994
|
-
registerOpenApiRoute(this.runtime, (0,
|
|
17085
|
+
registerOpenApiRoute(this.runtime, (0, import_utils45.normalizeUrlPath)(this.basename), "root", route);
|
|
16995
17086
|
}
|
|
16996
17087
|
wrapResult(index, item, result2) {
|
|
16997
17088
|
return {
|
|
@@ -17100,7 +17191,7 @@ var RootRouter = class {
|
|
|
17100
17191
|
groupItemsByOrder(items) {
|
|
17101
17192
|
const groups = /* @__PURE__ */ new Map();
|
|
17102
17193
|
items.forEach((item, index) => {
|
|
17103
|
-
const order = (0,
|
|
17194
|
+
const order = (0, import_utils45.isNumber)(item.order) ? item.order : 0;
|
|
17104
17195
|
const group = groups.get(order);
|
|
17105
17196
|
if (group) {
|
|
17106
17197
|
group.push({ index, item });
|
|
@@ -17171,7 +17262,7 @@ var RootRouter = class {
|
|
|
17171
17262
|
const arrResult = await this.runGroup(req, groupedItems[x]);
|
|
17172
17263
|
results.push(...arrResult);
|
|
17173
17264
|
}
|
|
17174
|
-
return (0,
|
|
17265
|
+
return (0, import_utils45.orderBy)(results, ["index"], ["asc"]);
|
|
17175
17266
|
});
|
|
17176
17267
|
this.registerOpenApiRoute({
|
|
17177
17268
|
method: "post",
|
|
@@ -17189,14 +17280,14 @@ var RootRouter = class {
|
|
|
17189
17280
|
|
|
17190
17281
|
// src/routers/data-router.ts
|
|
17191
17282
|
var import_express_json_router10 = __toESM(require("@web-ts-toolkit/express-json-router"));
|
|
17192
|
-
var
|
|
17283
|
+
var import_utils46 = require("@web-ts-toolkit/utils");
|
|
17193
17284
|
init_runtime();
|
|
17194
17285
|
init_helpers();
|
|
17195
17286
|
init_schemas();
|
|
17196
17287
|
var clientErrors4 = import_express_json_router10.default.clientErrors;
|
|
17197
17288
|
function setOption2(parentKey, optionKey, option) {
|
|
17198
|
-
const key = (0,
|
|
17199
|
-
const value = (0,
|
|
17289
|
+
const key = (0, import_utils46.isUndefined)(option) ? parentKey : `${parentKey}.${optionKey}`;
|
|
17290
|
+
const value = (0, import_utils46.isUndefined)(option) ? optionKey : option;
|
|
17200
17291
|
assertMutableRouterOption("data", key);
|
|
17201
17292
|
this.runtime.setDataOption(this.dataName, key, value);
|
|
17202
17293
|
return this;
|
|
@@ -17245,7 +17336,7 @@ var DataRouter = class {
|
|
|
17245
17336
|
this.runtime = runtime;
|
|
17246
17337
|
this.runtime.setDataOptions(dataName, initialOptions);
|
|
17247
17338
|
this.options = this.runtime.getDataOptions(dataName);
|
|
17248
|
-
this.fullBasePath = (0,
|
|
17339
|
+
this.fullBasePath = (0, import_utils46.normalizeUrlPath)(this.options.parentPath + this.options.basePath);
|
|
17249
17340
|
this.dataName = dataName;
|
|
17250
17341
|
this.router = new import_express_json_router10.default(this.options.basePath, createSetDataCore(this.runtime), accessRouterResponseHandler);
|
|
17251
17342
|
this.setCollectionRoutes();
|
|
@@ -17278,8 +17369,8 @@ var DataRouter = class {
|
|
|
17278
17369
|
req.query
|
|
17279
17370
|
);
|
|
17280
17371
|
const svc = this.getService(req);
|
|
17281
|
-
const includeCount = (0,
|
|
17282
|
-
const includeExtraHeaders = (0,
|
|
17372
|
+
const includeCount = (0, import_utils42.parseBooleanString)(include_count);
|
|
17373
|
+
const includeExtraHeaders = (0, import_utils42.parseBooleanString)(include_extra_headers);
|
|
17283
17374
|
const result2 = await svc.find(
|
|
17284
17375
|
{},
|
|
17285
17376
|
{ select: parseSelectParam(select), sort, skip, limit, page, pageSize: page_size },
|
|
@@ -17397,7 +17488,7 @@ var DataRouter = class {
|
|
|
17397
17488
|
});
|
|
17398
17489
|
}
|
|
17399
17490
|
set(keyOrOptions, value) {
|
|
17400
|
-
if (arguments.length === 2 && (0,
|
|
17491
|
+
if (arguments.length === 2 && (0, import_utils46.isString)(keyOrOptions)) {
|
|
17401
17492
|
assertMutableRouterOption("data", keyOrOptions);
|
|
17402
17493
|
this.runtime.setDataOption(
|
|
17403
17494
|
this.dataName,
|
|
@@ -17405,7 +17496,7 @@ var DataRouter = class {
|
|
|
17405
17496
|
value
|
|
17406
17497
|
);
|
|
17407
17498
|
}
|
|
17408
|
-
if (arguments.length === 1 && (0,
|
|
17499
|
+
if (arguments.length === 1 && (0, import_utils46.isPlainObject)(keyOrOptions)) {
|
|
17409
17500
|
assertMutableRouterOptions("data", keyOrOptions);
|
|
17410
17501
|
this.runtime.setDataOptions(this.dataName, keyOrOptions);
|
|
17411
17502
|
}
|
|
@@ -17540,7 +17631,7 @@ function createRuntimeApi(runtime) {
|
|
|
17540
17631
|
const wtt2 = runtimeMiddleware;
|
|
17541
17632
|
wtt2.runtime = runtime;
|
|
17542
17633
|
wtt2.createRouter = function(modelName, options) {
|
|
17543
|
-
if ((0,
|
|
17634
|
+
if ((0, import_utils47.isUndefined)(options)) {
|
|
17544
17635
|
return new RootRouter(modelName, runtime);
|
|
17545
17636
|
}
|
|
17546
17637
|
if (typeof modelName === "string") {
|
|
@@ -17561,10 +17652,10 @@ function createRuntimeApi(runtime) {
|
|
|
17561
17652
|
};
|
|
17562
17653
|
wtt2.combineRoutes = combineRoutes;
|
|
17563
17654
|
wtt2.set = function(keyOrOptions, value) {
|
|
17564
|
-
if (arguments.length === 2 && (0,
|
|
17655
|
+
if (arguments.length === 2 && (0, import_utils47.isString)(keyOrOptions)) {
|
|
17565
17656
|
return runtime.setGlobalOption(keyOrOptions, value);
|
|
17566
17657
|
}
|
|
17567
|
-
if (arguments.length === 1 && (0,
|
|
17658
|
+
if (arguments.length === 1 && (0, import_utils47.isPlainObject)(keyOrOptions)) {
|
|
17568
17659
|
return runtime.setGlobalOptions(keyOrOptions);
|
|
17569
17660
|
}
|
|
17570
17661
|
};
|