@web-ts-toolkit/access-router 0.56.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 +177 -120
- package/advanced.d.mts +1 -1
- package/advanced.d.ts +1 -1
- package/advanced.js +95 -66
- package/advanced.mjs +62 -33
- package/index.d.mts +2 -2
- package/index.d.ts +2 -2
- package/index.js +545 -514
- package/index.mjs +282 -251
- package/llms.txt +2 -2
- package/package.json +3 -3
- package/{parsers-BXKoUKMa.d.mts → parsers-CngKnVjW.d.mts} +65 -37
- package/{parsers-BXKoUKMa.d.ts → parsers-CngKnVjW.d.ts} +65 -37
package/index.mjs
CHANGED
|
@@ -2140,10 +2140,34 @@ var init_field_catalog = __esm({
|
|
|
2140
2140
|
}
|
|
2141
2141
|
});
|
|
2142
2142
|
|
|
2143
|
+
// src/acl/populate-target-configuration.ts
|
|
2144
|
+
import { isPlainObject as isPlainObject12 } from "@web-ts-toolkit/utils";
|
|
2145
|
+
function capturePopulateTargetConfiguration(runtime, modelName, source, proposedOptions) {
|
|
2146
|
+
const label = `Populate target "${modelName}" for ${source}`;
|
|
2147
|
+
if (!proposedOptions && !runtime.hasModel(modelName))
|
|
2148
|
+
authorizationError(
|
|
2149
|
+
`${label} must be configured first in this runtime; register its Mongoose model and setModelOptions with an object permissionSchema`
|
|
2150
|
+
);
|
|
2151
|
+
const model = runtime.getModelInstance(modelName);
|
|
2152
|
+
if (!model) authorizationError(`${label} requires an actual registered Mongoose model in this runtime`);
|
|
2153
|
+
const options = proposedOptions ?? runtime.getModelOptions(modelName);
|
|
2154
|
+
const permissionSchema = options.permissionSchema === void 0 ? runtime.getDefaultModelOption("permissionSchema") : options.permissionSchema;
|
|
2155
|
+
if (!isPlainObject12(permissionSchema))
|
|
2156
|
+
authorizationError(
|
|
2157
|
+
`${label} requires an effective object permissionSchema; configure the model or runtime model defaults ({} explicitly closes business fields)`
|
|
2158
|
+
);
|
|
2159
|
+
return { model, options: { ...options, permissionSchema } };
|
|
2160
|
+
}
|
|
2161
|
+
var init_populate_target_configuration = __esm({
|
|
2162
|
+
"src/acl/populate-target-configuration.ts"() {
|
|
2163
|
+
init_authorization_snapshot();
|
|
2164
|
+
}
|
|
2165
|
+
});
|
|
2166
|
+
|
|
2143
2167
|
// src/acl/virtual-populate-dependencies.ts
|
|
2144
|
-
import { get as get4, isPlainObject as
|
|
2168
|
+
import { get as get4, isPlainObject as isPlainObject13 } from "@web-ts-toolkit/utils";
|
|
2145
2169
|
function record(value, label) {
|
|
2146
|
-
if (!
|
|
2170
|
+
if (!isPlainObject13(value)) return fail(label, "entries must be plain { path, select? } objects");
|
|
2147
2171
|
for (const key of Reflect.ownKeys(value)) {
|
|
2148
2172
|
const property = Object.getOwnPropertyDescriptor(value, key);
|
|
2149
2173
|
if (typeof key !== "string" || !property.enumerable || !("value" in property))
|
|
@@ -2232,7 +2256,8 @@ function normalizeSelection(select, catalog, label) {
|
|
|
2232
2256
|
};
|
|
2233
2257
|
}
|
|
2234
2258
|
function captureVirtualPopulateDependencies(runtime, modelName, options, globalOptions = runtime.getGlobalOptions()) {
|
|
2235
|
-
const
|
|
2259
|
+
const requireOperationAccessForPopulateDependencies = globalOptions.requireOperationAccessForPopulateDependencies !== false;
|
|
2260
|
+
const requireOperationAccessForPopulateQueries = globalOptions.requireOperationAccessForPopulateQueries !== false;
|
|
2236
2261
|
const model = runtime.getModelInstance(modelName);
|
|
2237
2262
|
const targets = /* @__PURE__ */ new Map();
|
|
2238
2263
|
const scopes = [];
|
|
@@ -2272,7 +2297,12 @@ function captureVirtualPopulateDependencies(runtime, modelName, options, globalO
|
|
|
2272
2297
|
label,
|
|
2273
2298
|
`target "${ref}" requires a registered same-connection non-discriminator ObjectId model bound to the source ref`
|
|
2274
2299
|
);
|
|
2275
|
-
const
|
|
2300
|
+
const { options: targetOptions } = capturePopulateTargetConfiguration(
|
|
2301
|
+
runtime,
|
|
2302
|
+
ref,
|
|
2303
|
+
`dependsOnPopulate virtual "${label}"`,
|
|
2304
|
+
ref === modelName ? options : void 0
|
|
2305
|
+
);
|
|
2276
2306
|
const defaults = runtime.getDefaultModelOptions();
|
|
2277
2307
|
const readOption = (key) => resolveNestedOption((path2, fallback) => get4(targetOptions, path2, fallback), key, get4(defaults, key));
|
|
2278
2308
|
const documentPermissionField = targetOptions.documentPermissionField ?? defaults.documentPermissionField;
|
|
@@ -2281,7 +2311,9 @@ function captureVirtualPopulateDependencies(runtime, modelName, options, globalO
|
|
|
2281
2311
|
{
|
|
2282
2312
|
catalog,
|
|
2283
2313
|
documentPermissionField,
|
|
2284
|
-
|
|
2314
|
+
requireOperationAccessForPopulateDependencies,
|
|
2315
|
+
requireOperationAccessForPopulateQueries,
|
|
2316
|
+
permissionSchema: targetOptions.permissionSchema,
|
|
2285
2317
|
operationAccess: { read: readOption("operationAccess.read") },
|
|
2286
2318
|
baseFilter: { read: readOption("baseFilter.read") },
|
|
2287
2319
|
overrideFilter: { read: readOption("overrideFilter.read") },
|
|
@@ -2330,13 +2362,13 @@ function captureVirtualPopulateDependencies(runtime, modelName, options, globalO
|
|
|
2330
2362
|
);
|
|
2331
2363
|
continue;
|
|
2332
2364
|
}
|
|
2333
|
-
if (!
|
|
2365
|
+
if (!isPlainObject13(raw)) continue;
|
|
2334
2366
|
const entry = raw;
|
|
2335
2367
|
const label = join(sourcePrefix, name);
|
|
2336
2368
|
captureList(entry.dependsOnPopulate, label);
|
|
2337
2369
|
if (!("get" in entry))
|
|
2338
2370
|
for (const access of accesses) {
|
|
2339
|
-
if (
|
|
2371
|
+
if (isPlainObject13(entry[access]))
|
|
2340
2372
|
captureList(entry[access].dependsOnPopulate, `${label}.${access}`);
|
|
2341
2373
|
}
|
|
2342
2374
|
const byAccess = {};
|
|
@@ -2394,6 +2426,7 @@ var init_virtual_populate_dependencies = __esm({
|
|
|
2394
2426
|
init_authorization_snapshot();
|
|
2395
2427
|
init_field_catalog();
|
|
2396
2428
|
init_virtual_descriptor();
|
|
2429
|
+
init_populate_target_configuration();
|
|
2397
2430
|
elementType = (type) => type.$embeddedSchemaType ?? type.embeddedSchemaType ?? type.caster;
|
|
2398
2431
|
join = (prefix, path) => prefix ? `${prefix}.${path}` : path;
|
|
2399
2432
|
within = (path, parent) => path === parent || path.startsWith(`${parent}.`);
|
|
@@ -2418,7 +2451,7 @@ import {
|
|
|
2418
2451
|
isBoolean,
|
|
2419
2452
|
isFunction as isFunction2,
|
|
2420
2453
|
isNil as isNil2,
|
|
2421
|
-
isPlainObject as
|
|
2454
|
+
isPlainObject as isPlainObject14,
|
|
2422
2455
|
isString as isString4,
|
|
2423
2456
|
keys,
|
|
2424
2457
|
normalizeUrlPath,
|
|
@@ -2485,7 +2518,7 @@ var init_runtime = __esm({
|
|
|
2485
2518
|
const modelPermissionKeys = {};
|
|
2486
2519
|
forEach2(schemaKeys, (schemaKey) => {
|
|
2487
2520
|
const schemaRule = permissionSchema[schemaKey];
|
|
2488
|
-
const ruleEntries =
|
|
2521
|
+
const ruleEntries = isPlainObject14(schemaRule) ? Object.entries(schemaRule) : FIELD_ACCESS_KEYS.map((accessKey) => [accessKey, schemaRule]);
|
|
2489
2522
|
for (let x = 0; x < ruleEntries.length; x++) {
|
|
2490
2523
|
const [accessKey, value] = ruleEntries[x];
|
|
2491
2524
|
if (!isArray5(globalPermissionKeys[accessKey])) {
|
|
@@ -2526,7 +2559,7 @@ var init_runtime = __esm({
|
|
|
2526
2559
|
VIRTUAL_RESERVED_NAMES = /* @__PURE__ */ new Set(["_id", "__v", "id"]);
|
|
2527
2560
|
VIRTUAL_DANGEROUS_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
2528
2561
|
VIRTUAL_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
2529
|
-
isVirtualContainerValue2 = (value) =>
|
|
2562
|
+
isVirtualContainerValue2 = (value) => isPlainObject14(value) && "sub" in value;
|
|
2530
2563
|
virtualFullPath = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
2531
2564
|
virtualPathsOverlap = (virtualPath, permissionField) => {
|
|
2532
2565
|
if (!virtualPath || !permissionField) return false;
|
|
@@ -2621,7 +2654,7 @@ var init_runtime = __esm({
|
|
|
2621
2654
|
};
|
|
2622
2655
|
validateVirtualLeafValue = (value, entryLabel, storedFields, siblingVirtualNames, sharedDependsOn) => {
|
|
2623
2656
|
if (isFunction2(value)) return;
|
|
2624
|
-
if (!
|
|
2657
|
+
if (!isPlainObject14(value)) {
|
|
2625
2658
|
throw new Error(`Virtual ${entryLabel}: descriptor must be a getter function or { get, dependsOn }`);
|
|
2626
2659
|
}
|
|
2627
2660
|
const record3 = value;
|
|
@@ -2667,7 +2700,7 @@ var init_runtime = __esm({
|
|
|
2667
2700
|
`Virtual ${scopeLabel}${name}: scope-container must only hold "sub" (embedded container "${name}" is not a virtual-leaf collision)`
|
|
2668
2701
|
);
|
|
2669
2702
|
}
|
|
2670
|
-
if (!
|
|
2703
|
+
if (!isPlainObject14(record4.sub)) {
|
|
2671
2704
|
throw new Error(`Virtual ${scopeLabel}${name}: scope-container "sub" must be a plain object`);
|
|
2672
2705
|
}
|
|
2673
2706
|
continue;
|
|
@@ -2678,7 +2711,7 @@ var init_runtime = __esm({
|
|
|
2678
2711
|
);
|
|
2679
2712
|
}
|
|
2680
2713
|
if (isFunction2(raw)) continue;
|
|
2681
|
-
if (!
|
|
2714
|
+
if (!isPlainObject14(raw)) {
|
|
2682
2715
|
throw new Error(
|
|
2683
2716
|
`Virtual ${scopeLabel}${name}: malformed descriptor (expected getter, { get, dependsOn }, or per-access record)`
|
|
2684
2717
|
);
|
|
@@ -2732,7 +2765,7 @@ var init_runtime = __esm({
|
|
|
2732
2765
|
};
|
|
2733
2766
|
validateVirtualsTree = (model, virtuals, documentPermissionField, modelName) => {
|
|
2734
2767
|
if (virtuals === void 0 || virtuals === null) return;
|
|
2735
|
-
if (!
|
|
2768
|
+
if (!isPlainObject14(virtuals)) {
|
|
2736
2769
|
throw new Error(`Virtuals for model "${modelName}": virtuals must be a plain object mapping names to descriptors`);
|
|
2737
2770
|
}
|
|
2738
2771
|
const rootSchema = model?.schema ?? null;
|
|
@@ -2784,8 +2817,8 @@ var init_runtime = __esm({
|
|
|
2784
2817
|
{
|
|
2785
2818
|
requestPermissionField: "_permissions",
|
|
2786
2819
|
globalPermissions: () => ({}),
|
|
2787
|
-
|
|
2788
|
-
|
|
2820
|
+
requireOperationAccessForPopulateQueries: true,
|
|
2821
|
+
requireOperationAccessForPopulateDependencies: true,
|
|
2789
2822
|
logger: defaultLogger,
|
|
2790
2823
|
requestComplexity: defaultRequestComplexity
|
|
2791
2824
|
},
|
|
@@ -2959,13 +2992,15 @@ var init_runtime = __esm({
|
|
|
2959
2992
|
/** Shallowly replace supplied global values; nested objects such as requestComplexity are not deep-merged. */
|
|
2960
2993
|
setGlobalOptions(options) {
|
|
2961
2994
|
const next = { ...options };
|
|
2962
|
-
if ("
|
|
2963
|
-
next.
|
|
2995
|
+
if ("requireOperationAccessForPopulateQueries" in next)
|
|
2996
|
+
next.requireOperationAccessForPopulateQueries = next.requireOperationAccessForPopulateQueries !== false;
|
|
2997
|
+
if ("requireOperationAccessForPopulateDependencies" in next)
|
|
2998
|
+
next.requireOperationAccessForPopulateDependencies = next.requireOperationAccessForPopulateDependencies !== false;
|
|
2964
2999
|
this.globalOptions.assign(next);
|
|
2965
3000
|
}
|
|
2966
3001
|
setGlobalOption(key, value) {
|
|
2967
|
-
if (key === "
|
|
2968
|
-
this.globalOptions.set(
|
|
3002
|
+
if (key === "requireOperationAccessForPopulateQueries" || key === "requireOperationAccessForPopulateDependencies") {
|
|
3003
|
+
this.globalOptions.set(key, value !== false);
|
|
2969
3004
|
return;
|
|
2970
3005
|
}
|
|
2971
3006
|
this.globalOptions.set(key, value);
|
|
@@ -3088,10 +3123,10 @@ var init_runtime = __esm({
|
|
|
3088
3123
|
const segments = nestedPath.split(".");
|
|
3089
3124
|
let cursor = cloned;
|
|
3090
3125
|
for (let i = 0; i < segments.length - 1; i++) {
|
|
3091
|
-
if (!
|
|
3126
|
+
if (!isPlainObject14(cursor)) break;
|
|
3092
3127
|
cursor = cursor[segments[i]];
|
|
3093
3128
|
}
|
|
3094
|
-
if (
|
|
3129
|
+
if (isPlainObject14(cursor)) {
|
|
3095
3130
|
delete cursor[segments[segments.length - 1]];
|
|
3096
3131
|
}
|
|
3097
3132
|
proposedVirtuals = cloned;
|
|
@@ -3583,7 +3618,6 @@ function normalizePolicy(value, applicability, configuration, targets) {
|
|
|
3583
3618
|
const matches = targets.filter((target2) => target2.path === path);
|
|
3584
3619
|
if (matches.length !== 1) authorizationError(`unused or ambiguous related path: ${path}`);
|
|
3585
3620
|
const target = matches[0];
|
|
3586
|
-
if (target.kind === "passthrough") authorizationError(`related policy requires a registered target: ${path}`);
|
|
3587
3621
|
const child = authorizationRecord(entry, `related.${path}`);
|
|
3588
3622
|
assertAuthorizationKeys(
|
|
3589
3623
|
child,
|
|
@@ -4093,7 +4127,7 @@ var init_field_authorization = __esm({
|
|
|
4093
4127
|
});
|
|
4094
4128
|
|
|
4095
4129
|
// src/acl/virtual-projection.ts
|
|
4096
|
-
import { get as get6, isArray as isArray7, isPlainObject as
|
|
4130
|
+
import { get as get6, isArray as isArray7, isPlainObject as isPlainObject16 } from "@web-ts-toolkit/utils";
|
|
4097
4131
|
function planVirtualProjection(args) {
|
|
4098
4132
|
if (args.snapshot.catalog) return planCatalogProjection(args);
|
|
4099
4133
|
const {
|
|
@@ -4327,15 +4361,15 @@ var init_virtual_projection = __esm({
|
|
|
4327
4361
|
init_virtual_populate_dependencies();
|
|
4328
4362
|
init_virtual_descriptor();
|
|
4329
4363
|
getScopedPermissionSchema = (root, scopePath) => {
|
|
4330
|
-
if (!root || !
|
|
4364
|
+
if (!root || !isPlainObject16(root)) return null;
|
|
4331
4365
|
if (scopePath.length === 0) return root;
|
|
4332
4366
|
const scoped = get6(root, scopePath.join("."));
|
|
4333
|
-
return
|
|
4367
|
+
return isPlainObject16(scoped) ? scoped : null;
|
|
4334
4368
|
};
|
|
4335
4369
|
resolveAlwaysSelectForAccess = (raw, access) => {
|
|
4336
4370
|
if (!raw) return [];
|
|
4337
4371
|
if (isArray7(raw)) return [...raw];
|
|
4338
|
-
if (
|
|
4372
|
+
if (isPlainObject16(raw)) {
|
|
4339
4373
|
const record3 = raw;
|
|
4340
4374
|
const exact = record3[access];
|
|
4341
4375
|
if (isArray7(exact)) return [...exact];
|
|
@@ -4622,9 +4656,9 @@ function captureModelAuthorizationConfiguration(runtime, modelName, options = ru
|
|
|
4622
4656
|
options,
|
|
4623
4657
|
globalOptions
|
|
4624
4658
|
),
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
permissionSchema: options.permissionSchema,
|
|
4659
|
+
requireOperationAccessForPopulateDependencies: globalOptions.requireOperationAccessForPopulateDependencies !== false,
|
|
4660
|
+
requireOperationAccessForPopulateQueries: globalOptions.requireOperationAccessForPopulateQueries !== false,
|
|
4661
|
+
permissionSchema: options.permissionSchema === void 0 ? runtime.getDefaultModelOption("permissionSchema") : options.permissionSchema,
|
|
4628
4662
|
virtuals,
|
|
4629
4663
|
alwaysSelectFields: options.alwaysSelectFields,
|
|
4630
4664
|
modelPermissionPrefix: options.modelPermissionPrefix,
|
|
@@ -4690,15 +4724,15 @@ import {
|
|
|
4690
4724
|
isBoolean as isBoolean2,
|
|
4691
4725
|
isEmpty as isEmpty2,
|
|
4692
4726
|
isFunction as isFunction3,
|
|
4693
|
-
isPlainObject as
|
|
4727
|
+
isPlainObject as isPlainObject17,
|
|
4694
4728
|
isString as isString5
|
|
4695
4729
|
} from "@web-ts-toolkit/utils";
|
|
4696
4730
|
import { isDeepStrictEqual as isDeepStrictEqual2 } from "util";
|
|
4697
4731
|
function isAndFilter(filter2) {
|
|
4698
|
-
return !!filter2 &&
|
|
4732
|
+
return !!filter2 && isPlainObject17(filter2) && Object.keys(filter2).length === 1 && isArray8(filter2.$and);
|
|
4699
4733
|
}
|
|
4700
4734
|
function isMergeableClause(filter2) {
|
|
4701
|
-
return !!filter2 &&
|
|
4735
|
+
return !!filter2 && isPlainObject17(filter2) && Object.keys(filter2).every((key) => !key.startsWith("$"));
|
|
4702
4736
|
}
|
|
4703
4737
|
function optimizeAndFilter(clausesInput) {
|
|
4704
4738
|
const clauses = [];
|
|
@@ -4719,7 +4753,7 @@ function optimizeAndFilter(clausesInput) {
|
|
|
4719
4753
|
const entries = Array.from(value, dedupeKey);
|
|
4720
4754
|
return entries.every((entry) => entry !== void 0) ? `array:${JSON.stringify(entries)}` : void 0;
|
|
4721
4755
|
}
|
|
4722
|
-
if (
|
|
4756
|
+
if (isPlainObject17(value)) {
|
|
4723
4757
|
const entries = Object.keys(value).sort().map((key) => [key, dedupeKey(value[key])]);
|
|
4724
4758
|
return entries.every(([, entry]) => entry !== void 0) ? `object:${JSON.stringify(entries)}` : void 0;
|
|
4725
4759
|
}
|
|
@@ -4767,7 +4801,7 @@ function optimizeAndFilter(clausesInput) {
|
|
|
4767
4801
|
}
|
|
4768
4802
|
function normalizeFilter(filter2) {
|
|
4769
4803
|
if (filter2 === false) return false;
|
|
4770
|
-
if (!filter2 || !
|
|
4804
|
+
if (!filter2 || !isPlainObject17(filter2) || isEmpty2(filter2)) return null;
|
|
4771
4805
|
if (!isAndFilter(filter2)) {
|
|
4772
4806
|
return filter2;
|
|
4773
4807
|
}
|
|
@@ -4845,7 +4879,7 @@ async function setRequestPermissions(req) {
|
|
|
4845
4879
|
if (hasFieldValue && owner === void 0) return;
|
|
4846
4880
|
const globalPermissions = getGlobalOption("globalPermissions");
|
|
4847
4881
|
const permissions = isFunction3(globalPermissions) ? await globalPermissions.call(req, req) : void 0;
|
|
4848
|
-
if (
|
|
4882
|
+
if (isPlainObject17(permissions)) req[requestPermissionField] = permissions;
|
|
4849
4883
|
else if (isArray8(permissions)) req[requestPermissionField] = arrayToRecord(permissions);
|
|
4850
4884
|
else if (isString5(permissions)) req[requestPermissionField] = { [permissions]: true };
|
|
4851
4885
|
else req[requestPermissionField] = {};
|
|
@@ -5244,7 +5278,7 @@ var init_filter_resolution = __esm({
|
|
|
5244
5278
|
// src/acl/virtual-populate-execution.ts
|
|
5245
5279
|
import { Document as Document4, mongo as mongo4 } from "mongoose";
|
|
5246
5280
|
import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
|
|
5247
|
-
import { isPlainObject as
|
|
5281
|
+
import { isPlainObject as isPlainObject20 } from "@web-ts-toolkit/utils";
|
|
5248
5282
|
function projectVirtualPopulateView(source, selection, structurePaths = []) {
|
|
5249
5283
|
const root = { children: /* @__PURE__ */ new Map() };
|
|
5250
5284
|
for (const path of compactPersistedProjection(selection)) {
|
|
@@ -5276,8 +5310,8 @@ function equivalentVirtualPopulatePredicate(left, right) {
|
|
|
5276
5310
|
}
|
|
5277
5311
|
if (Array.isArray(left) || Array.isArray(right))
|
|
5278
5312
|
return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((entry, index) => equivalentVirtualPopulatePredicate(entry, right[index]));
|
|
5279
|
-
if (
|
|
5280
|
-
if (!
|
|
5313
|
+
if (isPlainObject20(left) || isPlainObject20(right)) {
|
|
5314
|
+
if (!isPlainObject20(left) || !isPlainObject20(right)) return false;
|
|
5281
5315
|
const a = Object.keys(left), b = Object.keys(right);
|
|
5282
5316
|
return a.length === b.length && a.every(
|
|
5283
5317
|
(key, index) => key === b[index] && equivalentVirtualPopulatePredicate(
|
|
@@ -5348,7 +5382,6 @@ function captureVirtualPopulateRows(batch, inputs, plan, publicPopulate = [], so
|
|
|
5348
5382
|
address,
|
|
5349
5383
|
plan: currentPlan,
|
|
5350
5384
|
refs: /* @__PURE__ */ new Map(),
|
|
5351
|
-
referenceTargets: /* @__PURE__ */ new Map(),
|
|
5352
5385
|
dependencies: /* @__PURE__ */ new Map()
|
|
5353
5386
|
};
|
|
5354
5387
|
row.occurrences.set(addressKey(address), occurrence);
|
|
@@ -5356,7 +5389,6 @@ function captureVirtualPopulateRows(batch, inputs, plan, publicPopulate = [], so
|
|
|
5356
5389
|
const dependencies = (candidate.populateDependencies ?? []).map((dependency) => {
|
|
5357
5390
|
if (!occurrence.refs.has(dependency.path))
|
|
5358
5391
|
occurrence.refs.set(dependency.path, originalRef(value, dependency.path));
|
|
5359
|
-
occurrence.referenceTargets.set(dependency.path, dependency.target);
|
|
5360
5392
|
const request = {
|
|
5361
5393
|
binding: dependency.target,
|
|
5362
5394
|
target: dependency.target,
|
|
@@ -5454,7 +5486,7 @@ async function execute(state) {
|
|
|
5454
5486
|
if (!pending) {
|
|
5455
5487
|
pending = (async () => {
|
|
5456
5488
|
try {
|
|
5457
|
-
if (target.configuration.
|
|
5489
|
+
if (target.configuration.requireOperationAccessForPopulateDependencies !== false && !await targetReadAllowed(state, target))
|
|
5458
5490
|
return void 0;
|
|
5459
5491
|
const parts = await work.hookGate.run(
|
|
5460
5492
|
() => resolveAccessFilterParts({
|
|
@@ -5540,12 +5572,6 @@ function readVirtualPopulateOriginalReference(row, address, path) {
|
|
|
5540
5572
|
function hasVirtualPopulatePublicReference(row, address, path) {
|
|
5541
5573
|
return !!rows.get(row)?.publicRequests.some((request) => addressKey(request.address) === addressKey([...address, path]));
|
|
5542
5574
|
}
|
|
5543
|
-
function isVirtualPopulateReferenceVisible(row, address, path) {
|
|
5544
|
-
const record3 = rows.get(row);
|
|
5545
|
-
const occurrence = record3?.occurrences.get(addressKey(address));
|
|
5546
|
-
const target = occurrence?.refs.get(path)?.present ? occurrence.referenceTargets.get(path) : void 0;
|
|
5547
|
-
return record3 && target ? targetReadAllowed(record3.batch, target) : Promise.resolve(true);
|
|
5548
|
-
}
|
|
5549
5575
|
function readVirtualPopulateInputs(row, address, virtualName) {
|
|
5550
5576
|
const record3 = rows.get(row);
|
|
5551
5577
|
if (!record3?.batch.completed) return { available: false };
|
|
@@ -5688,7 +5714,7 @@ var init_virtual_populate_execution = __esm({
|
|
|
5688
5714
|
publicViewIdentities = /* @__PURE__ */ new WeakMap();
|
|
5689
5715
|
familyRawFetches = /* @__PURE__ */ new WeakMap();
|
|
5690
5716
|
addressKey = (address) => JSON.stringify(address);
|
|
5691
|
-
storage = (value) => value instanceof Document4 ? value._doc :
|
|
5717
|
+
storage = (value) => value instanceof Document4 ? value._doc : isPlainObject20(value) ? value : void 0;
|
|
5692
5718
|
originalRef = (source, key) => {
|
|
5693
5719
|
const record3 = storage(source);
|
|
5694
5720
|
return {
|
|
@@ -5701,7 +5727,7 @@ var init_virtual_populate_execution = __esm({
|
|
|
5701
5727
|
const option = getCapturedAuthorizationOption(configuration, `${key}.${access}`);
|
|
5702
5728
|
return key === "operationAccess" || typeof option === "function" ? option : void 0;
|
|
5703
5729
|
});
|
|
5704
|
-
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.
|
|
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.
|
|
5705
5731
|
equivalentVirtualPopulatePredicate(
|
|
5706
5732
|
a.binding.configuration.catalog.persistedPaths,
|
|
5707
5733
|
b.binding.configuration.catalog.persistedPaths
|
|
@@ -5715,7 +5741,7 @@ var init_virtual_populate_execution = __esm({
|
|
|
5715
5741
|
});
|
|
5716
5742
|
|
|
5717
5743
|
// src/acl/output-field-filter.ts
|
|
5718
|
-
import { isPlainObject as
|
|
5744
|
+
import { isPlainObject as isPlainObject21 } from "@web-ts-toolkit/utils";
|
|
5719
5745
|
async function resolveOutputDocumentAuthorization(args) {
|
|
5720
5746
|
const { authorization, binding } = args;
|
|
5721
5747
|
const { configuration, access } = readServiceAuthorization(authorization, binding);
|
|
@@ -5729,7 +5755,7 @@ async function resolveOutputDocumentAuthorization(args) {
|
|
|
5729
5755
|
try {
|
|
5730
5756
|
const run = () => hook.call(this, doc, permissions, args.context);
|
|
5731
5757
|
const grants = await getRequestWorkState(binding.request, binding.runtime).hookGate.run(run);
|
|
5732
|
-
return
|
|
5758
|
+
return isPlainObject21(grants) ? grants : {};
|
|
5733
5759
|
} catch (error2) {
|
|
5734
5760
|
warn("docPermissions hook failed; applying empty document permissions", {
|
|
5735
5761
|
modelName: binding.modelName,
|
|
@@ -5844,7 +5870,7 @@ function copyOutputValue(value, plan, path) {
|
|
|
5844
5870
|
const visit = (input, current) => {
|
|
5845
5871
|
if (Array.isArray(input)) return input.map((entry) => visit(entry, current));
|
|
5846
5872
|
if (input instanceof Map) return visit(Object.fromEntries(input), current);
|
|
5847
|
-
if (!
|
|
5873
|
+
if (!isPlainObject21(input)) return deepIsolateValue(input);
|
|
5848
5874
|
const output = {};
|
|
5849
5875
|
for (const [key, entry] of Object.entries(input)) {
|
|
5850
5876
|
const child = `${current}.${key}`;
|
|
@@ -5860,25 +5886,21 @@ function copyOutputValue(value, plan, path) {
|
|
|
5860
5886
|
}
|
|
5861
5887
|
function copyAuthorizedReference(value, plan, path) {
|
|
5862
5888
|
if (Array.isArray(value)) return value.map((entry) => copyAuthorizedReference(entry, plan, path));
|
|
5863
|
-
if (!
|
|
5889
|
+
if (!isPlainObject21(value)) return deepIsolateValue(value);
|
|
5864
5890
|
const handle = getAssociatedDocumentAuthorization(value, plan.authorization);
|
|
5865
5891
|
if (handle) {
|
|
5866
5892
|
const copy = deepIsolateValue(value);
|
|
5867
5893
|
transferDocumentAuthorizationGraph(value, copy);
|
|
5868
5894
|
return copy;
|
|
5869
5895
|
}
|
|
5870
|
-
const { relatedTargets } = readServiceAuthorization(plan.authorization, plan.authorizationBinding);
|
|
5871
|
-
if (relatedTargets.some((target) => target.path === path && target.kind === "passthrough")) {
|
|
5872
|
-
return deepIsolateValue(value);
|
|
5873
|
-
}
|
|
5874
5896
|
return Object.prototype.hasOwnProperty.call(value, "_id") ? deepIsolateValue(value._id) : void 0;
|
|
5875
5897
|
}
|
|
5876
5898
|
function retainOutputMetadata(output, source, configuration, scope2) {
|
|
5877
5899
|
if (scope2.length || configuration.stripPermissionsField) return;
|
|
5878
5900
|
const parts = (configuration.documentPermissionField ?? "_permissions").split(".");
|
|
5879
5901
|
let value = source;
|
|
5880
|
-
for (const part of parts) value =
|
|
5881
|
-
if (!
|
|
5902
|
+
for (const part of parts) value = isPlainObject21(value) ? value[part] : void 0;
|
|
5903
|
+
if (!isPlainObject21(value)) return;
|
|
5882
5904
|
const keys2 = configuration.exposedDocPermissionKeys;
|
|
5883
5905
|
const metadata = Object.fromEntries(
|
|
5884
5906
|
Object.entries(value).filter(
|
|
@@ -5888,7 +5910,7 @@ function retainOutputMetadata(output, source, configuration, scope2) {
|
|
|
5888
5910
|
const copy = { ...output };
|
|
5889
5911
|
let target = copy;
|
|
5890
5912
|
for (const part of parts.slice(0, -1)) {
|
|
5891
|
-
target[part] =
|
|
5913
|
+
target[part] = isPlainObject21(target[part]) ? { ...target[part] } : {};
|
|
5892
5914
|
target = target[part];
|
|
5893
5915
|
}
|
|
5894
5916
|
target[parts[parts.length - 1]] = deepIsolateValue(metadata);
|
|
@@ -5930,7 +5952,7 @@ async function filterExistingOutput(source, plan, handle, associated) {
|
|
|
5930
5952
|
for (const entry of value2) values.push(await one(entry) ?? null);
|
|
5931
5953
|
return values;
|
|
5932
5954
|
}
|
|
5933
|
-
if (!
|
|
5955
|
+
if (!isPlainObject21(value2)) return value2 === null ? null : void 0;
|
|
5934
5956
|
const childHandle = associated ? getAssociatedDocumentAuthorization(value2) : void 0;
|
|
5935
5957
|
let child = scoped;
|
|
5936
5958
|
if (childHandle) {
|
|
@@ -6010,7 +6032,7 @@ async function filterModelOutputForHelper(args) {
|
|
|
6010
6032
|
const plan = helperPlan(normalized.authorization, binding);
|
|
6011
6033
|
if (args.doc == null) return { output: args.doc, fields: [] };
|
|
6012
6034
|
const source = isolateDocForOutput(args.doc);
|
|
6013
|
-
if (!
|
|
6035
|
+
if (!isPlainObject21(source)) return authorizationError("output helper requires one plain or hydrated document");
|
|
6014
6036
|
const knownOutput = !!args.doc && typeof args.doc === "object" && isKnownAuthorizationOutput(args.doc);
|
|
6015
6037
|
const handle = await resolveOutputDocumentAuthorization({
|
|
6016
6038
|
authorization: normalized.authorization,
|
|
@@ -6105,7 +6127,7 @@ __export(finalize_model_output_exports, {
|
|
|
6105
6127
|
finalizeModelOutput: () => finalizeModelOutput,
|
|
6106
6128
|
finalizeModelOutputs: () => finalizeModelOutputs
|
|
6107
6129
|
});
|
|
6108
|
-
import { get as get9, isPlainObject as
|
|
6130
|
+
import { get as get9, isPlainObject as isPlainObject22, set as set7 } from "@web-ts-toolkit/utils";
|
|
6109
6131
|
async function finalizeSingleDoc(args, input) {
|
|
6110
6132
|
const scopePath = args.scopePath;
|
|
6111
6133
|
const plan = args.plan;
|
|
@@ -6121,8 +6143,8 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6121
6143
|
const privateRow = args.virtualPopulateRow ?? (original && typeof original === "object" ? getVirtualPopulateRow(original) : void 0);
|
|
6122
6144
|
const privateAddress = args.virtualPopulateAddress ?? [];
|
|
6123
6145
|
const isolated = isolateDocForOutput(input);
|
|
6124
|
-
const output =
|
|
6125
|
-
if (captured &&
|
|
6146
|
+
const output = isPlainObject22(isolated) ? isolated : {};
|
|
6147
|
+
if (captured && isPlainObject22(input))
|
|
6126
6148
|
for (const key of Object.keys(output)) {
|
|
6127
6149
|
transferDocumentAuthorizationGraph(input[key], output[key]);
|
|
6128
6150
|
}
|
|
@@ -6177,7 +6199,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6177
6199
|
);
|
|
6178
6200
|
continue;
|
|
6179
6201
|
}
|
|
6180
|
-
if (captured && !
|
|
6202
|
+
if (captured && !isPlainObject22(rawContainer) && !Array.isArray(rawContainer)) {
|
|
6181
6203
|
delete output[containerName];
|
|
6182
6204
|
continue;
|
|
6183
6205
|
}
|
|
@@ -6201,7 +6223,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6201
6223
|
const finalizeOneChild = async (rawChild, address) => {
|
|
6202
6224
|
if (captured && Array.isArray(rawChild))
|
|
6203
6225
|
return mapWithConcurrencyLimit(rawChild, limit, (entry, index) => finalizeOneChild(entry, [...address, index]));
|
|
6204
|
-
if (!
|
|
6226
|
+
if (!isPlainObject22(rawChild) && !Array.isArray(rawChild)) return captured ? null : deepIsolateValue(rawChild);
|
|
6205
6227
|
if (args.traversal?.finalizeEmbeddedChildren) {
|
|
6206
6228
|
return args.traversal.finalizeEmbeddedChildren({
|
|
6207
6229
|
containerName,
|
|
@@ -6227,7 +6249,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6227
6249
|
(entry, index) => finalizeOneChild(entry, [...privateAddress, containerName, index])
|
|
6228
6250
|
);
|
|
6229
6251
|
output[containerName] = finalized;
|
|
6230
|
-
} else if (
|
|
6252
|
+
} else if (isPlainObject22(rawContainer)) {
|
|
6231
6253
|
output[containerName] = await finalizeOneChild(rawContainer, [
|
|
6232
6254
|
...privateAddress,
|
|
6233
6255
|
containerName
|
|
@@ -6271,7 +6293,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6271
6293
|
related: target.plan.relatedPlans?.length ? (args.related ?? []).filter((entry) => entry.path.startsWith(`${target.path}.`)) : []
|
|
6272
6294
|
};
|
|
6273
6295
|
const finalizeOneRelated = async (rawChild, originalChild = rawChild) => {
|
|
6274
|
-
if (!
|
|
6296
|
+
if (!isPlainObject22(rawChild) && !Array.isArray(rawChild)) return rawChild;
|
|
6275
6297
|
if (typeof rawChild?._bsontype === "string") return rawChild;
|
|
6276
6298
|
const childOriginal = getIncludeOriginal(originalChild);
|
|
6277
6299
|
const childRow = childOriginal && typeof childOriginal === "object" ? getVirtualPopulateRow(childOriginal) : void 0;
|
|
@@ -6292,7 +6314,7 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6292
6314
|
limit,
|
|
6293
6315
|
(entry, index) => finalizeOneRelated(entry, Array.isArray(originalRelated) ? originalRelated[index] : void 0)
|
|
6294
6316
|
);
|
|
6295
|
-
} else if (
|
|
6317
|
+
} else if (isPlainObject22(rawRelated)) {
|
|
6296
6318
|
finalized = await finalizeOneRelated(rawRelated, originalRelated);
|
|
6297
6319
|
} else {
|
|
6298
6320
|
continue;
|
|
@@ -6412,7 +6434,6 @@ async function finalizeSingleDoc(args, input) {
|
|
|
6412
6434
|
if (!captured && documentPermissionField in output) keep.add(documentPermissionField);
|
|
6413
6435
|
const trimmed = {};
|
|
6414
6436
|
for (const key of keep) {
|
|
6415
|
-
if (privateRow && !await isVirtualPopulateReferenceVisible(privateRow, privateAddress, key)) continue;
|
|
6416
6437
|
if (privateRow && !hasVirtualPopulatePublicReference(privateRow, privateAddress, key)) {
|
|
6417
6438
|
const ref = readVirtualPopulateOriginalReference(privateRow, privateAddress, key);
|
|
6418
6439
|
if (ref) {
|
|
@@ -6494,20 +6515,20 @@ var init_finalize_model_output = __esm({
|
|
|
6494
6515
|
init_field_catalog();
|
|
6495
6516
|
init_virtual_populate_execution();
|
|
6496
6517
|
init_include_output();
|
|
6497
|
-
isVirtualContainerValue3 = (value) =>
|
|
6518
|
+
isVirtualContainerValue3 = (value) => isPlainObject22(value) && "sub" in value;
|
|
6498
6519
|
getScopeVirtualsObject2 = (rootVirtuals, scopePath) => {
|
|
6499
|
-
if (!rootVirtuals || !
|
|
6520
|
+
if (!rootVirtuals || !isPlainObject22(rootVirtuals)) return null;
|
|
6500
6521
|
if (scopePath.length === 0) return rootVirtuals;
|
|
6501
6522
|
let current = rootVirtuals;
|
|
6502
6523
|
for (let i = 0; i < scopePath.length; i += 2) {
|
|
6503
6524
|
const field = scopePath[i];
|
|
6504
6525
|
const subMarker = scopePath[i + 1];
|
|
6505
6526
|
if (!field || subMarker !== "sub") return null;
|
|
6506
|
-
if (!
|
|
6527
|
+
if (!isPlainObject22(current)) return null;
|
|
6507
6528
|
const container = current[field];
|
|
6508
6529
|
if (!isVirtualContainerValue3(container)) return null;
|
|
6509
6530
|
current = container.sub;
|
|
6510
|
-
if (!
|
|
6531
|
+
if (!isPlainObject22(current)) return null;
|
|
6511
6532
|
}
|
|
6512
6533
|
return current;
|
|
6513
6534
|
};
|
|
@@ -6520,11 +6541,11 @@ var init_finalize_model_output = __esm({
|
|
|
6520
6541
|
return Object.entries(scopeVirtuals).filter(([, v]) => v !== void 0 && !isVirtualContainerValue3(v)).map(([k]) => k);
|
|
6521
6542
|
};
|
|
6522
6543
|
getScopedPermissionSchema2 = (root, scopePath) => {
|
|
6523
|
-
if (!root || !
|
|
6544
|
+
if (!root || !isPlainObject22(root)) return null;
|
|
6524
6545
|
if (scopePath.length === 0) return root;
|
|
6525
6546
|
try {
|
|
6526
6547
|
const scoped = get9(root, scopePath.join("."));
|
|
6527
|
-
return
|
|
6548
|
+
return isPlainObject22(scoped) ? scoped : null;
|
|
6528
6549
|
} catch {
|
|
6529
6550
|
return null;
|
|
6530
6551
|
}
|
|
@@ -6583,7 +6604,7 @@ var init_finalize_model_output = __esm({
|
|
|
6583
6604
|
const grants = await args.sharedGate.run(
|
|
6584
6605
|
() => hook.call(args.request, isolatedForHook, globalPerms, scopeContext)
|
|
6585
6606
|
);
|
|
6586
|
-
const normalized =
|
|
6607
|
+
const normalized = isPlainObject22(grants) ? grants : {};
|
|
6587
6608
|
scopeContext.docPermissions = normalized;
|
|
6588
6609
|
return normalized;
|
|
6589
6610
|
}
|
|
@@ -6605,19 +6626,21 @@ var init_finalize_model_output = __esm({
|
|
|
6605
6626
|
});
|
|
6606
6627
|
|
|
6607
6628
|
// src/index.ts
|
|
6608
|
-
import { isPlainObject as
|
|
6629
|
+
import { isPlainObject as isPlainObject31, isString as isString10, isUndefined as isUndefined4 } from "@web-ts-toolkit/utils";
|
|
6609
6630
|
|
|
6610
6631
|
// src/middleware.ts
|
|
6611
6632
|
import JsonRouter5 from "@web-ts-toolkit/express-json-router";
|
|
6612
|
-
import { isArray as isArray13, isFunction as isFunction7, isPlainObject as
|
|
6633
|
+
import { isArray as isArray13, isFunction as isFunction7, isPlainObject as isPlainObject27, isString as isString7 } from "@web-ts-toolkit/utils";
|
|
6613
6634
|
|
|
6614
6635
|
// src/core.ts
|
|
6615
6636
|
init_public_admission();
|
|
6616
6637
|
init_options();
|
|
6638
|
+
init_permission();
|
|
6617
6639
|
import {
|
|
6618
6640
|
castArray as castArray4,
|
|
6619
6641
|
compact as compact3,
|
|
6620
6642
|
forEach as forEach6,
|
|
6643
|
+
get as get15,
|
|
6621
6644
|
isArray as isArray12,
|
|
6622
6645
|
isBoolean as isBoolean5,
|
|
6623
6646
|
isFunction as isFunction6,
|
|
@@ -6627,27 +6650,6 @@ import {
|
|
|
6627
6650
|
uniq as uniq3
|
|
6628
6651
|
} from "@web-ts-toolkit/utils";
|
|
6629
6652
|
|
|
6630
|
-
// src/meta.ts
|
|
6631
|
-
init_runtime();
|
|
6632
|
-
init_runtime_context();
|
|
6633
|
-
var getRuntime5 = () => getActiveRuntime() ?? defaultRuntime;
|
|
6634
|
-
var getModelRef = (modelName, refPath) => {
|
|
6635
|
-
const direct = getRuntime5().getModelRef(modelName, refPath);
|
|
6636
|
-
if (direct) return direct;
|
|
6637
|
-
if (!refPath.includes(".")) return null;
|
|
6638
|
-
try {
|
|
6639
|
-
const runtime = getRuntime5();
|
|
6640
|
-
const instance = runtime.getModelInstance?.(
|
|
6641
|
-
modelName
|
|
6642
|
-
);
|
|
6643
|
-
const schemaPath = instance?.schema?.path?.(refPath);
|
|
6644
|
-
const ref = schemaPath?.options?.ref ?? schemaPath?.caster?.options?.ref ?? null;
|
|
6645
|
-
return typeof ref === "string" && ref.length > 0 ? ref : null;
|
|
6646
|
-
} catch {
|
|
6647
|
-
return null;
|
|
6648
|
-
}
|
|
6649
|
-
};
|
|
6650
|
-
|
|
6651
6653
|
// src/services/base.ts
|
|
6652
6654
|
init_options();
|
|
6653
6655
|
init_helpers();
|
|
@@ -6663,7 +6665,7 @@ import {
|
|
|
6663
6665
|
forEach as forEach3,
|
|
6664
6666
|
get as get8,
|
|
6665
6667
|
isArray as isArray9,
|
|
6666
|
-
isPlainObject as
|
|
6668
|
+
isPlainObject as isPlainObject18,
|
|
6667
6669
|
set as set6,
|
|
6668
6670
|
uniq
|
|
6669
6671
|
} from "@web-ts-toolkit/utils";
|
|
@@ -6788,7 +6790,7 @@ init_public_admission();
|
|
|
6788
6790
|
// src/correlated-includes.ts
|
|
6789
6791
|
init_request_complexity();
|
|
6790
6792
|
init_sort_policy();
|
|
6791
|
-
import { cloneDeep, isArray as isArray6, isPlainObject as
|
|
6793
|
+
import { cloneDeep, isArray as isArray6, isPlainObject as isPlainObject15 } from "@web-ts-toolkit/utils";
|
|
6792
6794
|
var PARENT_MARKER_KEY = "$parent";
|
|
6793
6795
|
var ESCAPE_WRAPPER_KEY = "$escape";
|
|
6794
6796
|
var SUBQUERY_PAYLOAD_KEYS = /* @__PURE__ */ new Set(["$$sq", "$$date"]);
|
|
@@ -6799,10 +6801,10 @@ var FIELD_SEGMENT_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
|
6799
6801
|
var ARRAY_INDEX_SEGMENT_PATTERN = /^(0|[1-9]\d*)$/;
|
|
6800
6802
|
var ownKeys = (value) => Object.keys(value);
|
|
6801
6803
|
function isParentRefMarker(value) {
|
|
6802
|
-
return
|
|
6804
|
+
return isPlainObject15(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === PARENT_MARKER_KEY;
|
|
6803
6805
|
}
|
|
6804
6806
|
function isEscapedParentRef(value) {
|
|
6805
|
-
return
|
|
6807
|
+
return isPlainObject15(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === ESCAPE_WRAPPER_KEY;
|
|
6806
6808
|
}
|
|
6807
6809
|
function hasMarkerKey(value) {
|
|
6808
6810
|
return ownKeys(value).includes(PARENT_MARKER_KEY) || ownKeys(value).includes(ESCAPE_WRAPPER_KEY);
|
|
@@ -6826,7 +6828,7 @@ function containsParentMarkerShape(value) {
|
|
|
6826
6828
|
seen.add(current);
|
|
6827
6829
|
return current.some(visit);
|
|
6828
6830
|
}
|
|
6829
|
-
if (
|
|
6831
|
+
if (isPlainObject15(current)) {
|
|
6830
6832
|
if (seen.has(current)) return false;
|
|
6831
6833
|
seen.add(current);
|
|
6832
6834
|
if (hasMarkerKey(current)) return true;
|
|
@@ -6856,7 +6858,7 @@ function scanTemplateValueNode(value, path, issues) {
|
|
|
6856
6858
|
}
|
|
6857
6859
|
return;
|
|
6858
6860
|
}
|
|
6859
|
-
if (
|
|
6861
|
+
if (isPlainObject15(value)) {
|
|
6860
6862
|
if (hasMarkerKey(value)) {
|
|
6861
6863
|
issues.push({
|
|
6862
6864
|
message: 'Malformed $parent reference: objects carrying $parent must be exactly { "$parent": "<field>" }',
|
|
@@ -6921,7 +6923,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
|
|
|
6921
6923
|
});
|
|
6922
6924
|
return;
|
|
6923
6925
|
}
|
|
6924
|
-
if (
|
|
6926
|
+
if (isPlainObject15(clause)) {
|
|
6925
6927
|
scanTemplateObjectEntries(clause, clausePath, issues);
|
|
6926
6928
|
}
|
|
6927
6929
|
});
|
|
@@ -6932,7 +6934,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
|
|
|
6932
6934
|
}
|
|
6933
6935
|
function validateCorrelatedFilterTemplate(filter2) {
|
|
6934
6936
|
const issues = [];
|
|
6935
|
-
if (!
|
|
6937
|
+
if (!isPlainObject15(filter2)) {
|
|
6936
6938
|
issues.push({ message: "Correlated include filter must be an object", path: [] });
|
|
6937
6939
|
return issues;
|
|
6938
6940
|
}
|
|
@@ -6981,7 +6983,7 @@ function collectFilterReferencePaths(filter2) {
|
|
|
6981
6983
|
value.forEach(visitValue);
|
|
6982
6984
|
return;
|
|
6983
6985
|
}
|
|
6984
|
-
if (
|
|
6986
|
+
if (isPlainObject15(value)) {
|
|
6985
6987
|
if (seen.has(value)) return;
|
|
6986
6988
|
seen.add(value);
|
|
6987
6989
|
for (const [key, child] of Object.entries(value)) {
|
|
@@ -7027,7 +7029,7 @@ function getOwnPathValue(parent, path) {
|
|
|
7027
7029
|
return current;
|
|
7028
7030
|
}
|
|
7029
7031
|
function cloneSubstitutedValue(value) {
|
|
7030
|
-
if (
|
|
7032
|
+
if (isPlainObject15(value) || isArray6(value)) return cloneDeep(value);
|
|
7031
7033
|
return value;
|
|
7032
7034
|
}
|
|
7033
7035
|
function literalParentRefObject(path) {
|
|
@@ -7076,7 +7078,7 @@ function resolveObjectEntries(obj, parent) {
|
|
|
7076
7078
|
if (isParentRefMarker(clause) || isEscapedParentRef(clause)) {
|
|
7077
7079
|
throw new CorrelatedReferenceError(`Unsupported $parent reference as a direct ${key} clause`);
|
|
7078
7080
|
}
|
|
7079
|
-
if (!
|
|
7081
|
+
if (!isPlainObject15(clause)) return cloneSubstitutedValue(clause);
|
|
7080
7082
|
return resolveObjectEntries(clause, parent);
|
|
7081
7083
|
});
|
|
7082
7084
|
continue;
|
|
@@ -7105,10 +7107,10 @@ function resolveValueNode(template, parent, bare) {
|
|
|
7105
7107
|
}
|
|
7106
7108
|
const value = getOwnPathValue(parent, path);
|
|
7107
7109
|
if (value === void 0 || value === null) throw UNRESOLVABLE;
|
|
7108
|
-
if (bare &&
|
|
7110
|
+
if (bare && isPlainObject15(value)) return { $eq: cloneDeep(value) };
|
|
7109
7111
|
return cloneSubstitutedValue(value);
|
|
7110
7112
|
}
|
|
7111
|
-
if (
|
|
7113
|
+
if (isPlainObject15(template)) {
|
|
7112
7114
|
if (hasMarkerKey(template)) {
|
|
7113
7115
|
throw new CorrelatedReferenceError(
|
|
7114
7116
|
'Malformed $parent reference: objects carrying $parent must be exactly { "$parent": "<field>" }'
|
|
@@ -7150,7 +7152,7 @@ function resolveCorrelatedIdTemplate(id, parent) {
|
|
|
7150
7152
|
}
|
|
7151
7153
|
function resolveCorrelatedFilterTemplate(filter2, parent) {
|
|
7152
7154
|
try {
|
|
7153
|
-
if (!
|
|
7155
|
+
if (!isPlainObject15(filter2) || isParentRefMarker(filter2) || isEscapedParentRef(filter2)) {
|
|
7154
7156
|
throw new CorrelatedReferenceError("Correlated include filter must be an object");
|
|
7155
7157
|
}
|
|
7156
7158
|
return { status: "resolved", filter: resolveObjectEntries(filter2, parent) };
|
|
@@ -7165,7 +7167,7 @@ function validateExpandedCorrelatedOperands(expanded, limits) {
|
|
|
7165
7167
|
var MAX_NESTED_INCLUDE_DEPTH = 10;
|
|
7166
7168
|
function validateCorrelatedArgsShape(args, op, depth) {
|
|
7167
7169
|
if (args === void 0) return [];
|
|
7168
|
-
if (!
|
|
7170
|
+
if (!isPlainObject15(args)) return ["Correlated include args must be an object"];
|
|
7169
7171
|
const record3 = args;
|
|
7170
7172
|
const allowed = op === "list" ? /* @__PURE__ */ new Set(["select", "sort", "skip", "limit", "page", "pageSize", "include"]) : /* @__PURE__ */ new Set(["select", "sort", "include"]);
|
|
7171
7173
|
for (const key of Object.keys(record3)) {
|
|
@@ -7187,7 +7189,7 @@ function validateCorrelatedArgsShape(args, op, depth) {
|
|
|
7187
7189
|
return [];
|
|
7188
7190
|
}
|
|
7189
7191
|
function validateCorrelatedIncludeShape(entry, depth = 0) {
|
|
7190
|
-
if (!
|
|
7192
|
+
if (!isPlainObject15(entry)) return ["Correlated include must be an object"];
|
|
7191
7193
|
const record3 = entry;
|
|
7192
7194
|
if (record3.mode !== "correlated") return ['Correlated include mode must be "correlated"'];
|
|
7193
7195
|
if (typeof record3.model !== "string" || record3.model.length === 0)
|
|
@@ -7200,7 +7202,7 @@ function validateCorrelatedIncludeShape(entry, depth = 0) {
|
|
|
7200
7202
|
if ("localField" in record3 || "foreignField" in record3) {
|
|
7201
7203
|
return ["Correlated includes must not carry localField or foreignField"];
|
|
7202
7204
|
}
|
|
7203
|
-
if (record3.options !== void 0 && !(
|
|
7205
|
+
if (record3.options !== void 0 && !(isPlainObject15(record3.options) && Object.keys(record3.options).length === 0)) {
|
|
7204
7206
|
return ["Correlated include options must be absent or empty"];
|
|
7205
7207
|
}
|
|
7206
7208
|
const hasId = record3.id !== void 0;
|
|
@@ -7222,7 +7224,7 @@ function validateCorrelatedIncludeShape(entry, depth = 0) {
|
|
|
7222
7224
|
return validateCorrelatedArgsShape(record3.args, record3.op, depth);
|
|
7223
7225
|
}
|
|
7224
7226
|
function isCorrelatedInclude(value) {
|
|
7225
|
-
return
|
|
7227
|
+
return isPlainObject15(value) && value.mode === "correlated";
|
|
7226
7228
|
}
|
|
7227
7229
|
|
|
7228
7230
|
// src/services/base.ts
|
|
@@ -7446,9 +7448,31 @@ function castCountGroups(input, values) {
|
|
|
7446
7448
|
// src/services/base.ts
|
|
7447
7449
|
init_service_authorization();
|
|
7448
7450
|
|
|
7451
|
+
// src/meta.ts
|
|
7452
|
+
init_runtime();
|
|
7453
|
+
init_runtime_context();
|
|
7454
|
+
var getRuntime5 = () => getActiveRuntime() ?? defaultRuntime;
|
|
7455
|
+
var getModelRef = (modelName, refPath, runtime = getRuntime5()) => {
|
|
7456
|
+
const direct = runtime.getModelRef(modelName, refPath);
|
|
7457
|
+
if (direct) return direct;
|
|
7458
|
+
if (!refPath.includes(".")) return null;
|
|
7459
|
+
try {
|
|
7460
|
+
const instance = runtime.getModelInstance?.(
|
|
7461
|
+
modelName
|
|
7462
|
+
);
|
|
7463
|
+
const schemaPath = instance?.schema?.path?.(refPath);
|
|
7464
|
+
const element = schemaPath?.$embeddedSchemaType ?? schemaPath?.embeddedSchemaType ?? schemaPath?.caster;
|
|
7465
|
+
const ref = schemaPath?.options?.ref ?? element?.options?.ref ?? null;
|
|
7466
|
+
return typeof ref === "string" && ref.length > 0 ? ref : null;
|
|
7467
|
+
} catch {
|
|
7468
|
+
return null;
|
|
7469
|
+
}
|
|
7470
|
+
};
|
|
7471
|
+
|
|
7449
7472
|
// src/acl/related-execution.ts
|
|
7450
7473
|
init_public_admission();
|
|
7451
7474
|
init_model_output_planning();
|
|
7475
|
+
init_populate_target_configuration();
|
|
7452
7476
|
init_authorization_snapshot();
|
|
7453
7477
|
|
|
7454
7478
|
// src/acl/service-execution.ts
|
|
@@ -7743,16 +7767,15 @@ function captureRelatedTargets(runtime, modelName, args = {}, depth = 0, globalO
|
|
|
7743
7767
|
for (const entry of entries(args.populate)) {
|
|
7744
7768
|
const path = typeof entry === "string" ? entry : entry.path;
|
|
7745
7769
|
if (typeof entry !== "string") assertPopulateAccess(entry.access);
|
|
7746
|
-
const model = getModelRef(modelName, path);
|
|
7747
|
-
if (model
|
|
7770
|
+
const model = getModelRef(modelName, path, runtime);
|
|
7771
|
+
if (model) {
|
|
7772
|
+
const target = capturePopulateTargetConfiguration(runtime, model, `${modelName}.${path}`);
|
|
7748
7773
|
targets.push({
|
|
7749
7774
|
path,
|
|
7750
7775
|
modelName: model,
|
|
7751
|
-
configuration: captureModelAuthorizationConfiguration(runtime, model,
|
|
7776
|
+
configuration: captureModelAuthorizationConfiguration(runtime, model, target.options, globalOptions),
|
|
7752
7777
|
staticObjectIdReference: staticObjectIdReference(runtime, modelName, path, model)
|
|
7753
7778
|
});
|
|
7754
|
-
else if (model && !(globalOptions.requireRegisteredPopulateModels === void 0 ? true : globalOptions.requireRegisteredPopulateModels)) {
|
|
7755
|
-
targets.push({ path, modelName: model, kind: "passthrough", configuration: { catalog: { paths: [] } } });
|
|
7756
7779
|
}
|
|
7757
7780
|
}
|
|
7758
7781
|
for (const entry of entries(args.include)) {
|
|
@@ -7938,20 +7961,20 @@ var copyAuthorizedOutput = (value) => {
|
|
|
7938
7961
|
transferDocumentAuthorizationGraph(value, copy);
|
|
7939
7962
|
return copy;
|
|
7940
7963
|
};
|
|
7941
|
-
var isVirtualContainerValueForGuard = (value) =>
|
|
7964
|
+
var isVirtualContainerValueForGuard = (value) => isPlainObject18(value) && "sub" in value;
|
|
7942
7965
|
var getScopeVirtualsForGuard = (rootVirtuals, scopePath) => {
|
|
7943
|
-
if (!rootVirtuals || !
|
|
7966
|
+
if (!rootVirtuals || !isPlainObject18(rootVirtuals)) return null;
|
|
7944
7967
|
if (scopePath.length === 0) return rootVirtuals;
|
|
7945
7968
|
let current = rootVirtuals;
|
|
7946
7969
|
for (let i = 0; i < scopePath.length; i += 2) {
|
|
7947
7970
|
const field = scopePath[i];
|
|
7948
7971
|
const subMarker = scopePath[i + 1];
|
|
7949
7972
|
if (!field || subMarker !== "sub") return null;
|
|
7950
|
-
if (!
|
|
7973
|
+
if (!isPlainObject18(current)) return null;
|
|
7951
7974
|
const container = current[field];
|
|
7952
7975
|
if (!isVirtualContainerValueForGuard(container)) return null;
|
|
7953
7976
|
current = container.sub;
|
|
7954
|
-
if (!
|
|
7977
|
+
if (!isPlainObject18(current)) return null;
|
|
7955
7978
|
}
|
|
7956
7979
|
return current;
|
|
7957
7980
|
};
|
|
@@ -8017,7 +8040,7 @@ var sanitizeSubScopeVirtualKeys = (data, snapshot, sub) => {
|
|
|
8017
8040
|
for (const entry of value) stripScope(entry, currentScope);
|
|
8018
8041
|
return;
|
|
8019
8042
|
}
|
|
8020
|
-
if (!
|
|
8043
|
+
if (!isPlainObject18(value)) return;
|
|
8021
8044
|
const record3 = value;
|
|
8022
8045
|
const leaves = getScopeVirtualLeafNames(snapshot, currentScope);
|
|
8023
8046
|
for (const leaf of leaves) {
|
|
@@ -8030,7 +8053,7 @@ var sanitizeSubScopeVirtualKeys = (data, snapshot, sub) => {
|
|
|
8030
8053
|
for (const key of Object.keys(record3)) {
|
|
8031
8054
|
if (leaves.has(key) || containers.has(key)) continue;
|
|
8032
8055
|
const child = record3[key];
|
|
8033
|
-
if (Array.isArray(child) ||
|
|
8056
|
+
if (Array.isArray(child) || isPlainObject18(child)) {
|
|
8034
8057
|
stripScope(child, currentScope);
|
|
8035
8058
|
}
|
|
8036
8059
|
}
|
|
@@ -8042,7 +8065,7 @@ var LOGICAL_FILTER_KEYS = /* @__PURE__ */ new Set(["$and", "$or", "$nor"]);
|
|
|
8042
8065
|
var isOperatorKey = (key) => key.startsWith("$");
|
|
8043
8066
|
var REMOVED_VIRTUAL_FILTER = /* @__PURE__ */ Symbol("removed virtual filter clause");
|
|
8044
8067
|
var rewriteFilterObject = (value, visit) => {
|
|
8045
|
-
if (!
|
|
8068
|
+
if (!isPlainObject18(value)) return value;
|
|
8046
8069
|
let changed = false;
|
|
8047
8070
|
const entries = [];
|
|
8048
8071
|
for (const [key, child] of Object.entries(value)) {
|
|
@@ -8073,7 +8096,7 @@ var resolveVirtualFilterField = (path, scope2) => {
|
|
|
8073
8096
|
if (!Object.hasOwn(scope2, segment) || scope2[segment] === void 0) return null;
|
|
8074
8097
|
const definition = scope2[segment];
|
|
8075
8098
|
if (!isVirtualContainerValueForGuard(definition)) return REMOVED_VIRTUAL_FILTER;
|
|
8076
|
-
scope2 =
|
|
8099
|
+
scope2 = isPlainObject18(definition.sub) ? definition.sub : null;
|
|
8077
8100
|
inContainer = true;
|
|
8078
8101
|
}
|
|
8079
8102
|
return scope2;
|
|
@@ -8085,7 +8108,7 @@ var stripVirtualFilterOperator = (key, value, scope2) => {
|
|
|
8085
8108
|
}
|
|
8086
8109
|
if (key === "$all") {
|
|
8087
8110
|
return rewriteFilterClauses(value, (entry) => {
|
|
8088
|
-
if (!
|
|
8111
|
+
if (!isPlainObject18(entry) || Object.keys(entry).length !== 1 || !Object.hasOwn(entry, "$elemMatch")) return entry;
|
|
8089
8112
|
return rewriteFilterObject(entry, (operator, operand) => stripVirtualFilterOperator(operator, operand, scope2));
|
|
8090
8113
|
});
|
|
8091
8114
|
}
|
|
@@ -8100,7 +8123,7 @@ var stripVirtualFilterQuery = (value, scope2, element = false) => {
|
|
|
8100
8123
|
if (isOperatorKey(key)) return element ? stripVirtualFilterOperator(key, child, scope2) : child;
|
|
8101
8124
|
const fieldScope = resolveVirtualFilterField(key, scope2);
|
|
8102
8125
|
if (fieldScope === REMOVED_VIRTUAL_FILTER) return REMOVED_VIRTUAL_FILTER;
|
|
8103
|
-
if (!fieldScope || !
|
|
8126
|
+
if (!fieldScope || !isPlainObject18(child)) return child;
|
|
8104
8127
|
if (Object.keys(child).some(isOperatorKey)) {
|
|
8105
8128
|
return rewriteFilterObject(
|
|
8106
8129
|
child,
|
|
@@ -8124,7 +8147,7 @@ function getCorrelatedTemplateDepth(includes) {
|
|
|
8124
8147
|
const visit = (entries, depth) => {
|
|
8125
8148
|
const list = castArray2(entries).filter(Boolean);
|
|
8126
8149
|
for (const entry of list) {
|
|
8127
|
-
if (!
|
|
8150
|
+
if (!isPlainObject18(entry)) continue;
|
|
8128
8151
|
max = Math.max(max, depth);
|
|
8129
8152
|
const nested = entry.args?.include;
|
|
8130
8153
|
if (nested !== void 0) {
|
|
@@ -8153,7 +8176,7 @@ function validateClientFilter(filter2) {
|
|
|
8153
8176
|
value.forEach((item, index) => visit(item, `${path}[${index}]`));
|
|
8154
8177
|
return;
|
|
8155
8178
|
}
|
|
8156
|
-
if (!
|
|
8179
|
+
if (!isPlainObject18(value)) return;
|
|
8157
8180
|
Object.entries(value).forEach(([key, child]) => {
|
|
8158
8181
|
const nextPath = path ? `${path}.${key}` : key;
|
|
8159
8182
|
if (blockedOperators.has(key)) {
|
|
@@ -8435,9 +8458,9 @@ var Base = class {
|
|
|
8435
8458
|
const walk = (node, prefix) => {
|
|
8436
8459
|
for (const [key, value] of Object.entries(node)) {
|
|
8437
8460
|
if (value === void 0) continue;
|
|
8438
|
-
if (
|
|
8461
|
+
if (isPlainObject18(value) && "sub" in value) {
|
|
8439
8462
|
const sub = value.sub;
|
|
8440
|
-
if (
|
|
8463
|
+
if (isPlainObject18(sub)) walk(sub, prefix ? `${prefix}.${key}` : key);
|
|
8441
8464
|
continue;
|
|
8442
8465
|
}
|
|
8443
8466
|
out.push(prefix ? `${prefix}.${key}` : key);
|
|
@@ -8490,7 +8513,7 @@ var Base = class {
|
|
|
8490
8513
|
this.throwClientRequestError("bad_request" /* BadRequest */, `Model ${modelName} not found`);
|
|
8491
8514
|
}
|
|
8492
8515
|
for (const entry of entries) {
|
|
8493
|
-
if (!
|
|
8516
|
+
if (!isPlainObject18(entry)) continue;
|
|
8494
8517
|
const models = visited.get(entry) ?? /* @__PURE__ */ new Set();
|
|
8495
8518
|
if (models.has(modelName)) continue;
|
|
8496
8519
|
models.add(modelName);
|
|
@@ -9109,7 +9132,7 @@ import {
|
|
|
9109
9132
|
get as get13,
|
|
9110
9133
|
isArray as isArray10,
|
|
9111
9134
|
isBoolean as isBoolean4,
|
|
9112
|
-
isPlainObject as
|
|
9135
|
+
isPlainObject as isPlainObject25,
|
|
9113
9136
|
omit,
|
|
9114
9137
|
set as set10,
|
|
9115
9138
|
uniq as uniq2,
|
|
@@ -9210,7 +9233,7 @@ var model_default = Model;
|
|
|
9210
9233
|
// src/acl/distinct-field-authorization.ts
|
|
9211
9234
|
init_field_authorization();
|
|
9212
9235
|
init_field_catalog();
|
|
9213
|
-
import { isPlainObject as
|
|
9236
|
+
import { isPlainObject as isPlainObject19 } from "@web-ts-toolkit/utils";
|
|
9214
9237
|
var schemaVariants = (schema) => Object.values(schema.discriminators ?? {});
|
|
9215
9238
|
var scalarTypes = /* @__PURE__ */ new Set([
|
|
9216
9239
|
"String",
|
|
@@ -9290,8 +9313,8 @@ function isDistinctFieldAuthorized(args) {
|
|
|
9290
9313
|
if (path !== field && !path.startsWith(`${field}.`) && !field.startsWith(`${path}.`)) continue;
|
|
9291
9314
|
if (path.startsWith(`${field}.`) && (!eligible(path) || !schemaShape(schema, path) || !granted(path)))
|
|
9292
9315
|
return false;
|
|
9293
|
-
if (
|
|
9294
|
-
if (!
|
|
9316
|
+
if (isPlainObject19(raw) && raw.sub !== void 0) {
|
|
9317
|
+
if (!isPlainObject19(raw.sub) || !declaredRulesSafe(raw.sub, path, next)) return false;
|
|
9295
9318
|
}
|
|
9296
9319
|
}
|
|
9297
9320
|
return true;
|
|
@@ -9469,7 +9492,7 @@ init_populate_target();
|
|
|
9469
9492
|
|
|
9470
9493
|
// src/helpers/apply-update.ts
|
|
9471
9494
|
init_lib();
|
|
9472
|
-
import { isPlainObject as
|
|
9495
|
+
import { isPlainObject as isPlainObject23, set as set8 } from "@web-ts-toolkit/utils";
|
|
9473
9496
|
function applyUpdate(target, data, allowedFields) {
|
|
9474
9497
|
const wholeFields = /* @__PURE__ */ new Set();
|
|
9475
9498
|
const partialContainers = /* @__PURE__ */ new Set();
|
|
@@ -9489,7 +9512,7 @@ function applyUpdate(target, data, allowedFields) {
|
|
|
9489
9512
|
const apply = (values, prefix = "") => {
|
|
9490
9513
|
for (const [key, value] of Object.entries(values)) {
|
|
9491
9514
|
const path = prefix ? `${prefix}.${key}` : key;
|
|
9492
|
-
if (partialContainers.has(path) && !wholeFields.has(path) && (
|
|
9515
|
+
if (partialContainers.has(path) && !wholeFields.has(path) && (isPlainObject23(value) || Array.isArray(value))) {
|
|
9493
9516
|
apply(value, path);
|
|
9494
9517
|
} else if (isDocument2(target)) {
|
|
9495
9518
|
target.set(path, value);
|
|
@@ -9506,7 +9529,7 @@ init_document();
|
|
|
9506
9529
|
init_request_work();
|
|
9507
9530
|
init_logger_helpers();
|
|
9508
9531
|
init_request_complexity();
|
|
9509
|
-
import { get as get10, isPlainObject as
|
|
9532
|
+
import { get as get10, isPlainObject as isPlainObject24, set as set9 } from "@web-ts-toolkit/utils";
|
|
9510
9533
|
import { mongo as mongo5 } from "mongoose";
|
|
9511
9534
|
|
|
9512
9535
|
// src/acl/select-resolution.ts
|
|
@@ -9623,7 +9646,7 @@ init_field_catalog();
|
|
|
9623
9646
|
init_service_authorization();
|
|
9624
9647
|
var own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
9625
9648
|
var inside = (path, root) => path === root || path.startsWith(`${root}.`);
|
|
9626
|
-
var record2 = (value) =>
|
|
9649
|
+
var record2 = (value) => isPlainObject24(value);
|
|
9627
9650
|
function inputValue(value) {
|
|
9628
9651
|
if (typeof value === "function" || typeof value === "symbol") {
|
|
9629
9652
|
authorizationError("input values must be persisted data, not functions or symbols");
|
|
@@ -10979,10 +11002,6 @@ var Service = class extends Base {
|
|
|
10979
11002
|
const target = captured.relatedTargets.find((target2) => target2.path === descriptor.path);
|
|
10980
11003
|
const modelName = target?.modelName;
|
|
10981
11004
|
if (!modelName) continue;
|
|
10982
|
-
if (target.kind === "passthrough") {
|
|
10983
|
-
result2.push({ path: descriptor.path, select: descriptor.select });
|
|
10984
|
-
continue;
|
|
10985
|
-
}
|
|
10986
11005
|
const policy = relatedPolicy(state.authorization, state.binding, descriptor.path);
|
|
10987
11006
|
const svc = this.requestCore.getPublicService(modelName);
|
|
10988
11007
|
const child = createRelatedExecution(
|
|
@@ -11001,7 +11020,7 @@ var Service = class extends Base {
|
|
|
11001
11020
|
if (isExecutionRowDenied(svc, child)) continue;
|
|
11002
11021
|
const childState = readServiceExecution(svc, child);
|
|
11003
11022
|
const targetConfiguration = readServiceAuthorization(childState.authorization, childState.binding).configuration;
|
|
11004
|
-
if (policy?.operation.mode !== "grant" && !await this.hookGate.run(
|
|
11023
|
+
if (targetConfiguration.requireOperationAccessForPopulateQueries !== false && policy?.operation.mode !== "grant" && !await this.hookGate.run(
|
|
11005
11024
|
() => evaluateRouteGuard(
|
|
11006
11025
|
this.req,
|
|
11007
11026
|
getAuthorizationPermissions(childState.authorization, childState.binding),
|
|
@@ -11053,7 +11072,7 @@ var Service = class extends Base {
|
|
|
11053
11072
|
if (this.isScalarPopulateValue(rawTarget)) return rawTarget;
|
|
11054
11073
|
const isDoc = (() => {
|
|
11055
11074
|
try {
|
|
11056
|
-
if (
|
|
11075
|
+
if (isPlainObject25(rawTarget)) return true;
|
|
11057
11076
|
const maybe = rawTarget;
|
|
11058
11077
|
if (maybe && typeof maybe === "object" && "_doc" in maybe) return true;
|
|
11059
11078
|
if (maybe && typeof maybe.toObject === "function") return true;
|
|
@@ -13456,7 +13475,7 @@ init_helpers();
|
|
|
13456
13475
|
|
|
13457
13476
|
// src/processors.ts
|
|
13458
13477
|
init_permissions_alias();
|
|
13459
|
-
import { cloneDeep as cloneDeep5, forEach as forEach5, get as get14, hasOwn as hasOwn3, isArray as isArray11, isPlainObject as
|
|
13478
|
+
import { cloneDeep as cloneDeep5, forEach as forEach5, get as get14, hasOwn as hasOwn3, isArray as isArray11, isPlainObject as isPlainObject26, map, set as set11 } from "@web-ts-toolkit/utils";
|
|
13460
13479
|
function cloneProcessorValue(value) {
|
|
13461
13480
|
const copy = cloneDeep5(value);
|
|
13462
13481
|
copyPermissionsAliasGraph(value, copy);
|
|
@@ -13496,7 +13515,7 @@ function resolveLeafParents(obj, src) {
|
|
|
13496
13515
|
for (let ind = 0; ind < segs.length - 1; ind += 1) {
|
|
13497
13516
|
const seg = segs[ind];
|
|
13498
13517
|
targets = targets.reduce((ret, target) => {
|
|
13499
|
-
if (!
|
|
13518
|
+
if (!isPlainObject26(target)) return ret;
|
|
13500
13519
|
const targetObject = target;
|
|
13501
13520
|
const next = targetObject[seg];
|
|
13502
13521
|
if (isArray11(next)) {
|
|
@@ -13510,7 +13529,7 @@ function resolveLeafParents(obj, src) {
|
|
|
13510
13529
|
const leaf = segs[segs.length - 1];
|
|
13511
13530
|
const pairs = [];
|
|
13512
13531
|
forEach5(targets, (target) => {
|
|
13513
|
-
if (!
|
|
13532
|
+
if (!isPlainObject26(target)) return;
|
|
13514
13533
|
pairs.push({ parent: target, leaf });
|
|
13515
13534
|
});
|
|
13516
13535
|
return pairs;
|
|
@@ -13531,7 +13550,7 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
13531
13550
|
forEach5(segs, (seg, ind) => {
|
|
13532
13551
|
if (segs.length === ind + 1) {
|
|
13533
13552
|
forEach5(targets, (target) => {
|
|
13534
|
-
if (!
|
|
13553
|
+
if (!isPlainObject26(target)) return;
|
|
13535
13554
|
const targetObject = target;
|
|
13536
13555
|
const leaf = targetObject[seg];
|
|
13537
13556
|
const sourceForDest = leaf;
|
|
@@ -13539,7 +13558,7 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
13539
13558
|
if (isArray11(leaf)) {
|
|
13540
13559
|
if (leaf.length === 0) {
|
|
13541
13560
|
depopulated = [];
|
|
13542
|
-
} else if (leaf.every((item) =>
|
|
13561
|
+
} else if (leaf.every((item) => isPlainObject26(item))) {
|
|
13543
13562
|
depopulated = map(leaf, idField).map((id, i) => {
|
|
13544
13563
|
if (id === void 0) {
|
|
13545
13564
|
failMissingId(`${src}[${i}]`);
|
|
@@ -13549,7 +13568,7 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
13549
13568
|
} else {
|
|
13550
13569
|
return;
|
|
13551
13570
|
}
|
|
13552
|
-
} else if (
|
|
13571
|
+
} else if (isPlainObject26(leaf)) {
|
|
13553
13572
|
const id = get14(leaf, idField);
|
|
13554
13573
|
if (id === void 0) {
|
|
13555
13574
|
failMissingId(src);
|
|
@@ -13563,7 +13582,7 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
|
|
|
13563
13582
|
});
|
|
13564
13583
|
} else {
|
|
13565
13584
|
targets = targets.reduce((ret, target) => {
|
|
13566
|
-
if (!
|
|
13585
|
+
if (!isPlainObject26(target)) return ret;
|
|
13567
13586
|
const targetObject = target;
|
|
13568
13587
|
const next = targetObject[seg];
|
|
13569
13588
|
if (isArray11(next)) {
|
|
@@ -13669,7 +13688,7 @@ var countPaths = (docObject, operations, options = { mutable: true }) => {
|
|
|
13669
13688
|
let count;
|
|
13670
13689
|
if (isArray11(leafValue)) {
|
|
13671
13690
|
count = leafValue.length;
|
|
13672
|
-
} else if (
|
|
13691
|
+
} else if (isPlainObject26(leafValue)) {
|
|
13673
13692
|
count = Object.keys(leafValue).length;
|
|
13674
13693
|
} else if (leafValue === null || typeof leafValue === "undefined") {
|
|
13675
13694
|
count = 0;
|
|
@@ -13747,6 +13766,8 @@ init_core_shared();
|
|
|
13747
13766
|
init_virtual_projection();
|
|
13748
13767
|
init_populate_target();
|
|
13749
13768
|
init_model_output_planning();
|
|
13769
|
+
init_authorization_snapshot();
|
|
13770
|
+
init_document();
|
|
13750
13771
|
init_output_field_filter();
|
|
13751
13772
|
init_request_work();
|
|
13752
13773
|
var emptyPermissionLeaf = () => ({ $: "_" });
|
|
@@ -13857,17 +13878,11 @@ var Core = class {
|
|
|
13857
13878
|
return this.genSelect(modelName, access, targetFields, options);
|
|
13858
13879
|
}
|
|
13859
13880
|
/** Persisted request-only populate admission; fetch planning is not field authority. */
|
|
13860
|
-
async requestPopulateSelect(
|
|
13881
|
+
async requestPopulateSelect(configuration, permissions, access, targetFields = null, scopePath = []) {
|
|
13861
13882
|
const subPaths = scopePath.flatMap((part) => [part, "sub"]);
|
|
13862
|
-
const permissionSchema =
|
|
13863
|
-
const
|
|
13864
|
-
|
|
13865
|
-
try {
|
|
13866
|
-
const runtime = getActiveRuntime() ?? defaultRuntime;
|
|
13867
|
-
virtualNames = runtime.getVirtualNames(modelName, subPaths);
|
|
13868
|
-
} catch {
|
|
13869
|
-
virtualNames = [];
|
|
13870
|
-
}
|
|
13883
|
+
const permissionSchema = get15(configuration, ["permissionSchema", ...subPaths]);
|
|
13884
|
+
const prefix = scopePath.length ? `${scopePath.join(".")}.` : "";
|
|
13885
|
+
const virtualNames = (configuration.catalog.virtualPaths ?? []).filter((path) => path.startsWith(prefix)).map((path) => path.slice(prefix.length)).filter((path) => !path.includes("."));
|
|
13871
13886
|
return resolveSelectForRequest({
|
|
13872
13887
|
req: this.req,
|
|
13873
13888
|
permissionSchema,
|
|
@@ -13886,13 +13901,21 @@ var Core = class {
|
|
|
13886
13901
|
assertPublicAdmission(_populate, "populate");
|
|
13887
13902
|
assertPopulateAccess(access);
|
|
13888
13903
|
if (!_populate) return [];
|
|
13889
|
-
|
|
13890
|
-
for (const p of
|
|
13904
|
+
const descriptors = copyAuthorizationValue(Array.isArray(_populate) ? _populate : [_populate], true);
|
|
13905
|
+
for (const p of descriptors) {
|
|
13891
13906
|
if (!isString6(p)) assertPopulateAccess(p.access);
|
|
13892
13907
|
}
|
|
13893
|
-
|
|
13908
|
+
const runtime = this.requestRuntime;
|
|
13909
|
+
const globalOptions = modelServiceGlobalOptions(this, runtime);
|
|
13910
|
+
const relatedTargets = captureRelatedTargets(runtime, modelName, { populate: descriptors }, 0, globalOptions);
|
|
13911
|
+
const sourceConfiguration = captureModelAuthorizationConfiguration(runtime, modelName, void 0, globalOptions);
|
|
13912
|
+
const originalPermissions = this.getGlobalPermissions();
|
|
13913
|
+
const permissions = new permission_default(
|
|
13914
|
+
Object.fromEntries(originalPermissions.keys.map((key) => [key, originalPermissions.has(key)]))
|
|
13915
|
+
);
|
|
13916
|
+
const populate = compact3(
|
|
13894
13917
|
await Promise.all(
|
|
13895
|
-
|
|
13918
|
+
descriptors.map(async (p) => {
|
|
13896
13919
|
const populateAccess = !isString6(p) && p.access ? p.access : access;
|
|
13897
13920
|
assertPopulateAccess(populateAccess);
|
|
13898
13921
|
const originalSelect = isString6(p) ? void 0 : p.select;
|
|
@@ -13904,78 +13927,86 @@ var Core = class {
|
|
|
13904
13927
|
const pathForSourcePermission = scopePrefix && ret.path.startsWith(`${scopePrefix}.`) ? ret.path.slice(scopePrefix.length + 1) : ret.path;
|
|
13905
13928
|
const parentPath = pathForSourcePermission.includes(".") ? pathForSourcePermission.split(".")[0] : pathForSourcePermission;
|
|
13906
13929
|
const allowedParentPaths = await this.requestPopulateSelect(
|
|
13907
|
-
|
|
13930
|
+
sourceConfiguration,
|
|
13931
|
+
permissions,
|
|
13908
13932
|
populateAccess,
|
|
13909
13933
|
[parentPath],
|
|
13910
13934
|
scopePath
|
|
13911
13935
|
);
|
|
13912
13936
|
if (!allowedParentPaths.includes(parentPath)) return null;
|
|
13913
|
-
const
|
|
13914
|
-
if (!
|
|
13915
|
-
const
|
|
13916
|
-
|
|
13917
|
-
|
|
13918
|
-
|
|
13919
|
-
|
|
13920
|
-
|
|
13921
|
-
|
|
13922
|
-
|
|
13937
|
+
const target = relatedTargets.find((entry) => entry.path === ret.path);
|
|
13938
|
+
if (!target) return null;
|
|
13939
|
+
const refModelName = target.modelName;
|
|
13940
|
+
const targetConfiguration = target.configuration;
|
|
13941
|
+
if (targetConfiguration.requireOperationAccessForPopulateQueries !== false && !await withCapturedModelOperationGuard(
|
|
13942
|
+
this,
|
|
13943
|
+
refModelName,
|
|
13944
|
+
populateAccess,
|
|
13945
|
+
getCapturedAuthorizationOption(targetConfiguration, `operationAccess.${populateAccess}`),
|
|
13946
|
+
permissions,
|
|
13947
|
+
() => this.isAllowed(refModelName, populateAccess)
|
|
13948
|
+
)) {
|
|
13923
13949
|
return null;
|
|
13924
13950
|
}
|
|
13925
|
-
ret.select = await this.requestPopulateSelect(
|
|
13926
|
-
|
|
13927
|
-
|
|
13928
|
-
|
|
13951
|
+
ret.select = await this.requestPopulateSelect(
|
|
13952
|
+
targetConfiguration,
|
|
13953
|
+
permissions,
|
|
13954
|
+
populateAccess,
|
|
13955
|
+
ret.select
|
|
13956
|
+
);
|
|
13957
|
+
const hookInputs = resolveAlwaysSelectForAccess(
|
|
13958
|
+
targetConfiguration.alwaysSelectFields,
|
|
13959
|
+
populateAccess
|
|
13960
|
+
);
|
|
13961
|
+
ret.select = uniq3([
|
|
13962
|
+
...ret.select,
|
|
13963
|
+
...stripVirtuals(hookInputs, [...targetConfiguration.catalog.virtualPaths ?? []])
|
|
13964
|
+
]);
|
|
13965
|
+
const match = isString6(p) ? {} : p.match ?? {};
|
|
13966
|
+
const filter2 = await resolveAccessFilterForRequest({
|
|
13967
|
+
req: this.req,
|
|
13968
|
+
permissions,
|
|
13969
|
+
cache: this.caches.baseFilter,
|
|
13970
|
+
cacheKey: `${refModelName}_baseFilter_${populateAccess}`,
|
|
13971
|
+
access: populateAccess,
|
|
13972
|
+
filter: deepIsolateValue(match),
|
|
13973
|
+
getOption: (key) => getCapturedAuthorizationOption(targetConfiguration, key)
|
|
13974
|
+
});
|
|
13929
13975
|
if (filter2 === false) return null;
|
|
13930
|
-
ret.match = filter2;
|
|
13931
|
-
|
|
13932
|
-
|
|
13933
|
-
|
|
13934
|
-
|
|
13935
|
-
|
|
13936
|
-
|
|
13937
|
-
|
|
13938
|
-
|
|
13939
|
-
|
|
13940
|
-
|
|
13941
|
-
|
|
13942
|
-
|
|
13943
|
-
|
|
13944
|
-
|
|
13945
|
-
|
|
13946
|
-
|
|
13947
|
-
|
|
13948
|
-
|
|
13949
|
-
|
|
13950
|
-
|
|
13951
|
-
|
|
13952
|
-
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
13958
|
-
|
|
13959
|
-
|
|
13960
|
-
|
|
13961
|
-
|
|
13962
|
-
|
|
13963
|
-
|
|
13964
|
-
(t) => t !== "-_id" && !t.includes(".sub.")
|
|
13965
|
-
);
|
|
13966
|
-
if (!merged.includes("_id")) merged.push("_id");
|
|
13967
|
-
ret.select = merged;
|
|
13968
|
-
setPopulateTargetMeta(ret, {
|
|
13969
|
-
targetModelName: refModelName,
|
|
13970
|
-
virtualAccess: planAccess,
|
|
13971
|
-
outputAccess: planAccess,
|
|
13972
|
-
docPermissionsAccess: planAccess,
|
|
13973
|
-
requestedSelect: originalSelect,
|
|
13974
|
-
plan: targetPlan,
|
|
13975
|
-
snapshot: targetSnapshot
|
|
13976
|
-
});
|
|
13977
|
-
} catch {
|
|
13978
|
-
}
|
|
13976
|
+
ret.match = deepIsolateValue(intersectFilters(match, filter2));
|
|
13977
|
+
const planAccess = populateAccess;
|
|
13978
|
+
const targetSnapshot = targetConfiguration;
|
|
13979
|
+
const targetPlan = planVirtualProjection({
|
|
13980
|
+
receivingModelName: refModelName,
|
|
13981
|
+
snapshot: {
|
|
13982
|
+
permissionSchema: targetSnapshot.permissionSchema,
|
|
13983
|
+
virtuals: targetSnapshot.virtuals,
|
|
13984
|
+
alwaysSelectFields: targetSnapshot.alwaysSelectFields,
|
|
13985
|
+
modelPermissionPrefix: targetSnapshot.modelPermissionPrefix,
|
|
13986
|
+
requireExplicitSelect: targetSnapshot.requireExplicitSelect,
|
|
13987
|
+
documentPermissionField: targetSnapshot.documentPermissionField
|
|
13988
|
+
},
|
|
13989
|
+
virtualAccess: planAccess,
|
|
13990
|
+
outputAccess: planAccess,
|
|
13991
|
+
docPermissionsAccess: planAccess,
|
|
13992
|
+
requestedSelect: originalSelect,
|
|
13993
|
+
internalFetch: { baseFields: ["_id"] },
|
|
13994
|
+
globalPermissions: permissions
|
|
13995
|
+
});
|
|
13996
|
+
const merged = uniq3([...normalizeSelect(ret.select), ...targetPlan.virtualOnlyDeps ?? []]).filter(
|
|
13997
|
+
(t) => t !== "-_id" && !t.includes(".sub.")
|
|
13998
|
+
);
|
|
13999
|
+
if (!merged.includes("_id")) merged.push("_id");
|
|
14000
|
+
ret.select = merged;
|
|
14001
|
+
setPopulateTargetMeta(ret, {
|
|
14002
|
+
targetModelName: refModelName,
|
|
14003
|
+
virtualAccess: planAccess,
|
|
14004
|
+
outputAccess: planAccess,
|
|
14005
|
+
docPermissionsAccess: planAccess,
|
|
14006
|
+
requestedSelect: originalSelect,
|
|
14007
|
+
plan: targetPlan,
|
|
14008
|
+
snapshot: targetSnapshot
|
|
14009
|
+
});
|
|
13979
14010
|
return ret;
|
|
13980
14011
|
})
|
|
13981
14012
|
)
|
|
@@ -14299,12 +14330,12 @@ function guard(condition) {
|
|
|
14299
14330
|
const permissions = req[PERMISSIONS];
|
|
14300
14331
|
let cond = condition;
|
|
14301
14332
|
let phas = (key) => permissions.has(key);
|
|
14302
|
-
if (
|
|
14333
|
+
if (isPlainObject27(condition)) {
|
|
14303
14334
|
const { modelName, id, condition: _cond } = condition;
|
|
14304
14335
|
const svc = req.macl.getPublicService(modelName);
|
|
14305
14336
|
const select = getModelOption(modelName, `alwaysSelectFields.read`, void 0);
|
|
14306
14337
|
let _id = isString7(id) ? id : null;
|
|
14307
|
-
if (
|
|
14338
|
+
if (isPlainObject27(id)) {
|
|
14308
14339
|
const { type = "param", key } = id;
|
|
14309
14340
|
if (type === "param") {
|
|
14310
14341
|
const paramValue = req.params[key];
|
|
@@ -14346,7 +14377,7 @@ import express2 from "express";
|
|
|
14346
14377
|
|
|
14347
14378
|
// src/routers/model-router.ts
|
|
14348
14379
|
import JsonRouter8 from "@web-ts-toolkit/express-json-router";
|
|
14349
|
-
import { forEach as forEach7, isPlainObject as
|
|
14380
|
+
import { forEach as forEach7, isPlainObject as isPlainObject29, isString as isString8, isUndefined as isUndefined2, normalizeUrlPath as normalizeUrlPath3, padEnd } from "@web-ts-toolkit/utils";
|
|
14350
14381
|
init_logger_helpers();
|
|
14351
14382
|
init_runtime();
|
|
14352
14383
|
init_runtime_context();
|
|
@@ -14480,7 +14511,7 @@ import JsonRouter7 from "@web-ts-toolkit/express-json-router";
|
|
|
14480
14511
|
|
|
14481
14512
|
// src/validation/common.ts
|
|
14482
14513
|
import { z as z2 } from "zod";
|
|
14483
|
-
import { isPlainObject as
|
|
14514
|
+
import { isPlainObject as isPlainObject28 } from "@web-ts-toolkit/utils";
|
|
14484
14515
|
|
|
14485
14516
|
// src/validation/public-admission-schema.ts
|
|
14486
14517
|
init_public_admission();
|
|
@@ -14609,7 +14640,7 @@ var correlatedFilterSchema = z2.record(z2.string(), z2.unknown()).superRefine((f
|
|
|
14609
14640
|
}
|
|
14610
14641
|
});
|
|
14611
14642
|
var correlatedEmptyOptionsSchema = z2.unknown().refine(
|
|
14612
|
-
(value) => value === void 0 ||
|
|
14643
|
+
(value) => value === void 0 || isPlainObject28(value) && Object.keys(value).length === 0,
|
|
14613
14644
|
"Correlated include options must be absent or empty"
|
|
14614
14645
|
).optional();
|
|
14615
14646
|
var correlatedPathSchema = z2.string().min(1).superRefine((path, ctx) => {
|
|
@@ -14646,7 +14677,7 @@ var correlatedListArgsSchema = z2.object({
|
|
|
14646
14677
|
include: z2.lazy(() => correlatedNestedIncludeSchema).optional()
|
|
14647
14678
|
}).strict().superRefine((args, ctx) => checkArgsMarkers(args.select, args.sort, ctx));
|
|
14648
14679
|
var correlatedCountArgsSchema = z2.unknown().refine(
|
|
14649
|
-
(value) => value === void 0 ||
|
|
14680
|
+
(value) => value === void 0 || isPlainObject28(value) && Object.keys(value).length === 0,
|
|
14650
14681
|
"Count includes accept no args"
|
|
14651
14682
|
).optional();
|
|
14652
14683
|
var correlatedReadByIdSchema = z2.object({
|
|
@@ -14699,7 +14730,7 @@ var correlatedNestedIncludeSchema = z2.union([includeItemSchema, z2.array(includ
|
|
|
14699
14730
|
var rejectDuplicateCorrelatedPaths = (items, ctx) => {
|
|
14700
14731
|
const seen = /* @__PURE__ */ new Set();
|
|
14701
14732
|
items.forEach((item, index) => {
|
|
14702
|
-
if (
|
|
14733
|
+
if (isPlainObject28(item) && item.mode === "correlated" && typeof item.path === "string") {
|
|
14703
14734
|
if (seen.has(item.path)) {
|
|
14704
14735
|
ctx.addIssue({
|
|
14705
14736
|
code: z2.ZodIssueCode.custom,
|
|
@@ -16700,7 +16731,7 @@ var ModelRouter = class _ModelRouter {
|
|
|
16700
16731
|
value
|
|
16701
16732
|
);
|
|
16702
16733
|
}
|
|
16703
|
-
if (arguments.length === 1 &&
|
|
16734
|
+
if (arguments.length === 1 && isPlainObject29(keyOrOptions)) {
|
|
16704
16735
|
assertMutableRouterOptions("model", keyOrOptions);
|
|
16705
16736
|
this.runtime.setModelOptions(
|
|
16706
16737
|
this.modelName,
|
|
@@ -17234,7 +17265,7 @@ var RootRouter = class {
|
|
|
17234
17265
|
|
|
17235
17266
|
// src/routers/data-router.ts
|
|
17236
17267
|
import JsonRouter10 from "@web-ts-toolkit/express-json-router";
|
|
17237
|
-
import { isPlainObject as
|
|
17268
|
+
import { isPlainObject as isPlainObject30, isString as isString9, isUndefined as isUndefined3, normalizeUrlPath as normalizeUrlPath5 } from "@web-ts-toolkit/utils";
|
|
17238
17269
|
init_runtime();
|
|
17239
17270
|
init_helpers();
|
|
17240
17271
|
init_schemas();
|
|
@@ -17450,7 +17481,7 @@ var DataRouter = class {
|
|
|
17450
17481
|
value
|
|
17451
17482
|
);
|
|
17452
17483
|
}
|
|
17453
|
-
if (arguments.length === 1 &&
|
|
17484
|
+
if (arguments.length === 1 && isPlainObject30(keyOrOptions)) {
|
|
17454
17485
|
assertMutableRouterOptions("data", keyOrOptions);
|
|
17455
17486
|
this.runtime.setDataOptions(this.dataName, keyOrOptions);
|
|
17456
17487
|
}
|
|
@@ -17609,7 +17640,7 @@ function createRuntimeApi(runtime) {
|
|
|
17609
17640
|
if (arguments.length === 2 && isString10(keyOrOptions)) {
|
|
17610
17641
|
return runtime.setGlobalOption(keyOrOptions, value);
|
|
17611
17642
|
}
|
|
17612
|
-
if (arguments.length === 1 &&
|
|
17643
|
+
if (arguments.length === 1 && isPlainObject31(keyOrOptions)) {
|
|
17613
17644
|
return runtime.setGlobalOptions(keyOrOptions);
|
|
17614
17645
|
}
|
|
17615
17646
|
};
|