@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/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, import_utils15.isPlainObject)(value)) return fail(label, "entries must be plain { path, select? } objects");
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))
@@ -2252,7 +2277,8 @@ function normalizeSelection(select, catalog, label) {
2252
2277
  };
2253
2278
  }
2254
2279
  function captureVirtualPopulateDependencies(runtime, modelName, options, globalOptions = runtime.getGlobalOptions()) {
2255
- const requireReadOperationAccessForPopulateDependencies = globalOptions.requireReadOperationAccessForPopulateDependencies !== false;
2280
+ const requireOperationAccessForPopulateDependencies = globalOptions.requireOperationAccessForPopulateDependencies !== false;
2281
+ const requireOperationAccessForPopulateQueries = globalOptions.requireOperationAccessForPopulateQueries !== false;
2256
2282
  const model = runtime.getModelInstance(modelName);
2257
2283
  const targets = /* @__PURE__ */ new Map();
2258
2284
  const scopes = [];
@@ -2292,16 +2318,23 @@ function captureVirtualPopulateDependencies(runtime, modelName, options, globalO
2292
2318
  label,
2293
2319
  `target "${ref}" requires a registered same-connection non-discriminator ObjectId model bound to the source ref`
2294
2320
  );
2295
- const targetOptions = ref === modelName ? options : runtime.getModelOptions(ref);
2321
+ const { options: targetOptions } = capturePopulateTargetConfiguration(
2322
+ runtime,
2323
+ ref,
2324
+ `dependsOnPopulate virtual "${label}"`,
2325
+ ref === modelName ? options : void 0
2326
+ );
2296
2327
  const defaults = runtime.getDefaultModelOptions();
2297
- const readOption = (key) => resolveNestedOption((path2, fallback) => (0, import_utils15.get)(targetOptions, path2, fallback), key, (0, import_utils15.get)(defaults, key));
2328
+ const readOption = (key) => resolveNestedOption((path2, fallback) => (0, import_utils16.get)(targetOptions, path2, fallback), key, (0, import_utils16.get)(defaults, key));
2298
2329
  const documentPermissionField = targetOptions.documentPermissionField ?? defaults.documentPermissionField;
2299
2330
  const catalog = captureAuthorizationFieldCatalog(targetModel.schema, void 0, documentPermissionField);
2300
2331
  const configuration = copyAuthorizationValue(
2301
2332
  {
2302
2333
  catalog,
2303
2334
  documentPermissionField,
2304
- requireReadOperationAccessForPopulateDependencies,
2335
+ requireOperationAccessForPopulateDependencies,
2336
+ requireOperationAccessForPopulateQueries,
2337
+ permissionSchema: targetOptions.permissionSchema,
2305
2338
  operationAccess: { read: readOption("operationAccess.read") },
2306
2339
  baseFilter: { read: readOption("baseFilter.read") },
2307
2340
  overrideFilter: { read: readOption("overrideFilter.read") },
@@ -2350,13 +2383,13 @@ function captureVirtualPopulateDependencies(runtime, modelName, options, globalO
2350
2383
  );
2351
2384
  continue;
2352
2385
  }
2353
- if (!(0, import_utils15.isPlainObject)(raw)) continue;
2386
+ if (!(0, import_utils16.isPlainObject)(raw)) continue;
2354
2387
  const entry = raw;
2355
2388
  const label = join(sourcePrefix, name);
2356
2389
  captureList(entry.dependsOnPopulate, label);
2357
2390
  if (!("get" in entry))
2358
2391
  for (const access of accesses) {
2359
- if ((0, import_utils15.isPlainObject)(entry[access]))
2392
+ if ((0, import_utils16.isPlainObject)(entry[access]))
2360
2393
  captureList(entry[access].dependsOnPopulate, `${label}.${access}`);
2361
2394
  }
2362
2395
  const byAccess = {};
@@ -2406,15 +2439,16 @@ function resolveVirtualPopulateDependencies(configuration, scopePath, virtualNam
2406
2439
  )
2407
2440
  );
2408
2441
  }
2409
- var import_utils15, elementType, join, within, accesses, fail, varyingSchema, varyingModel, snapshots;
2442
+ var import_utils16, elementType, join, within, accesses, fail, varyingSchema, varyingModel, snapshots;
2410
2443
  var init_virtual_populate_dependencies = __esm({
2411
2444
  "src/acl/virtual-populate-dependencies.ts"() {
2412
- import_utils15 = require("@web-ts-toolkit/utils");
2445
+ import_utils16 = require("@web-ts-toolkit/utils");
2413
2446
  init_query();
2414
2447
  init_manager();
2415
2448
  init_authorization_snapshot();
2416
2449
  init_field_catalog();
2417
2450
  init_virtual_descriptor();
2451
+ init_populate_target_configuration();
2418
2452
  elementType = (type) => type.$embeddedSchemaType ?? type.embeddedSchemaType ?? type.caster;
2419
2453
  join = (prefix, path) => prefix ? `${prefix}.${path}` : path;
2420
2454
  within = (path, parent) => path === parent || path.startsWith(`${parent}.`);
@@ -2429,14 +2463,14 @@ var init_virtual_populate_dependencies = __esm({
2429
2463
  });
2430
2464
 
2431
2465
  // src/runtime.ts
2432
- var import_mongoose4, import_mongoose_schema_jsonschema, import_utils16, 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;
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;
2433
2467
  var init_runtime = __esm({
2434
2468
  "src/runtime.ts"() {
2435
2469
  import_mongoose4 = __toESM(require("mongoose"));
2436
2470
  init_public_admission();
2437
2471
  init_hydration();
2438
2472
  import_mongoose_schema_jsonschema = __toESM(require("mongoose-schema-jsonschema"));
2439
- import_utils16 = require("@web-ts-toolkit/utils");
2473
+ import_utils17 = require("@web-ts-toolkit/utils");
2440
2474
  init_helpers();
2441
2475
  init_registry();
2442
2476
  init_logger_default();
@@ -2465,44 +2499,44 @@ var init_runtime = __esm({
2465
2499
  listHardLimit: DEFAULT_LIST_HARD_LIMIT
2466
2500
  };
2467
2501
  normalizeBasePath = (name, value) => {
2468
- if ((0, import_utils16.isNil)(value)) {
2502
+ if ((0, import_utils17.isNil)(value)) {
2469
2503
  return `/${pluralize(name)}`;
2470
2504
  }
2471
- return (0, import_utils16.isString)(value) ? (0, import_utils16.addLeadingSlash)(value) : "";
2505
+ return (0, import_utils17.isString)(value) ? (0, import_utils17.addLeadingSlash)(value) : "";
2472
2506
  };
2473
2507
  hasModelPermission = (value, modelPermissionPrefix) => {
2474
2508
  if (!modelPermissionPrefix) {
2475
2509
  return true;
2476
2510
  }
2477
- if ((0, import_utils16.isString)(value)) {
2511
+ if ((0, import_utils17.isString)(value)) {
2478
2512
  return value.trim().split(" ").some((item) => item.startsWith(modelPermissionPrefix));
2479
2513
  }
2480
- if ((0, import_utils16.isArray)(value)) {
2514
+ if ((0, import_utils17.isArray)(value)) {
2481
2515
  return value.some((item) => {
2482
- if ((0, import_utils16.isString)(item) || (0, import_utils16.isArray)(item)) {
2516
+ if ((0, import_utils17.isString)(item) || (0, import_utils17.isArray)(item)) {
2483
2517
  return hasModelPermission(item, modelPermissionPrefix);
2484
2518
  }
2485
2519
  return true;
2486
2520
  });
2487
2521
  }
2488
- return (0, import_utils16.isFunction)(value);
2522
+ return (0, import_utils17.isFunction)(value);
2489
2523
  };
2490
2524
  classifyPermissionSchema = (permissionSchema, modelPermissionPrefix) => {
2491
2525
  const schemaKeys = Object.keys(permissionSchema);
2492
2526
  const globalPermissionKeys = {};
2493
2527
  const modelPermissionKeys = {};
2494
- (0, import_utils16.forEach)(schemaKeys, (schemaKey) => {
2528
+ (0, import_utils17.forEach)(schemaKeys, (schemaKey) => {
2495
2529
  const schemaRule = permissionSchema[schemaKey];
2496
- const ruleEntries = (0, import_utils16.isPlainObject)(schemaRule) ? Object.entries(schemaRule) : FIELD_ACCESS_KEYS.map((accessKey) => [accessKey, schemaRule]);
2530
+ const ruleEntries = (0, import_utils17.isPlainObject)(schemaRule) ? Object.entries(schemaRule) : FIELD_ACCESS_KEYS.map((accessKey) => [accessKey, schemaRule]);
2497
2531
  for (let x = 0; x < ruleEntries.length; x++) {
2498
2532
  const [accessKey, value] = ruleEntries[x];
2499
- if (!(0, import_utils16.isArray)(globalPermissionKeys[accessKey])) {
2533
+ if (!(0, import_utils17.isArray)(globalPermissionKeys[accessKey])) {
2500
2534
  globalPermissionKeys[accessKey] = [];
2501
2535
  }
2502
- if (!(0, import_utils16.isArray)(modelPermissionKeys[accessKey])) {
2536
+ if (!(0, import_utils17.isArray)(modelPermissionKeys[accessKey])) {
2503
2537
  modelPermissionKeys[accessKey] = [];
2504
2538
  }
2505
- if ((0, import_utils16.isBoolean)(value)) {
2539
+ if ((0, import_utils17.isBoolean)(value)) {
2506
2540
  globalPermissionKeys[accessKey].push(schemaKey);
2507
2541
  continue;
2508
2542
  }
@@ -2534,13 +2568,13 @@ var init_runtime = __esm({
2534
2568
  VIRTUAL_RESERVED_NAMES = /* @__PURE__ */ new Set(["_id", "__v", "id"]);
2535
2569
  VIRTUAL_DANGEROUS_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
2536
2570
  VIRTUAL_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
2537
- isVirtualContainerValue2 = (value) => (0, import_utils16.isPlainObject)(value) && "sub" in value;
2571
+ isVirtualContainerValue2 = (value) => (0, import_utils17.isPlainObject)(value) && "sub" in value;
2538
2572
  virtualFullPath = (prefix, name) => prefix ? `${prefix}.${name}` : name;
2539
2573
  virtualPathsOverlap = (virtualPath, permissionField) => {
2540
2574
  if (!virtualPath || !permissionField) return false;
2541
2575
  try {
2542
- if ((0, import_utils16.get)((0, import_utils16.set)({}, virtualPath, true), permissionField) !== void 0) return true;
2543
- if ((0, import_utils16.get)((0, import_utils16.set)({}, permissionField, true), virtualPath) !== void 0) return true;
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;
2544
2578
  } catch {
2545
2579
  return false;
2546
2580
  }
@@ -2601,12 +2635,12 @@ var init_runtime = __esm({
2601
2635
  };
2602
2636
  validateVirtualDependsOn = (dependsOn, entryLabel, storedFields, siblingVirtualNames) => {
2603
2637
  if (dependsOn === void 0) return [];
2604
- if (!(0, import_utils16.isArray)(dependsOn)) {
2638
+ if (!(0, import_utils17.isArray)(dependsOn)) {
2605
2639
  throw new Error(`Virtual ${entryLabel}: dependsOn must be an array of top-level persisted field names`);
2606
2640
  }
2607
2641
  const list = dependsOn;
2608
2642
  for (const dep of list) {
2609
- if (!(0, import_utils16.isString)(dep) || dep.length === 0) {
2643
+ if (!(0, import_utils17.isString)(dep) || dep.length === 0) {
2610
2644
  throw new Error(`Virtual ${entryLabel}: dependsOn entries must be non-empty strings`);
2611
2645
  }
2612
2646
  if (dep.includes(".")) {
@@ -2628,12 +2662,12 @@ var init_runtime = __esm({
2628
2662
  return list;
2629
2663
  };
2630
2664
  validateVirtualLeafValue = (value, entryLabel, storedFields, siblingVirtualNames, sharedDependsOn) => {
2631
- if ((0, import_utils16.isFunction)(value)) return;
2632
- if (!(0, import_utils16.isPlainObject)(value)) {
2665
+ if ((0, import_utils17.isFunction)(value)) return;
2666
+ if (!(0, import_utils17.isPlainObject)(value)) {
2633
2667
  throw new Error(`Virtual ${entryLabel}: descriptor must be a getter function or { get, dependsOn }`);
2634
2668
  }
2635
2669
  const record3 = value;
2636
- if (!(0, import_utils16.isFunction)(record3.get)) {
2670
+ if (!(0, import_utils17.isFunction)(record3.get)) {
2637
2671
  throw new Error(`Virtual ${entryLabel}: descriptor.get must be a callable getter function`);
2638
2672
  }
2639
2673
  validateVirtualDependsOn(record3.dependsOn ?? sharedDependsOn, entryLabel, storedFields, siblingVirtualNames);
@@ -2675,7 +2709,7 @@ var init_runtime = __esm({
2675
2709
  `Virtual ${scopeLabel}${name}: scope-container must only hold "sub" (embedded container "${name}" is not a virtual-leaf collision)`
2676
2710
  );
2677
2711
  }
2678
- if (!(0, import_utils16.isPlainObject)(record4.sub)) {
2712
+ if (!(0, import_utils17.isPlainObject)(record4.sub)) {
2679
2713
  throw new Error(`Virtual ${scopeLabel}${name}: scope-container "sub" must be a plain object`);
2680
2714
  }
2681
2715
  continue;
@@ -2685,8 +2719,8 @@ var init_runtime = __esm({
2685
2719
  `Virtual ${scopeLabel}${name}: collides with a stored path (inspected actual Mongoose schema/child scope; getModelAtt alone is insufficient)`
2686
2720
  );
2687
2721
  }
2688
- if ((0, import_utils16.isFunction)(raw)) continue;
2689
- if (!(0, import_utils16.isPlainObject)(raw)) {
2722
+ if ((0, import_utils17.isFunction)(raw)) continue;
2723
+ if (!(0, import_utils17.isPlainObject)(raw)) {
2690
2724
  throw new Error(
2691
2725
  `Virtual ${scopeLabel}${name}: malformed descriptor (expected getter, { get, dependsOn }, or per-access record)`
2692
2726
  );
@@ -2740,7 +2774,7 @@ var init_runtime = __esm({
2740
2774
  };
2741
2775
  validateVirtualsTree = (model, virtuals, documentPermissionField, modelName) => {
2742
2776
  if (virtuals === void 0 || virtuals === null) return;
2743
- if (!(0, import_utils16.isPlainObject)(virtuals)) {
2777
+ if (!(0, import_utils17.isPlainObject)(virtuals)) {
2744
2778
  throw new Error(`Virtuals for model "${modelName}": virtuals must be a plain object mapping names to descriptors`);
2745
2779
  }
2746
2780
  const rootSchema = model?.schema ?? null;
@@ -2792,8 +2826,8 @@ var init_runtime = __esm({
2792
2826
  {
2793
2827
  requestPermissionField: "_permissions",
2794
2828
  globalPermissions: () => ({}),
2795
- requireRegisteredPopulateModels: true,
2796
- requireReadOperationAccessForPopulateDependencies: true,
2829
+ requireOperationAccessForPopulateQueries: true,
2830
+ requireOperationAccessForPopulateDependencies: true,
2797
2831
  logger: defaultLogger,
2798
2832
  requestComplexity: defaultRequestComplexity
2799
2833
  },
@@ -2848,7 +2882,7 @@ var init_runtime = __esm({
2848
2882
  }
2849
2883
  registerOpenApiRoute(route) {
2850
2884
  this.openApiRegistry.register(
2851
- this.openApiPathPrefix ? { ...route, path: (0, import_utils16.normalizeUrlPath)(`${this.openApiPathPrefix}/${route.path}`) } : route
2885
+ this.openApiPathPrefix ? { ...route, path: (0, import_utils17.normalizeUrlPath)(`${this.openApiPathPrefix}/${route.path}`) } : route
2852
2886
  );
2853
2887
  }
2854
2888
  /**
@@ -2859,7 +2893,7 @@ var init_runtime = __esm({
2859
2893
  */
2860
2894
  withOpenApiPathPrefix(prefix, build) {
2861
2895
  const previous = this.openApiPathPrefix;
2862
- this.openApiPathPrefix = (0, import_utils16.normalizeUrlPath)(`${previous}/${prefix}`);
2896
+ this.openApiPathPrefix = (0, import_utils17.normalizeUrlPath)(`${previous}/${prefix}`);
2863
2897
  try {
2864
2898
  return build();
2865
2899
  } finally {
@@ -2967,13 +3001,15 @@ var init_runtime = __esm({
2967
3001
  /** Shallowly replace supplied global values; nested objects such as requestComplexity are not deep-merged. */
2968
3002
  setGlobalOptions(options) {
2969
3003
  const next = { ...options };
2970
- if ("requireReadOperationAccessForPopulateDependencies" in next)
2971
- next.requireReadOperationAccessForPopulateDependencies = next.requireReadOperationAccessForPopulateDependencies !== false;
3004
+ if ("requireOperationAccessForPopulateQueries" in next)
3005
+ next.requireOperationAccessForPopulateQueries = next.requireOperationAccessForPopulateQueries !== false;
3006
+ if ("requireOperationAccessForPopulateDependencies" in next)
3007
+ next.requireOperationAccessForPopulateDependencies = next.requireOperationAccessForPopulateDependencies !== false;
2972
3008
  this.globalOptions.assign(next);
2973
3009
  }
2974
3010
  setGlobalOption(key, value) {
2975
- if (key === "requireReadOperationAccessForPopulateDependencies") {
2976
- this.globalOptions.set("requireReadOperationAccessForPopulateDependencies", value !== false);
3011
+ if (key === "requireOperationAccessForPopulateQueries" || key === "requireOperationAccessForPopulateDependencies") {
3012
+ this.globalOptions.set(key, value !== false);
2977
3013
  return;
2978
3014
  }
2979
3015
  this.globalOptions.set(key, value);
@@ -3002,7 +3038,7 @@ var init_runtime = __esm({
3002
3038
  if (keyStr === "defaults") assertPublicDefaults(value);
3003
3039
  else if (keyStr.startsWith("defaults.")) {
3004
3040
  const proposed = {};
3005
- (0, import_utils16.set)(proposed, keyStr.slice("defaults.".length), value);
3041
+ (0, import_utils17.set)(proposed, keyStr.slice("defaults.".length), value);
3006
3042
  assertPublicDefaults(proposed);
3007
3043
  }
3008
3044
  this.defaultModelOptions.set(key, value);
@@ -3031,7 +3067,7 @@ var init_runtime = __esm({
3031
3067
  }).onchange("basePath", function(newval, key, target) {
3032
3068
  target[key] = normalizeBasePath(
3033
3069
  modelName,
3034
- (0, import_utils16.isString)(newval) || (0, import_utils16.isNil)(newval) ? newval : void 0
3070
+ (0, import_utils17.isString)(newval) || (0, import_utils17.isNil)(newval) ? newval : void 0
3035
3071
  );
3036
3072
  }).build();
3037
3073
  this.modelJsonSchemas[modelName] = model.jsonSchema();
@@ -3075,7 +3111,7 @@ var init_runtime = __esm({
3075
3111
  if (keyStr === "defaults") assertPublicDefaults(value);
3076
3112
  else if (keyStr.startsWith("defaults.")) {
3077
3113
  const proposed = {};
3078
- (0, import_utils16.set)(proposed, keyStr.slice("defaults.".length), value);
3114
+ (0, import_utils17.set)(proposed, keyStr.slice("defaults.".length), value);
3079
3115
  assertPublicDefaults(proposed);
3080
3116
  }
3081
3117
  const manager = this.modelOptions[modelName];
@@ -3096,15 +3132,15 @@ var init_runtime = __esm({
3096
3132
  const segments = nestedPath.split(".");
3097
3133
  let cursor = cloned;
3098
3134
  for (let i = 0; i < segments.length - 1; i++) {
3099
- if (!(0, import_utils16.isPlainObject)(cursor)) break;
3135
+ if (!(0, import_utils17.isPlainObject)(cursor)) break;
3100
3136
  cursor = cursor[segments[i]];
3101
3137
  }
3102
- if ((0, import_utils16.isPlainObject)(cursor)) {
3138
+ if ((0, import_utils17.isPlainObject)(cursor)) {
3103
3139
  delete cursor[segments[segments.length - 1]];
3104
3140
  }
3105
3141
  proposedVirtuals = cloned;
3106
3142
  } else {
3107
- (0, import_utils16.set)(cloned, nestedPath, value);
3143
+ (0, import_utils17.set)(cloned, nestedPath, value);
3108
3144
  proposedVirtuals = cloned;
3109
3145
  }
3110
3146
  }
@@ -3205,7 +3241,7 @@ var init_runtime = __esm({
3205
3241
  manager.onchange("basePath", function(newval, key, target) {
3206
3242
  target[key] = normalizeBasePath(
3207
3243
  dataName,
3208
- (0, import_utils16.isString)(newval) || (0, import_utils16.isNil)(newval) ? newval : void 0
3244
+ (0, import_utils17.isString)(newval) || (0, import_utils17.isNil)(newval) ? newval : void 0
3209
3245
  );
3210
3246
  }).build();
3211
3247
  return manager;
@@ -3265,20 +3301,20 @@ var init_runtime = __esm({
3265
3301
  const schema = model.schema;
3266
3302
  this.modelRefs[modelName] = buildRefs(schema.tree);
3267
3303
  this.modelSubs[modelName] = buildSubPaths(schema.tree);
3268
- this.modelAtts[modelName] = (0, import_utils16.keys)(schema.obj);
3304
+ this.modelAtts[modelName] = (0, import_utils17.keys)(schema.obj);
3269
3305
  }
3270
3306
  getModelRef(modelName, refPath) {
3271
3307
  this.ensureModelMeta(modelName);
3272
- const value = (0, import_utils16.get)(this.modelRefs, `${modelName}.${refPath}`, null);
3273
- return (0, import_utils16.isString)(value) ? value : null;
3308
+ const value = (0, import_utils17.get)(this.modelRefs, `${modelName}.${refPath}`, null);
3309
+ return (0, import_utils17.isString)(value) ? value : null;
3274
3310
  }
3275
3311
  getModelSub(modelName) {
3276
3312
  this.ensureModelMeta(modelName);
3277
- return (0, import_utils16.get)(this.modelSubs, modelName, []);
3313
+ return (0, import_utils17.get)(this.modelSubs, modelName, []);
3278
3314
  }
3279
3315
  getModelAtt(modelName) {
3280
3316
  this.ensureModelMeta(modelName);
3281
- return (0, import_utils16.get)(this.modelAtts, modelName, []);
3317
+ return (0, import_utils17.get)(this.modelAtts, modelName, []);
3282
3318
  }
3283
3319
  };
3284
3320
  defaultRuntime = new AccessRuntime({ allowGlobalModelLookup: true });
@@ -3454,10 +3490,10 @@ var init_options = __esm({
3454
3490
  });
3455
3491
 
3456
3492
  // src/permission.ts
3457
- var import_utils17, Permission, permission_default;
3493
+ var import_utils18, Permission, permission_default;
3458
3494
  var init_permission = __esm({
3459
3495
  "src/permission.ts"() {
3460
- import_utils17 = require("@web-ts-toolkit/utils");
3496
+ import_utils18 = require("@web-ts-toolkit/utils");
3461
3497
  Permission = class {
3462
3498
  constructor(permissions) {
3463
3499
  this.permissions = { ...permissions };
@@ -3473,7 +3509,7 @@ var init_permission = __esm({
3473
3509
  return [permissionOrPermissions].concat(permissions);
3474
3510
  }
3475
3511
  hasKey(permission) {
3476
- return (0, import_utils17.hasOwn)(this.permissions, permission);
3512
+ return (0, import_utils18.hasOwn)(this.permissions, permission);
3477
3513
  }
3478
3514
  has(permission) {
3479
3515
  return this.permissions[permission] === true;
@@ -3591,7 +3627,6 @@ function normalizePolicy(value, applicability, configuration, targets) {
3591
3627
  const matches = targets.filter((target2) => target2.path === path);
3592
3628
  if (matches.length !== 1) authorizationError(`unused or ambiguous related path: ${path}`);
3593
3629
  const target = matches[0];
3594
- if (target.kind === "passthrough") authorizationError(`related policy requires a registered target: ${path}`);
3595
3630
  const child = authorizationRecord(entry, `related.${path}`);
3596
3631
  assertAuthorizationKeys(
3597
3632
  child,
@@ -3960,7 +3995,7 @@ function attachIncludeOutput(doc, path, value) {
3960
3995
  const state = stateFor(doc);
3961
3996
  if (!state) throw new Error("Include attachment requires a prepared output row");
3962
3997
  state.attachments.push({ path, value });
3963
- (0, import_utils18.set)(doc, path, deepIsolateValue(value));
3998
+ (0, import_utils19.set)(doc, path, deepIsolateValue(value));
3964
3999
  }
3965
4000
  function getIncludeSource(doc) {
3966
4001
  return stateFor(doc)?.source ?? doc;
@@ -3975,14 +4010,14 @@ function restoreIncludeOutput(doc, output) {
3975
4010
  for (const { path, value } of attachments) {
3976
4011
  const copy = deepIsolateValue(value);
3977
4012
  if (copy !== null && typeof copy === "object") origins.set(copy, value);
3978
- (0, import_utils18.set)(output, path, copy);
4013
+ (0, import_utils19.set)(output, path, copy);
3979
4014
  }
3980
4015
  return origins;
3981
4016
  }
3982
- var import_utils18, outputs2, stateFor;
4017
+ var import_utils19, outputs2, stateFor;
3983
4018
  var init_include_output = __esm({
3984
4019
  "src/output/include-output.ts"() {
3985
- import_utils18 = require("@web-ts-toolkit/utils");
4020
+ import_utils19 = require("@web-ts-toolkit/utils");
3986
4021
  init_document_authorization();
3987
4022
  init_document();
3988
4023
  outputs2 = /* @__PURE__ */ new WeakMap();
@@ -4324,10 +4359,10 @@ function planVirtualProjection(args) {
4324
4359
  relatedPlans
4325
4360
  };
4326
4361
  }
4327
- var import_utils20, getScopedPermissionSchema, resolveAlwaysSelectForAccess, stripVirtualsFromNormalizedSelect, snapshotVirtualPaths, stripLeadingDash, dbPrefixForScope, toDbPath;
4362
+ var import_utils21, getScopedPermissionSchema, resolveAlwaysSelectForAccess, stripVirtualsFromNormalizedSelect, snapshotVirtualPaths, stripLeadingDash, dbPrefixForScope, toDbPath;
4328
4363
  var init_virtual_projection = __esm({
4329
4364
  "src/acl/virtual-projection.ts"() {
4330
- import_utils20 = require("@web-ts-toolkit/utils");
4365
+ import_utils21 = require("@web-ts-toolkit/utils");
4331
4366
  init_query();
4332
4367
  init_field_authorization();
4333
4368
  init_output_projection();
@@ -4335,20 +4370,20 @@ var init_virtual_projection = __esm({
4335
4370
  init_virtual_populate_dependencies();
4336
4371
  init_virtual_descriptor();
4337
4372
  getScopedPermissionSchema = (root, scopePath) => {
4338
- if (!root || !(0, import_utils20.isPlainObject)(root)) return null;
4373
+ if (!root || !(0, import_utils21.isPlainObject)(root)) return null;
4339
4374
  if (scopePath.length === 0) return root;
4340
- const scoped = (0, import_utils20.get)(root, scopePath.join("."));
4341
- return (0, import_utils20.isPlainObject)(scoped) ? scoped : null;
4375
+ const scoped = (0, import_utils21.get)(root, scopePath.join("."));
4376
+ return (0, import_utils21.isPlainObject)(scoped) ? scoped : null;
4342
4377
  };
4343
4378
  resolveAlwaysSelectForAccess = (raw, access) => {
4344
4379
  if (!raw) return [];
4345
- if ((0, import_utils20.isArray)(raw)) return [...raw];
4346
- if ((0, import_utils20.isPlainObject)(raw)) {
4380
+ if ((0, import_utils21.isArray)(raw)) return [...raw];
4381
+ if ((0, import_utils21.isPlainObject)(raw)) {
4347
4382
  const record3 = raw;
4348
4383
  const exact = record3[access];
4349
- if ((0, import_utils20.isArray)(exact)) return [...exact];
4384
+ if ((0, import_utils21.isArray)(exact)) return [...exact];
4350
4385
  const def = record3.default;
4351
- if ((0, import_utils20.isArray)(def)) return [...def];
4386
+ if ((0, import_utils21.isArray)(def)) return [...def];
4352
4387
  return [];
4353
4388
  }
4354
4389
  return [];
@@ -4613,8 +4648,8 @@ var init_output_projection = __esm({
4613
4648
 
4614
4649
  // src/acl/model-output-planning.ts
4615
4650
  function getCapturedAuthorizationOption(configuration, key) {
4616
- const defaultValue = key.startsWith("operationAccess.") ? (0, import_utils21.get)(configuration.operationAccessDefaults, key.slice("operationAccess.".length)) : void 0;
4617
- return resolveNestedOption((path, fallback) => (0, import_utils21.get)(configuration, path, fallback), key, defaultValue);
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);
4618
4653
  }
4619
4654
  function captureModelAuthorizationConfiguration(runtime, modelName, options = runtime.getModelOptions(modelName), globalOptions = runtime.getGlobalOptions()) {
4620
4655
  const model = runtime.getModelInstance(modelName);
@@ -4629,9 +4664,9 @@ function captureModelAuthorizationConfiguration(runtime, modelName, options = ru
4629
4664
  options,
4630
4665
  globalOptions
4631
4666
  ),
4632
- requireReadOperationAccessForPopulateDependencies: globalOptions.requireReadOperationAccessForPopulateDependencies !== false,
4633
- requireRegisteredPopulateModels: globalOptions.requireRegisteredPopulateModels,
4634
- permissionSchema: options.permissionSchema,
4667
+ requireOperationAccessForPopulateDependencies: globalOptions.requireOperationAccessForPopulateDependencies !== false,
4668
+ requireOperationAccessForPopulateQueries: globalOptions.requireOperationAccessForPopulateQueries !== false,
4669
+ permissionSchema: options.permissionSchema === void 0 ? runtime.getDefaultModelOption("permissionSchema") : options.permissionSchema,
4635
4670
  virtuals,
4636
4671
  alwaysSelectFields: options.alwaysSelectFields,
4637
4672
  modelPermissionPrefix: options.modelPermissionPrefix,
@@ -4677,10 +4712,10 @@ function planModelOutputForHelper(args) {
4677
4712
  requestedSelect: args.select
4678
4713
  });
4679
4714
  }
4680
- var import_utils21;
4715
+ var import_utils22;
4681
4716
  var init_model_output_planning = __esm({
4682
4717
  "src/acl/model-output-planning.ts"() {
4683
- import_utils21 = require("@web-ts-toolkit/utils");
4718
+ import_utils22 = require("@web-ts-toolkit/utils");
4684
4719
  init_manager();
4685
4720
  init_field_catalog();
4686
4721
  init_authorization_snapshot();
@@ -4692,10 +4727,10 @@ var init_model_output_planning = __esm({
4692
4727
 
4693
4728
  // src/core-shared.ts
4694
4729
  function isAndFilter(filter2) {
4695
- return !!filter2 && (0, import_utils22.isPlainObject)(filter2) && Object.keys(filter2).length === 1 && (0, import_utils22.isArray)(filter2.$and);
4730
+ return !!filter2 && (0, import_utils23.isPlainObject)(filter2) && Object.keys(filter2).length === 1 && (0, import_utils23.isArray)(filter2.$and);
4696
4731
  }
4697
4732
  function isMergeableClause(filter2) {
4698
- return !!filter2 && (0, import_utils22.isPlainObject)(filter2) && Object.keys(filter2).every((key) => !key.startsWith("$"));
4733
+ return !!filter2 && (0, import_utils23.isPlainObject)(filter2) && Object.keys(filter2).every((key) => !key.startsWith("$"));
4699
4734
  }
4700
4735
  function optimizeAndFilter(clausesInput) {
4701
4736
  const clauses = [];
@@ -4712,11 +4747,11 @@ function optimizeAndFilter(clausesInput) {
4712
4747
  const dedupeKey = (value) => {
4713
4748
  if (value instanceof RegExp) return `regexp:${JSON.stringify([value.source, value.flags])}`;
4714
4749
  if (value instanceof Date) return `date:${value.getTime()}`;
4715
- if ((0, import_utils22.isArray)(value)) {
4750
+ if ((0, import_utils23.isArray)(value)) {
4716
4751
  const entries = Array.from(value, dedupeKey);
4717
4752
  return entries.every((entry) => entry !== void 0) ? `array:${JSON.stringify(entries)}` : void 0;
4718
4753
  }
4719
- if ((0, import_utils22.isPlainObject)(value)) {
4754
+ if ((0, import_utils23.isPlainObject)(value)) {
4720
4755
  const entries = Object.keys(value).sort().map((key) => [key, dedupeKey(value[key])]);
4721
4756
  return entries.every(([, entry]) => entry !== void 0) ? `object:${JSON.stringify(entries)}` : void 0;
4722
4757
  }
@@ -4746,7 +4781,7 @@ function optimizeAndFilter(clausesInput) {
4746
4781
  }
4747
4782
  let canMerge = true;
4748
4783
  for (const [key, value] of Object.entries(clause)) {
4749
- if ((0, import_utils22.hasOwn)(mergedClause, key) && !(0, import_node_util4.isDeepStrictEqual)(mergedClause[key], value)) {
4784
+ if ((0, import_utils23.hasOwn)(mergedClause, key) && !(0, import_node_util4.isDeepStrictEqual)(mergedClause[key], value)) {
4750
4785
  canMerge = false;
4751
4786
  break;
4752
4787
  }
@@ -4757,24 +4792,24 @@ function optimizeAndFilter(clausesInput) {
4757
4792
  }
4758
4793
  Object.assign(mergedClause, clause);
4759
4794
  }
4760
- const finalClauses = (0, import_utils22.isEmpty)(mergedClause) ? remainingClauses : [mergedClause, ...remainingClauses];
4795
+ const finalClauses = (0, import_utils23.isEmpty)(mergedClause) ? remainingClauses : [mergedClause, ...remainingClauses];
4761
4796
  if (finalClauses.length === 0) return null;
4762
4797
  if (finalClauses.length === 1) return finalClauses[0];
4763
4798
  return { $and: finalClauses };
4764
4799
  }
4765
4800
  function normalizeFilter(filter2) {
4766
4801
  if (filter2 === false) return false;
4767
- if (!filter2 || !(0, import_utils22.isPlainObject)(filter2) || (0, import_utils22.isEmpty)(filter2)) return null;
4802
+ if (!filter2 || !(0, import_utils23.isPlainObject)(filter2) || (0, import_utils23.isEmpty)(filter2)) return null;
4768
4803
  if (!isAndFilter(filter2)) {
4769
4804
  return filter2;
4770
4805
  }
4771
4806
  return optimizeAndFilter(filter2.$and);
4772
4807
  }
4773
4808
  async function resolveIdentifierFilter(req, idField, resolveIdFilter, id) {
4774
- if ((0, import_utils22.isFunction)(resolveIdFilter)) {
4809
+ if ((0, import_utils23.isFunction)(resolveIdFilter)) {
4775
4810
  return await resolveIdFilter.call(req, id);
4776
4811
  }
4777
- if ((0, import_utils22.isString)(idField)) {
4812
+ if ((0, import_utils23.isString)(idField)) {
4778
4813
  return { [idField]: id };
4779
4814
  }
4780
4815
  return { _id: id };
@@ -4798,7 +4833,7 @@ async function resolveAccessFilterParts({
4798
4833
  }
4799
4834
  const overrideFilterFn = getOption(`overrideFilter.${access}`, null);
4800
4835
  const baseFilterFn = rows2.mode === "request" ? getOption(`baseFilter.${access}`, null) : null;
4801
- if (nextFilter !== false && (0, import_utils22.isFunction)(overrideFilterFn)) {
4836
+ if (nextFilter !== false && (0, import_utils23.isFunction)(overrideFilterFn)) {
4802
4837
  nextFilter = normalizeFilter(await overrideFilterFn.call(req, nextFilter, permissions));
4803
4838
  }
4804
4839
  if (nextFilter === false) return { transformed: false, scope: {}, filter: false };
@@ -4806,7 +4841,7 @@ async function resolveAccessFilterParts({
4806
4841
  const scope2 = rows2.mode === "scope" ? rows2.filter : {};
4807
4842
  return { transformed: nextFilter ?? {}, scope: scope2, filter: intersectFilters(nextFilter, scope2) };
4808
4843
  }
4809
- if (!(0, import_utils22.isFunction)(baseFilterFn)) return { transformed: nextFilter ?? {}, scope: {}, filter: nextFilter ?? {} };
4844
+ if (!(0, import_utils23.isFunction)(baseFilterFn)) return { transformed: nextFilter ?? {}, scope: {}, filter: nextFilter ?? {} };
4810
4845
  const cached = cache.get(cacheKey);
4811
4846
  const reusable = cached?.resolver === baseFilterFn;
4812
4847
  const baseFilter = normalizeFilter(
@@ -4841,34 +4876,34 @@ async function setRequestPermissions(req) {
4841
4876
  if (owner === activeRuntime) return;
4842
4877
  if (hasFieldValue && owner === void 0) return;
4843
4878
  const globalPermissions = getGlobalOption("globalPermissions");
4844
- const permissions = (0, import_utils22.isFunction)(globalPermissions) ? await globalPermissions.call(req, req) : void 0;
4845
- if ((0, import_utils22.isPlainObject)(permissions)) req[requestPermissionField] = permissions;
4846
- else if ((0, import_utils22.isArray)(permissions)) req[requestPermissionField] = (0, import_utils22.arrayToRecord)(permissions);
4847
- else if ((0, import_utils22.isString)(permissions)) req[requestPermissionField] = { [permissions]: true };
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 };
4848
4883
  else req[requestPermissionField] = {};
4849
4884
  owners.set(requestPermissionField, activeRuntime);
4850
4885
  }
4851
4886
  async function evaluateRouteGuard(req, permissions, routeGuard) {
4852
4887
  const phas = (key) => permissions.has(key);
4853
4888
  const { stringHandler, arrayHandler } = createValidator(phas);
4854
- if ((0, import_utils22.isBoolean)(routeGuard)) {
4889
+ if ((0, import_utils23.isBoolean)(routeGuard)) {
4855
4890
  return routeGuard === true;
4856
4891
  }
4857
- if ((0, import_utils22.isString)(routeGuard)) {
4892
+ if ((0, import_utils23.isString)(routeGuard)) {
4858
4893
  return stringHandler(routeGuard);
4859
4894
  }
4860
- if ((0, import_utils22.isArray)(routeGuard)) {
4895
+ if ((0, import_utils23.isArray)(routeGuard)) {
4861
4896
  return arrayHandler(routeGuard);
4862
4897
  }
4863
- if ((0, import_utils22.isFunction)(routeGuard)) {
4898
+ if ((0, import_utils23.isFunction)(routeGuard)) {
4864
4899
  return routeGuard.call(req, permissions);
4865
4900
  }
4866
4901
  return false;
4867
4902
  }
4868
4903
  async function callHookChain(req, hook, doc, permissions, context) {
4869
- const hooks = (0, import_utils22.castArray)(hook);
4904
+ const hooks = (0, import_utils23.castArray)(hook);
4870
4905
  for (let x = 0; x < hooks.length; x++) {
4871
- if ((0, import_utils22.isFunction)(hooks[x])) {
4906
+ if ((0, import_utils23.isFunction)(hooks[x])) {
4872
4907
  doc = await hooks[x].call(req, doc, permissions, context);
4873
4908
  }
4874
4909
  }
@@ -4888,22 +4923,22 @@ async function collectSchemaFields({
4888
4923
  for (let x = 0; x < keys2.length; x++) {
4889
4924
  const key = keys2[x];
4890
4925
  const value = extractScopedOutputRule(permissionSchema, key, access);
4891
- if ((0, import_utils22.isBoolean)(value)) {
4926
+ if ((0, import_utils23.isBoolean)(value)) {
4892
4927
  if (value) fields.push(key);
4893
- } else if ((0, import_utils22.isString)(value)) {
4928
+ } else if ((0, import_utils23.isString)(value)) {
4894
4929
  if (stringHandler(value)) fields.push(key);
4895
- } else if ((0, import_utils22.isArray)(value)) {
4930
+ } else if ((0, import_utils23.isArray)(value)) {
4896
4931
  if (arrayHandler(value)) fields.push(key);
4897
- } else if ((0, import_utils22.isFunction)(value)) {
4932
+ } else if ((0, import_utils23.isFunction)(value)) {
4898
4933
  if (await value.call(req, ...functionArgs)) fields.push(key);
4899
4934
  }
4900
4935
  }
4901
4936
  return fields;
4902
4937
  }
4903
- var import_utils22, import_node_util4, permissionFieldOwners;
4938
+ var import_utils23, import_node_util4, permissionFieldOwners;
4904
4939
  var init_core_shared = __esm({
4905
4940
  "src/core-shared.ts"() {
4906
- import_utils22 = require("@web-ts-toolkit/utils");
4941
+ import_utils23 = require("@web-ts-toolkit/utils");
4907
4942
  import_node_util4 = require("util");
4908
4943
  init_helpers();
4909
4944
  init_options();
@@ -5272,8 +5307,8 @@ function equivalentVirtualPopulatePredicate(left, right) {
5272
5307
  }
5273
5308
  if (Array.isArray(left) || Array.isArray(right))
5274
5309
  return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((entry, index) => equivalentVirtualPopulatePredicate(entry, right[index]));
5275
- if ((0, import_utils26.isPlainObject)(left) || (0, import_utils26.isPlainObject)(right)) {
5276
- if (!(0, import_utils26.isPlainObject)(left) || !(0, import_utils26.isPlainObject)(right)) return false;
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;
5277
5312
  const a = Object.keys(left), b = Object.keys(right);
5278
5313
  return a.length === b.length && a.every(
5279
5314
  (key, index) => key === b[index] && equivalentVirtualPopulatePredicate(
@@ -5344,7 +5379,6 @@ function captureVirtualPopulateRows(batch, inputs, plan, publicPopulate = [], so
5344
5379
  address,
5345
5380
  plan: currentPlan,
5346
5381
  refs: /* @__PURE__ */ new Map(),
5347
- referenceTargets: /* @__PURE__ */ new Map(),
5348
5382
  dependencies: /* @__PURE__ */ new Map()
5349
5383
  };
5350
5384
  row.occurrences.set(addressKey(address), occurrence);
@@ -5352,7 +5386,6 @@ function captureVirtualPopulateRows(batch, inputs, plan, publicPopulate = [], so
5352
5386
  const dependencies = (candidate.populateDependencies ?? []).map((dependency) => {
5353
5387
  if (!occurrence.refs.has(dependency.path))
5354
5388
  occurrence.refs.set(dependency.path, originalRef(value, dependency.path));
5355
- occurrence.referenceTargets.set(dependency.path, dependency.target);
5356
5389
  const request = {
5357
5390
  binding: dependency.target,
5358
5391
  target: dependency.target,
@@ -5450,7 +5483,7 @@ async function execute(state) {
5450
5483
  if (!pending) {
5451
5484
  pending = (async () => {
5452
5485
  try {
5453
- if (target.configuration.requireReadOperationAccessForPopulateDependencies !== false && !await targetReadAllowed(state, target))
5486
+ if (target.configuration.requireOperationAccessForPopulateDependencies !== false && !await targetReadAllowed(state, target))
5454
5487
  return void 0;
5455
5488
  const parts = await work.hookGate.run(
5456
5489
  () => resolveAccessFilterParts({
@@ -5536,12 +5569,6 @@ function readVirtualPopulateOriginalReference(row, address, path) {
5536
5569
  function hasVirtualPopulatePublicReference(row, address, path) {
5537
5570
  return !!rows.get(row)?.publicRequests.some((request) => addressKey(request.address) === addressKey([...address, path]));
5538
5571
  }
5539
- function isVirtualPopulateReferenceVisible(row, address, path) {
5540
- const record3 = rows.get(row);
5541
- const occurrence = record3?.occurrences.get(addressKey(address));
5542
- const target = occurrence?.refs.get(path)?.present ? occurrence.referenceTargets.get(path) : void 0;
5543
- return record3 && target ? targetReadAllowed(record3.batch, target) : Promise.resolve(true);
5544
- }
5545
5572
  function readVirtualPopulateInputs(row, address, virtualName) {
5546
5573
  const record3 = rows.get(row);
5547
5574
  if (!record3?.batch.completed) return { available: false };
@@ -5665,12 +5692,12 @@ async function loadVirtualPopulateOutputRows(owner, inputs, plan, publicPopulate
5665
5692
  }
5666
5693
  return output;
5667
5694
  }
5668
- var import_mongoose7, import_node_util5, import_utils26, batches, rows, outputRows, fetchedPublicIdentities, publicViewIdentities, familyRawFetches, addressKey, storage, originalRef, copyOriginalValue, readPolicy, compatible, idKey, logUnavailable;
5695
+ var import_mongoose7, import_node_util5, import_utils27, batches, rows, outputRows, fetchedPublicIdentities, publicViewIdentities, familyRawFetches, addressKey, storage, originalRef, copyOriginalValue, readPolicy, compatible, idKey, logUnavailable;
5669
5696
  var init_virtual_populate_execution = __esm({
5670
5697
  "src/acl/virtual-populate-execution.ts"() {
5671
5698
  import_mongoose7 = require("mongoose");
5672
5699
  import_node_util5 = require("util");
5673
- import_utils26 = require("@web-ts-toolkit/utils");
5700
+ import_utils27 = require("@web-ts-toolkit/utils");
5674
5701
  init_cache();
5675
5702
  init_core_shared();
5676
5703
  init_document();
@@ -5687,7 +5714,7 @@ var init_virtual_populate_execution = __esm({
5687
5714
  publicViewIdentities = /* @__PURE__ */ new WeakMap();
5688
5715
  familyRawFetches = /* @__PURE__ */ new WeakMap();
5689
5716
  addressKey = (address) => JSON.stringify(address);
5690
- storage = (value) => value instanceof import_mongoose7.Document ? value._doc : (0, import_utils26.isPlainObject)(value) ? value : void 0;
5717
+ storage = (value) => value instanceof import_mongoose7.Document ? value._doc : (0, import_utils27.isPlainObject)(value) ? value : void 0;
5691
5718
  originalRef = (source, key) => {
5692
5719
  const record3 = storage(source);
5693
5720
  return {
@@ -5700,7 +5727,7 @@ var init_virtual_populate_execution = __esm({
5700
5727
  const option = getCapturedAuthorizationOption(configuration, `${key}.${access}`);
5701
5728
  return key === "operationAccess" || typeof option === "function" ? option : void 0;
5702
5729
  });
5703
- 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.requireReadOperationAccessForPopulateDependencies === b.binding.configuration.requireReadOperationAccessForPopulateDependencies && // 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.
5704
5731
  equivalentVirtualPopulatePredicate(
5705
5732
  a.binding.configuration.catalog.persistedPaths,
5706
5733
  b.binding.configuration.catalog.persistedPaths
@@ -5727,7 +5754,7 @@ async function resolveOutputDocumentAuthorization(args) {
5727
5754
  try {
5728
5755
  const run = () => hook.call(this, doc, permissions, args.context);
5729
5756
  const grants = await getRequestWorkState(binding.request, binding.runtime).hookGate.run(run);
5730
- return (0, import_utils27.isPlainObject)(grants) ? grants : {};
5757
+ return (0, import_utils28.isPlainObject)(grants) ? grants : {};
5731
5758
  } catch (error2) {
5732
5759
  warn("docPermissions hook failed; applying empty document permissions", {
5733
5760
  modelName: binding.modelName,
@@ -5842,7 +5869,7 @@ function copyOutputValue(value, plan, path) {
5842
5869
  const visit = (input, current) => {
5843
5870
  if (Array.isArray(input)) return input.map((entry) => visit(entry, current));
5844
5871
  if (input instanceof Map) return visit(Object.fromEntries(input), current);
5845
- if (!(0, import_utils27.isPlainObject)(input)) return deepIsolateValue(input);
5872
+ if (!(0, import_utils28.isPlainObject)(input)) return deepIsolateValue(input);
5846
5873
  const output = {};
5847
5874
  for (const [key, entry] of Object.entries(input)) {
5848
5875
  const child = `${current}.${key}`;
@@ -5858,25 +5885,21 @@ function copyOutputValue(value, plan, path) {
5858
5885
  }
5859
5886
  function copyAuthorizedReference(value, plan, path) {
5860
5887
  if (Array.isArray(value)) return value.map((entry) => copyAuthorizedReference(entry, plan, path));
5861
- if (!(0, import_utils27.isPlainObject)(value)) return deepIsolateValue(value);
5888
+ if (!(0, import_utils28.isPlainObject)(value)) return deepIsolateValue(value);
5862
5889
  const handle = getAssociatedDocumentAuthorization(value, plan.authorization);
5863
5890
  if (handle) {
5864
5891
  const copy = deepIsolateValue(value);
5865
5892
  transferDocumentAuthorizationGraph(value, copy);
5866
5893
  return copy;
5867
5894
  }
5868
- const { relatedTargets } = readServiceAuthorization(plan.authorization, plan.authorizationBinding);
5869
- if (relatedTargets.some((target) => target.path === path && target.kind === "passthrough")) {
5870
- return deepIsolateValue(value);
5871
- }
5872
5895
  return Object.prototype.hasOwnProperty.call(value, "_id") ? deepIsolateValue(value._id) : void 0;
5873
5896
  }
5874
5897
  function retainOutputMetadata(output, source, configuration, scope2) {
5875
5898
  if (scope2.length || configuration.stripPermissionsField) return;
5876
5899
  const parts = (configuration.documentPermissionField ?? "_permissions").split(".");
5877
5900
  let value = source;
5878
- for (const part of parts) value = (0, import_utils27.isPlainObject)(value) ? value[part] : void 0;
5879
- if (!(0, import_utils27.isPlainObject)(value)) return;
5901
+ for (const part of parts) value = (0, import_utils28.isPlainObject)(value) ? value[part] : void 0;
5902
+ if (!(0, import_utils28.isPlainObject)(value)) return;
5880
5903
  const keys2 = configuration.exposedDocPermissionKeys;
5881
5904
  const metadata = Object.fromEntries(
5882
5905
  Object.entries(value).filter(
@@ -5886,7 +5909,7 @@ function retainOutputMetadata(output, source, configuration, scope2) {
5886
5909
  const copy = { ...output };
5887
5910
  let target = copy;
5888
5911
  for (const part of parts.slice(0, -1)) {
5889
- target[part] = (0, import_utils27.isPlainObject)(target[part]) ? { ...target[part] } : {};
5912
+ target[part] = (0, import_utils28.isPlainObject)(target[part]) ? { ...target[part] } : {};
5890
5913
  target = target[part];
5891
5914
  }
5892
5915
  target[parts[parts.length - 1]] = deepIsolateValue(metadata);
@@ -5928,7 +5951,7 @@ async function filterExistingOutput(source, plan, handle, associated) {
5928
5951
  for (const entry of value2) values.push(await one(entry) ?? null);
5929
5952
  return values;
5930
5953
  }
5931
- if (!(0, import_utils27.isPlainObject)(value2)) return value2 === null ? null : void 0;
5954
+ if (!(0, import_utils28.isPlainObject)(value2)) return value2 === null ? null : void 0;
5932
5955
  const childHandle = associated ? getAssociatedDocumentAuthorization(value2) : void 0;
5933
5956
  let child = scoped;
5934
5957
  if (childHandle) {
@@ -6008,7 +6031,7 @@ async function filterModelOutputForHelper(args) {
6008
6031
  const plan = helperPlan(normalized.authorization, binding);
6009
6032
  if (args.doc == null) return { output: args.doc, fields: [] };
6010
6033
  const source = isolateDocForOutput(args.doc);
6011
- if (!(0, import_utils27.isPlainObject)(source)) return authorizationError("output helper requires one plain or hydrated document");
6034
+ if (!(0, import_utils28.isPlainObject)(source)) return authorizationError("output helper requires one plain or hydrated document");
6012
6035
  const knownOutput = !!args.doc && typeof args.doc === "object" && isKnownAuthorizationOutput(args.doc);
6013
6036
  const handle = await resolveOutputDocumentAuthorization({
6014
6037
  authorization: normalized.authorization,
@@ -6019,10 +6042,10 @@ async function filterModelOutputForHelper(args) {
6019
6042
  });
6020
6043
  return filterExistingOutput(source, plan, handle, false);
6021
6044
  }
6022
- var import_utils27, unresolvedDocuments, owningDocuments;
6045
+ var import_utils28, unresolvedDocuments, owningDocuments;
6023
6046
  var init_output_field_filter = __esm({
6024
6047
  "src/acl/output-field-filter.ts"() {
6025
- import_utils27 = require("@web-ts-toolkit/utils");
6048
+ import_utils28 = require("@web-ts-toolkit/utils");
6026
6049
  init_permissions_alias();
6027
6050
  init_document();
6028
6051
  init_request_work();
@@ -6119,8 +6142,8 @@ async function finalizeSingleDoc(args, input) {
6119
6142
  const privateRow = args.virtualPopulateRow ?? (original && typeof original === "object" ? getVirtualPopulateRow(original) : void 0);
6120
6143
  const privateAddress = args.virtualPopulateAddress ?? [];
6121
6144
  const isolated = isolateDocForOutput(input);
6122
- const output = (0, import_utils28.isPlainObject)(isolated) ? isolated : {};
6123
- if (captured && (0, import_utils28.isPlainObject)(input))
6145
+ const output = (0, import_utils29.isPlainObject)(isolated) ? isolated : {};
6146
+ if (captured && (0, import_utils29.isPlainObject)(input))
6124
6147
  for (const key of Object.keys(output)) {
6125
6148
  transferDocumentAuthorizationGraph(input[key], output[key]);
6126
6149
  }
@@ -6175,7 +6198,7 @@ async function finalizeSingleDoc(args, input) {
6175
6198
  );
6176
6199
  continue;
6177
6200
  }
6178
- if (captured && !(0, import_utils28.isPlainObject)(rawContainer) && !Array.isArray(rawContainer)) {
6201
+ if (captured && !(0, import_utils29.isPlainObject)(rawContainer) && !Array.isArray(rawContainer)) {
6179
6202
  delete output[containerName];
6180
6203
  continue;
6181
6204
  }
@@ -6199,7 +6222,7 @@ async function finalizeSingleDoc(args, input) {
6199
6222
  const finalizeOneChild = async (rawChild, address) => {
6200
6223
  if (captured && Array.isArray(rawChild))
6201
6224
  return mapWithConcurrencyLimit(rawChild, limit, (entry, index) => finalizeOneChild(entry, [...address, index]));
6202
- if (!(0, import_utils28.isPlainObject)(rawChild) && !Array.isArray(rawChild)) return captured ? null : deepIsolateValue(rawChild);
6225
+ if (!(0, import_utils29.isPlainObject)(rawChild) && !Array.isArray(rawChild)) return captured ? null : deepIsolateValue(rawChild);
6203
6226
  if (args.traversal?.finalizeEmbeddedChildren) {
6204
6227
  return args.traversal.finalizeEmbeddedChildren({
6205
6228
  containerName,
@@ -6225,7 +6248,7 @@ async function finalizeSingleDoc(args, input) {
6225
6248
  (entry, index) => finalizeOneChild(entry, [...privateAddress, containerName, index])
6226
6249
  );
6227
6250
  output[containerName] = finalized;
6228
- } else if ((0, import_utils28.isPlainObject)(rawContainer)) {
6251
+ } else if ((0, import_utils29.isPlainObject)(rawContainer)) {
6229
6252
  output[containerName] = await finalizeOneChild(rawContainer, [
6230
6253
  ...privateAddress,
6231
6254
  containerName
@@ -6237,8 +6260,8 @@ async function finalizeSingleDoc(args, input) {
6237
6260
  let rawRelated;
6238
6261
  let originalRelated;
6239
6262
  try {
6240
- rawRelated = target.path.includes(".") ? (0, import_utils28.get)(output, target.path) : output[target.path];
6241
- originalRelated = (0, import_utils28.get)(original, target.path);
6263
+ rawRelated = target.path.includes(".") ? (0, import_utils29.get)(output, target.path) : output[target.path];
6264
+ originalRelated = (0, import_utils29.get)(original, target.path);
6242
6265
  } catch {
6243
6266
  continue;
6244
6267
  }
@@ -6269,7 +6292,7 @@ async function finalizeSingleDoc(args, input) {
6269
6292
  related: target.plan.relatedPlans?.length ? (args.related ?? []).filter((entry) => entry.path.startsWith(`${target.path}.`)) : []
6270
6293
  };
6271
6294
  const finalizeOneRelated = async (rawChild, originalChild = rawChild) => {
6272
- if (!(0, import_utils28.isPlainObject)(rawChild) && !Array.isArray(rawChild)) return rawChild;
6295
+ if (!(0, import_utils29.isPlainObject)(rawChild) && !Array.isArray(rawChild)) return rawChild;
6273
6296
  if (typeof rawChild?._bsontype === "string") return rawChild;
6274
6297
  const childOriginal = getIncludeOriginal(originalChild);
6275
6298
  const childRow = childOriginal && typeof childOriginal === "object" ? getVirtualPopulateRow(childOriginal) : void 0;
@@ -6290,13 +6313,13 @@ async function finalizeSingleDoc(args, input) {
6290
6313
  limit,
6291
6314
  (entry, index) => finalizeOneRelated(entry, Array.isArray(originalRelated) ? originalRelated[index] : void 0)
6292
6315
  );
6293
- } else if ((0, import_utils28.isPlainObject)(rawRelated)) {
6316
+ } else if ((0, import_utils29.isPlainObject)(rawRelated)) {
6294
6317
  finalized = await finalizeOneRelated(rawRelated, originalRelated);
6295
6318
  } else {
6296
6319
  continue;
6297
6320
  }
6298
6321
  try {
6299
- if (target.path.includes(".")) (0, import_utils28.set)(output, target.path, finalized);
6322
+ if (target.path.includes(".")) (0, import_utils29.set)(output, target.path, finalized);
6300
6323
  else output[target.path] = finalized;
6301
6324
  } catch {
6302
6325
  }
@@ -6410,7 +6433,6 @@ async function finalizeSingleDoc(args, input) {
6410
6433
  if (!captured && documentPermissionField in output) keep.add(documentPermissionField);
6411
6434
  const trimmed = {};
6412
6435
  for (const key of keep) {
6413
- if (privateRow && !await isVirtualPopulateReferenceVisible(privateRow, privateAddress, key)) continue;
6414
6436
  if (privateRow && !hasVirtualPopulatePublicReference(privateRow, privateAddress, key)) {
6415
6437
  const ref = readVirtualPopulateOriginalReference(privateRow, privateAddress, key);
6416
6438
  if (ref) {
@@ -6477,10 +6499,10 @@ async function finalizeModelOutputs(args) {
6477
6499
  return finalizeSingleDoc(internal, input);
6478
6500
  });
6479
6501
  }
6480
- var import_utils28, isVirtualContainerValue3, getScopeVirtualsObject2, getScopeVirtualNames, getScopedPermissionSchema2, resolveGlobalPermissions, resolveDocPermissions, isAbsentDependency, __finalizeInternals;
6502
+ var import_utils29, isVirtualContainerValue3, getScopeVirtualsObject2, getScopeVirtualNames, getScopedPermissionSchema2, resolveGlobalPermissions, resolveDocPermissions, isAbsentDependency, __finalizeInternals;
6481
6503
  var init_finalize_model_output = __esm({
6482
6504
  "src/output/finalize-model-output.ts"() {
6483
- import_utils28 = require("@web-ts-toolkit/utils");
6505
+ import_utils29 = require("@web-ts-toolkit/utils");
6484
6506
  init_document();
6485
6507
  init_concurrency();
6486
6508
  init_request_work();
@@ -6493,20 +6515,20 @@ var init_finalize_model_output = __esm({
6493
6515
  init_field_catalog();
6494
6516
  init_virtual_populate_execution();
6495
6517
  init_include_output();
6496
- isVirtualContainerValue3 = (value) => (0, import_utils28.isPlainObject)(value) && "sub" in value;
6518
+ isVirtualContainerValue3 = (value) => (0, import_utils29.isPlainObject)(value) && "sub" in value;
6497
6519
  getScopeVirtualsObject2 = (rootVirtuals, scopePath) => {
6498
- if (!rootVirtuals || !(0, import_utils28.isPlainObject)(rootVirtuals)) return null;
6520
+ if (!rootVirtuals || !(0, import_utils29.isPlainObject)(rootVirtuals)) return null;
6499
6521
  if (scopePath.length === 0) return rootVirtuals;
6500
6522
  let current = rootVirtuals;
6501
6523
  for (let i = 0; i < scopePath.length; i += 2) {
6502
6524
  const field = scopePath[i];
6503
6525
  const subMarker = scopePath[i + 1];
6504
6526
  if (!field || subMarker !== "sub") return null;
6505
- if (!(0, import_utils28.isPlainObject)(current)) return null;
6527
+ if (!(0, import_utils29.isPlainObject)(current)) return null;
6506
6528
  const container = current[field];
6507
6529
  if (!isVirtualContainerValue3(container)) return null;
6508
6530
  current = container.sub;
6509
- if (!(0, import_utils28.isPlainObject)(current)) return null;
6531
+ if (!(0, import_utils29.isPlainObject)(current)) return null;
6510
6532
  }
6511
6533
  return current;
6512
6534
  };
@@ -6519,11 +6541,11 @@ var init_finalize_model_output = __esm({
6519
6541
  return Object.entries(scopeVirtuals).filter(([, v]) => v !== void 0 && !isVirtualContainerValue3(v)).map(([k]) => k);
6520
6542
  };
6521
6543
  getScopedPermissionSchema2 = (root, scopePath) => {
6522
- if (!root || !(0, import_utils28.isPlainObject)(root)) return null;
6544
+ if (!root || !(0, import_utils29.isPlainObject)(root)) return null;
6523
6545
  if (scopePath.length === 0) return root;
6524
6546
  try {
6525
- const scoped = (0, import_utils28.get)(root, scopePath.join("."));
6526
- return (0, import_utils28.isPlainObject)(scoped) ? scoped : null;
6547
+ const scoped = (0, import_utils29.get)(root, scopePath.join("."));
6548
+ return (0, import_utils29.isPlainObject)(scoped) ? scoped : null;
6527
6549
  } catch {
6528
6550
  return null;
6529
6551
  }
@@ -6582,7 +6604,7 @@ var init_finalize_model_output = __esm({
6582
6604
  const grants = await args.sharedGate.run(
6583
6605
  () => hook.call(args.request, isolatedForHook, globalPerms, scopeContext)
6584
6606
  );
6585
- const normalized = (0, import_utils28.isPlainObject)(grants) ? grants : {};
6607
+ const normalized = (0, import_utils29.isPlainObject)(grants) ? grants : {};
6586
6608
  scopeContext.docPermissions = normalized;
6587
6609
  return normalized;
6588
6610
  }
@@ -6654,40 +6676,20 @@ __export(index_exports, {
6654
6676
  setModelOptions: () => setModelOptions
6655
6677
  });
6656
6678
  module.exports = __toCommonJS(index_exports);
6657
- var import_utils46 = require("@web-ts-toolkit/utils");
6679
+ var import_utils47 = require("@web-ts-toolkit/utils");
6658
6680
 
6659
6681
  // src/middleware.ts
6660
6682
  var import_express_json_router5 = __toESM(require("@web-ts-toolkit/express-json-router"));
6661
- var import_utils39 = require("@web-ts-toolkit/utils");
6683
+ var import_utils40 = require("@web-ts-toolkit/utils");
6662
6684
 
6663
6685
  // src/core.ts
6664
6686
  init_public_admission();
6665
- var import_utils38 = require("@web-ts-toolkit/utils");
6687
+ var import_utils39 = require("@web-ts-toolkit/utils");
6666
6688
  init_options();
6667
-
6668
- // src/meta.ts
6669
- init_runtime();
6670
- init_runtime_context();
6671
- var getRuntime5 = () => getActiveRuntime() ?? defaultRuntime;
6672
- var getModelRef = (modelName, refPath) => {
6673
- const direct = getRuntime5().getModelRef(modelName, refPath);
6674
- if (direct) return direct;
6675
- if (!refPath.includes(".")) return null;
6676
- try {
6677
- const runtime = getRuntime5();
6678
- const instance = runtime.getModelInstance?.(
6679
- modelName
6680
- );
6681
- const schemaPath = instance?.schema?.path?.(refPath);
6682
- const ref = schemaPath?.options?.ref ?? schemaPath?.caster?.options?.ref ?? null;
6683
- return typeof ref === "string" && ref.length > 0 ? ref : null;
6684
- } catch {
6685
- return null;
6686
- }
6687
- };
6689
+ init_permission();
6688
6690
 
6689
6691
  // src/services/base.ts
6690
- var import_utils23 = require("@web-ts-toolkit/utils");
6692
+ var import_utils24 = require("@web-ts-toolkit/utils");
6691
6693
  init_options();
6692
6694
  init_helpers();
6693
6695
  init_document();
@@ -6813,7 +6815,7 @@ function requestFieldScope(options) {
6813
6815
  init_public_admission();
6814
6816
 
6815
6817
  // src/correlated-includes.ts
6816
- var import_utils19 = require("@web-ts-toolkit/utils");
6818
+ var import_utils20 = require("@web-ts-toolkit/utils");
6817
6819
  init_request_complexity();
6818
6820
  init_sort_policy();
6819
6821
  var PARENT_MARKER_KEY = "$parent";
@@ -6826,10 +6828,10 @@ var FIELD_SEGMENT_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
6826
6828
  var ARRAY_INDEX_SEGMENT_PATTERN = /^(0|[1-9]\d*)$/;
6827
6829
  var ownKeys = (value) => Object.keys(value);
6828
6830
  function isParentRefMarker(value) {
6829
- return (0, import_utils19.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === PARENT_MARKER_KEY;
6831
+ return (0, import_utils20.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === PARENT_MARKER_KEY;
6830
6832
  }
6831
6833
  function isEscapedParentRef(value) {
6832
- return (0, import_utils19.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === ESCAPE_WRAPPER_KEY;
6834
+ return (0, import_utils20.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === ESCAPE_WRAPPER_KEY;
6833
6835
  }
6834
6836
  function hasMarkerKey(value) {
6835
6837
  return ownKeys(value).includes(PARENT_MARKER_KEY) || ownKeys(value).includes(ESCAPE_WRAPPER_KEY);
@@ -6848,12 +6850,12 @@ function containsParentMarkerShape(value) {
6848
6850
  const seen = /* @__PURE__ */ new Set();
6849
6851
  const visit = (current) => {
6850
6852
  if (isParentRefMarker(current) || isEscapedParentRef(current)) return true;
6851
- if ((0, import_utils19.isArray)(current)) {
6853
+ if ((0, import_utils20.isArray)(current)) {
6852
6854
  if (seen.has(current)) return false;
6853
6855
  seen.add(current);
6854
6856
  return current.some(visit);
6855
6857
  }
6856
- if ((0, import_utils19.isPlainObject)(current)) {
6858
+ if ((0, import_utils20.isPlainObject)(current)) {
6857
6859
  if (seen.has(current)) return false;
6858
6860
  seen.add(current);
6859
6861
  if (hasMarkerKey(current)) return true;
@@ -6883,7 +6885,7 @@ function scanTemplateValueNode(value, path, issues) {
6883
6885
  }
6884
6886
  return;
6885
6887
  }
6886
- if ((0, import_utils19.isPlainObject)(value)) {
6888
+ if ((0, import_utils20.isPlainObject)(value)) {
6887
6889
  if (hasMarkerKey(value)) {
6888
6890
  issues.push({
6889
6891
  message: 'Malformed $parent reference: objects carrying $parent must be exactly { "$parent": "<field>" }',
@@ -6894,7 +6896,7 @@ function scanTemplateValueNode(value, path, issues) {
6894
6896
  scanTemplateObjectEntries(value, path, issues);
6895
6897
  return;
6896
6898
  }
6897
- if ((0, import_utils19.isArray)(value)) {
6899
+ if ((0, import_utils20.isArray)(value)) {
6898
6900
  value.forEach((item, index) => scanTemplateValueNode(item, [...path, index], issues));
6899
6901
  }
6900
6902
  }
@@ -6935,7 +6937,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
6935
6937
  continue;
6936
6938
  }
6937
6939
  if (LOGICAL_CLAUSE_KEYS.has(key)) {
6938
- if (!(0, import_utils19.isArray)(child)) {
6940
+ if (!(0, import_utils20.isArray)(child)) {
6939
6941
  scanTemplateValueNode(child, childPath, issues);
6940
6942
  continue;
6941
6943
  }
@@ -6948,7 +6950,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
6948
6950
  });
6949
6951
  return;
6950
6952
  }
6951
- if ((0, import_utils19.isPlainObject)(clause)) {
6953
+ if ((0, import_utils20.isPlainObject)(clause)) {
6952
6954
  scanTemplateObjectEntries(clause, clausePath, issues);
6953
6955
  }
6954
6956
  });
@@ -6959,7 +6961,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
6959
6961
  }
6960
6962
  function validateCorrelatedFilterTemplate(filter2) {
6961
6963
  const issues = [];
6962
- if (!(0, import_utils19.isPlainObject)(filter2)) {
6964
+ if (!(0, import_utils20.isPlainObject)(filter2)) {
6963
6965
  issues.push({ message: "Correlated include filter must be an object", path: [] });
6964
6966
  return issues;
6965
6967
  }
@@ -7002,13 +7004,13 @@ function collectFilterReferencePaths(filter2) {
7002
7004
  return;
7003
7005
  }
7004
7006
  if (isEscapedParentRef(value)) return;
7005
- if ((0, import_utils19.isArray)(value)) {
7007
+ if ((0, import_utils20.isArray)(value)) {
7006
7008
  if (seen.has(value)) return;
7007
7009
  seen.add(value);
7008
7010
  value.forEach(visitValue);
7009
7011
  return;
7010
7012
  }
7011
- if ((0, import_utils19.isPlainObject)(value)) {
7013
+ if ((0, import_utils20.isPlainObject)(value)) {
7012
7014
  if (seen.has(value)) return;
7013
7015
  seen.add(value);
7014
7016
  for (const [key, child] of Object.entries(value)) {
@@ -7054,7 +7056,7 @@ function getOwnPathValue(parent, path) {
7054
7056
  return current;
7055
7057
  }
7056
7058
  function cloneSubstitutedValue(value) {
7057
- if ((0, import_utils19.isPlainObject)(value) || (0, import_utils19.isArray)(value)) return (0, import_utils19.cloneDeep)(value);
7059
+ if ((0, import_utils20.isPlainObject)(value) || (0, import_utils20.isArray)(value)) return (0, import_utils20.cloneDeep)(value);
7058
7060
  return value;
7059
7061
  }
7060
7062
  function literalParentRefObject(path) {
@@ -7095,7 +7097,7 @@ function resolveObjectEntries(obj, parent) {
7095
7097
  continue;
7096
7098
  }
7097
7099
  if (LOGICAL_CLAUSE_KEYS.has(key)) {
7098
- if (!(0, import_utils19.isArray)(child)) {
7100
+ if (!(0, import_utils20.isArray)(child)) {
7099
7101
  out[key] = resolveValueNode(child, parent, false);
7100
7102
  continue;
7101
7103
  }
@@ -7103,7 +7105,7 @@ function resolveObjectEntries(obj, parent) {
7103
7105
  if (isParentRefMarker(clause) || isEscapedParentRef(clause)) {
7104
7106
  throw new CorrelatedReferenceError(`Unsupported $parent reference as a direct ${key} clause`);
7105
7107
  }
7106
- if (!(0, import_utils19.isPlainObject)(clause)) return cloneSubstitutedValue(clause);
7108
+ if (!(0, import_utils20.isPlainObject)(clause)) return cloneSubstitutedValue(clause);
7107
7109
  return resolveObjectEntries(clause, parent);
7108
7110
  });
7109
7111
  continue;
@@ -7132,10 +7134,10 @@ function resolveValueNode(template, parent, bare) {
7132
7134
  }
7133
7135
  const value = getOwnPathValue(parent, path);
7134
7136
  if (value === void 0 || value === null) throw UNRESOLVABLE;
7135
- if (bare && (0, import_utils19.isPlainObject)(value)) return { $eq: (0, import_utils19.cloneDeep)(value) };
7137
+ if (bare && (0, import_utils20.isPlainObject)(value)) return { $eq: (0, import_utils20.cloneDeep)(value) };
7136
7138
  return cloneSubstitutedValue(value);
7137
7139
  }
7138
- if ((0, import_utils19.isPlainObject)(template)) {
7140
+ if ((0, import_utils20.isPlainObject)(template)) {
7139
7141
  if (hasMarkerKey(template)) {
7140
7142
  throw new CorrelatedReferenceError(
7141
7143
  'Malformed $parent reference: objects carrying $parent must be exactly { "$parent": "<field>" }'
@@ -7143,7 +7145,7 @@ function resolveValueNode(template, parent, bare) {
7143
7145
  }
7144
7146
  return resolveObjectEntries(template, parent);
7145
7147
  }
7146
- if ((0, import_utils19.isArray)(template)) {
7148
+ if ((0, import_utils20.isArray)(template)) {
7147
7149
  return template.map((item) => resolveValueNode(item, parent, false));
7148
7150
  }
7149
7151
  return template;
@@ -7177,7 +7179,7 @@ function resolveCorrelatedIdTemplate(id, parent) {
7177
7179
  }
7178
7180
  function resolveCorrelatedFilterTemplate(filter2, parent) {
7179
7181
  try {
7180
- if (!(0, import_utils19.isPlainObject)(filter2) || isParentRefMarker(filter2) || isEscapedParentRef(filter2)) {
7182
+ if (!(0, import_utils20.isPlainObject)(filter2) || isParentRefMarker(filter2) || isEscapedParentRef(filter2)) {
7181
7183
  throw new CorrelatedReferenceError("Correlated include filter must be an object");
7182
7184
  }
7183
7185
  return { status: "resolved", filter: resolveObjectEntries(filter2, parent) };
@@ -7192,7 +7194,7 @@ function validateExpandedCorrelatedOperands(expanded, limits) {
7192
7194
  var MAX_NESTED_INCLUDE_DEPTH = 10;
7193
7195
  function validateCorrelatedArgsShape(args, op, depth) {
7194
7196
  if (args === void 0) return [];
7195
- if (!(0, import_utils19.isPlainObject)(args)) return ["Correlated include args must be an object"];
7197
+ if (!(0, import_utils20.isPlainObject)(args)) return ["Correlated include args must be an object"];
7196
7198
  const record3 = args;
7197
7199
  const allowed = op === "list" ? /* @__PURE__ */ new Set(["select", "sort", "skip", "limit", "page", "pageSize", "include"]) : /* @__PURE__ */ new Set(["select", "sort", "include"]);
7198
7200
  for (const key of Object.keys(record3)) {
@@ -7214,7 +7216,7 @@ function validateCorrelatedArgsShape(args, op, depth) {
7214
7216
  return [];
7215
7217
  }
7216
7218
  function validateCorrelatedIncludeShape(entry, depth = 0) {
7217
- if (!(0, import_utils19.isPlainObject)(entry)) return ["Correlated include must be an object"];
7219
+ if (!(0, import_utils20.isPlainObject)(entry)) return ["Correlated include must be an object"];
7218
7220
  const record3 = entry;
7219
7221
  if (record3.mode !== "correlated") return ['Correlated include mode must be "correlated"'];
7220
7222
  if (typeof record3.model !== "string" || record3.model.length === 0)
@@ -7227,7 +7229,7 @@ function validateCorrelatedIncludeShape(entry, depth = 0) {
7227
7229
  if ("localField" in record3 || "foreignField" in record3) {
7228
7230
  return ["Correlated includes must not carry localField or foreignField"];
7229
7231
  }
7230
- if (record3.options !== void 0 && !((0, import_utils19.isPlainObject)(record3.options) && Object.keys(record3.options).length === 0)) {
7232
+ if (record3.options !== void 0 && !((0, import_utils20.isPlainObject)(record3.options) && Object.keys(record3.options).length === 0)) {
7231
7233
  return ["Correlated include options must be absent or empty"];
7232
7234
  }
7233
7235
  const hasId = record3.id !== void 0;
@@ -7249,7 +7251,7 @@ function validateCorrelatedIncludeShape(entry, depth = 0) {
7249
7251
  return validateCorrelatedArgsShape(record3.args, record3.op, depth);
7250
7252
  }
7251
7253
  function isCorrelatedInclude(value) {
7252
- return (0, import_utils19.isPlainObject)(value) && value.mode === "correlated";
7254
+ return (0, import_utils20.isPlainObject)(value) && value.mode === "correlated";
7253
7255
  }
7254
7256
 
7255
7257
  // src/services/base.ts
@@ -7473,9 +7475,31 @@ function castCountGroups(input, values) {
7473
7475
  // src/services/base.ts
7474
7476
  init_service_authorization();
7475
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
+
7476
7499
  // src/acl/related-execution.ts
7477
7500
  init_public_admission();
7478
7501
  init_model_output_planning();
7502
+ init_populate_target_configuration();
7479
7503
  init_authorization_snapshot();
7480
7504
 
7481
7505
  // src/acl/service-execution.ts
@@ -7770,16 +7794,15 @@ function captureRelatedTargets(runtime, modelName, args = {}, depth = 0, globalO
7770
7794
  for (const entry of entries(args.populate)) {
7771
7795
  const path = typeof entry === "string" ? entry : entry.path;
7772
7796
  if (typeof entry !== "string") assertPopulateAccess(entry.access);
7773
- const model = getModelRef(modelName, path);
7774
- if (model && runtime.hasModel(model))
7797
+ const model = getModelRef(modelName, path, runtime);
7798
+ if (model) {
7799
+ const target = capturePopulateTargetConfiguration(runtime, model, `${modelName}.${path}`);
7775
7800
  targets.push({
7776
7801
  path,
7777
7802
  modelName: model,
7778
- configuration: captureModelAuthorizationConfiguration(runtime, model, void 0, globalOptions),
7803
+ configuration: captureModelAuthorizationConfiguration(runtime, model, target.options, globalOptions),
7779
7804
  staticObjectIdReference: staticObjectIdReference(runtime, modelName, path, model)
7780
7805
  });
7781
- else if (model && !(globalOptions.requireRegisteredPopulateModels === void 0 ? true : globalOptions.requireRegisteredPopulateModels)) {
7782
- targets.push({ path, modelName: model, kind: "passthrough", configuration: { catalog: { paths: [] } } });
7783
7806
  }
7784
7807
  }
7785
7808
  for (const entry of entries(args.include)) {
@@ -7965,20 +7988,20 @@ var copyAuthorizedOutput = (value) => {
7965
7988
  transferDocumentAuthorizationGraph(value, copy);
7966
7989
  return copy;
7967
7990
  };
7968
- var isVirtualContainerValueForGuard = (value) => (0, import_utils23.isPlainObject)(value) && "sub" in value;
7991
+ var isVirtualContainerValueForGuard = (value) => (0, import_utils24.isPlainObject)(value) && "sub" in value;
7969
7992
  var getScopeVirtualsForGuard = (rootVirtuals, scopePath) => {
7970
- if (!rootVirtuals || !(0, import_utils23.isPlainObject)(rootVirtuals)) return null;
7993
+ if (!rootVirtuals || !(0, import_utils24.isPlainObject)(rootVirtuals)) return null;
7971
7994
  if (scopePath.length === 0) return rootVirtuals;
7972
7995
  let current = rootVirtuals;
7973
7996
  for (let i = 0; i < scopePath.length; i += 2) {
7974
7997
  const field = scopePath[i];
7975
7998
  const subMarker = scopePath[i + 1];
7976
7999
  if (!field || subMarker !== "sub") return null;
7977
- if (!(0, import_utils23.isPlainObject)(current)) return null;
8000
+ if (!(0, import_utils24.isPlainObject)(current)) return null;
7978
8001
  const container = current[field];
7979
8002
  if (!isVirtualContainerValueForGuard(container)) return null;
7980
8003
  current = container.sub;
7981
- if (!(0, import_utils23.isPlainObject)(current)) return null;
8004
+ if (!(0, import_utils24.isPlainObject)(current)) return null;
7982
8005
  }
7983
8006
  return current;
7984
8007
  };
@@ -8044,7 +8067,7 @@ var sanitizeSubScopeVirtualKeys = (data, snapshot, sub) => {
8044
8067
  for (const entry of value) stripScope(entry, currentScope);
8045
8068
  return;
8046
8069
  }
8047
- if (!(0, import_utils23.isPlainObject)(value)) return;
8070
+ if (!(0, import_utils24.isPlainObject)(value)) return;
8048
8071
  const record3 = value;
8049
8072
  const leaves = getScopeVirtualLeafNames(snapshot, currentScope);
8050
8073
  for (const leaf of leaves) {
@@ -8057,7 +8080,7 @@ var sanitizeSubScopeVirtualKeys = (data, snapshot, sub) => {
8057
8080
  for (const key of Object.keys(record3)) {
8058
8081
  if (leaves.has(key) || containers.has(key)) continue;
8059
8082
  const child = record3[key];
8060
- if (Array.isArray(child) || (0, import_utils23.isPlainObject)(child)) {
8083
+ if (Array.isArray(child) || (0, import_utils24.isPlainObject)(child)) {
8061
8084
  stripScope(child, currentScope);
8062
8085
  }
8063
8086
  }
@@ -8069,7 +8092,7 @@ var LOGICAL_FILTER_KEYS = /* @__PURE__ */ new Set(["$and", "$or", "$nor"]);
8069
8092
  var isOperatorKey = (key) => key.startsWith("$");
8070
8093
  var REMOVED_VIRTUAL_FILTER = /* @__PURE__ */ Symbol("removed virtual filter clause");
8071
8094
  var rewriteFilterObject = (value, visit) => {
8072
- if (!(0, import_utils23.isPlainObject)(value)) return value;
8095
+ if (!(0, import_utils24.isPlainObject)(value)) return value;
8073
8096
  let changed = false;
8074
8097
  const entries = [];
8075
8098
  for (const [key, child] of Object.entries(value)) {
@@ -8100,7 +8123,7 @@ var resolveVirtualFilterField = (path, scope2) => {
8100
8123
  if (!Object.hasOwn(scope2, segment) || scope2[segment] === void 0) return null;
8101
8124
  const definition = scope2[segment];
8102
8125
  if (!isVirtualContainerValueForGuard(definition)) return REMOVED_VIRTUAL_FILTER;
8103
- scope2 = (0, import_utils23.isPlainObject)(definition.sub) ? definition.sub : null;
8126
+ scope2 = (0, import_utils24.isPlainObject)(definition.sub) ? definition.sub : null;
8104
8127
  inContainer = true;
8105
8128
  }
8106
8129
  return scope2;
@@ -8112,7 +8135,7 @@ var stripVirtualFilterOperator = (key, value, scope2) => {
8112
8135
  }
8113
8136
  if (key === "$all") {
8114
8137
  return rewriteFilterClauses(value, (entry) => {
8115
- if (!(0, import_utils23.isPlainObject)(entry) || Object.keys(entry).length !== 1 || !Object.hasOwn(entry, "$elemMatch")) return entry;
8138
+ if (!(0, import_utils24.isPlainObject)(entry) || Object.keys(entry).length !== 1 || !Object.hasOwn(entry, "$elemMatch")) return entry;
8116
8139
  return rewriteFilterObject(entry, (operator, operand) => stripVirtualFilterOperator(operator, operand, scope2));
8117
8140
  });
8118
8141
  }
@@ -8127,7 +8150,7 @@ var stripVirtualFilterQuery = (value, scope2, element = false) => {
8127
8150
  if (isOperatorKey(key)) return element ? stripVirtualFilterOperator(key, child, scope2) : child;
8128
8151
  const fieldScope = resolveVirtualFilterField(key, scope2);
8129
8152
  if (fieldScope === REMOVED_VIRTUAL_FILTER) return REMOVED_VIRTUAL_FILTER;
8130
- if (!fieldScope || !(0, import_utils23.isPlainObject)(child)) return child;
8153
+ if (!fieldScope || !(0, import_utils24.isPlainObject)(child)) return child;
8131
8154
  if (Object.keys(child).some(isOperatorKey)) {
8132
8155
  return rewriteFilterObject(
8133
8156
  child,
@@ -8149,9 +8172,9 @@ var stripSubVirtualKeysFromFilter = (filter2, snapshot, sub) => {
8149
8172
  function getCorrelatedTemplateDepth(includes) {
8150
8173
  let max = 0;
8151
8174
  const visit = (entries, depth) => {
8152
- const list = (0, import_utils23.castArray)(entries).filter(Boolean);
8175
+ const list = (0, import_utils24.castArray)(entries).filter(Boolean);
8153
8176
  for (const entry of list) {
8154
- if (!(0, import_utils23.isPlainObject)(entry)) continue;
8177
+ if (!(0, import_utils24.isPlainObject)(entry)) continue;
8155
8178
  max = Math.max(max, depth);
8156
8179
  const nested = entry.args?.include;
8157
8180
  if (nested !== void 0) {
@@ -8176,11 +8199,11 @@ function validateClientFilter(filter2) {
8176
8199
  }
8177
8200
  const blockedOperators = /* @__PURE__ */ new Set(["$where", "$expr", "$function", "$accumulator"]);
8178
8201
  const visit = (value, path) => {
8179
- if ((0, import_utils23.isArray)(value)) {
8202
+ if ((0, import_utils24.isArray)(value)) {
8180
8203
  value.forEach((item, index) => visit(item, `${path}[${index}]`));
8181
8204
  return;
8182
8205
  }
8183
- if (!(0, import_utils23.isPlainObject)(value)) return;
8206
+ if (!(0, import_utils24.isPlainObject)(value)) return;
8184
8207
  Object.entries(value).forEach(([key, child]) => {
8185
8208
  const nextPath = path ? `${path}.${key}` : key;
8186
8209
  if (blockedOperators.has(key)) {
@@ -8385,7 +8408,7 @@ var Base = class {
8385
8408
  }
8386
8409
  processInclude(include, authorization) {
8387
8410
  assertPublicAdmission(include, "include");
8388
- const items = (0, import_utils23.compact)((0, import_utils23.castArray)(include));
8411
+ const items = (0, import_utils24.compact)((0, import_utils24.castArray)(include));
8389
8412
  const legacy = [];
8390
8413
  const correlated = [];
8391
8414
  const correlatedReferenceFields = [];
@@ -8421,23 +8444,23 @@ var Base = class {
8421
8444
  else this.assertIncludeOutputPaths([...legacy, ...correlated]);
8422
8445
  let includeLocalFields = [];
8423
8446
  let includePaths = [];
8424
- (0, import_utils23.forEach)(legacy, (inc) => {
8447
+ (0, import_utils24.forEach)(legacy, (inc) => {
8425
8448
  includeLocalFields.push(inc.localField);
8426
8449
  includePaths.push(inc.path);
8427
8450
  });
8428
- includeLocalFields = (0, import_utils23.uniq)((0, import_utils23.compact)(includeLocalFields));
8429
- includePaths = (0, import_utils23.uniq)((0, import_utils23.compact)(includePaths));
8451
+ includeLocalFields = (0, import_utils24.uniq)((0, import_utils24.compact)(includeLocalFields));
8452
+ includePaths = (0, import_utils24.uniq)((0, import_utils24.compact)(includePaths));
8430
8453
  return {
8431
8454
  includes: legacy,
8432
8455
  correlatedIncludes: correlated,
8433
8456
  includeLocalFields,
8434
8457
  includePaths,
8435
- correlatedReferenceFields: (0, import_utils23.uniq)((0, import_utils23.compact)(correlatedReferenceFields))
8458
+ correlatedReferenceFields: (0, import_utils24.uniq)((0, import_utils24.compact)(correlatedReferenceFields))
8436
8459
  };
8437
8460
  }
8438
8461
  validateIncludeOutputPath(path, modelName, configuration) {
8439
8462
  const permissionField = configuration ? configuration.documentPermissionField ?? "_permissions" : getModelOption(modelName, "documentPermissionField");
8440
- if ((0, import_utils23.get)((0, import_utils23.set)({}, path, true), permissionField) !== void 0 || (0, import_utils23.get)((0, import_utils23.set)({}, permissionField, true), path) !== void 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) {
8441
8464
  this.throwClientRequestError(
8442
8465
  "bad_request" /* BadRequest */,
8443
8466
  `Include output path ${path} overlaps document permission field ${permissionField} on model ${modelName}`
@@ -8462,9 +8485,9 @@ var Base = class {
8462
8485
  const walk = (node, prefix) => {
8463
8486
  for (const [key, value] of Object.entries(node)) {
8464
8487
  if (value === void 0) continue;
8465
- if ((0, import_utils23.isPlainObject)(value) && "sub" in value) {
8488
+ if ((0, import_utils24.isPlainObject)(value) && "sub" in value) {
8466
8489
  const sub = value.sub;
8467
- if ((0, import_utils23.isPlainObject)(sub)) walk(sub, prefix ? `${prefix}.${key}` : key);
8490
+ if ((0, import_utils24.isPlainObject)(sub)) walk(sub, prefix ? `${prefix}.${key}` : key);
8468
8491
  continue;
8469
8492
  }
8470
8493
  out.push(prefix ? `${prefix}.${key}` : key);
@@ -8517,7 +8540,7 @@ var Base = class {
8517
8540
  this.throwClientRequestError("bad_request" /* BadRequest */, `Model ${modelName} not found`);
8518
8541
  }
8519
8542
  for (const entry of entries) {
8520
- if (!(0, import_utils23.isPlainObject)(entry)) continue;
8543
+ if (!(0, import_utils24.isPlainObject)(entry)) continue;
8521
8544
  const models = visited.get(entry) ?? /* @__PURE__ */ new Set();
8522
8545
  if (models.has(modelName)) continue;
8523
8546
  models.add(modelName);
@@ -8530,7 +8553,7 @@ var Base = class {
8530
8553
  const target = targets?.find((target2) => target2.path === entry.path);
8531
8554
  if (nested)
8532
8555
  pending.push({
8533
- entries: (0, import_utils23.compact)((0, import_utils23.castArray)(nested)),
8556
+ entries: (0, import_utils24.compact)((0, import_utils24.castArray)(nested)),
8534
8557
  modelName: entry.model,
8535
8558
  configuration: target?.configuration,
8536
8559
  targets: target?.relatedTargets
@@ -8540,7 +8563,7 @@ var Base = class {
8540
8563
  }
8541
8564
  }
8542
8565
  getForeignKeyValues(value) {
8543
- return (0, import_utils23.flatten)((0, import_utils23.castArray)(value));
8566
+ return (0, import_utils24.flatten)((0, import_utils24.castArray)(value));
8544
8567
  }
8545
8568
  getForeignKey(value) {
8546
8569
  return String(value);
@@ -8548,7 +8571,7 @@ var Base = class {
8548
8571
  buildForeignKeyIndex(rows2, foreignField) {
8549
8572
  const index = /* @__PURE__ */ new Map();
8550
8573
  for (const row of rows2) {
8551
- for (const value of this.getForeignKeyValues((0, import_utils23.get)(row, foreignField))) {
8574
+ for (const value of this.getForeignKeyValues((0, import_utils24.get)(row, foreignField))) {
8552
8575
  const key = this.getForeignKey(value);
8553
8576
  const values = index.get(key);
8554
8577
  if (values) values.push(row);
@@ -8584,9 +8607,9 @@ var Base = class {
8584
8607
  async includeDocs(docs, include, parentAuthorization) {
8585
8608
  assertPublicAdmission(include, "include");
8586
8609
  if (!include) return docs;
8587
- const includes = (0, import_utils23.compact)((0, import_utils23.castArray)(include));
8610
+ const includes = (0, import_utils24.compact)((0, import_utils24.castArray)(include));
8588
8611
  if (includes.length === 0) return docs;
8589
- const isSingle = !(0, import_utils23.isArray)(docs);
8612
+ const isSingle = !(0, import_utils24.isArray)(docs);
8590
8613
  let docList = (isSingle ? [docs] : docs).map(prepareIncludeOutput);
8591
8614
  for (let x = 0; x < includes.length; x++) {
8592
8615
  const include2 = includes[x];
@@ -8616,7 +8639,7 @@ var Base = class {
8616
8639
  const svc = await this.getAuthorizedTargetService(model, "read", path, parentAuthorization);
8617
8640
  for (let y = 0; y < docs.length; y++) {
8618
8641
  const doc = docs[y];
8619
- const localValue = (0, import_utils23.get)(doc, localField);
8642
+ const localValue = (0, import_utils24.get)(doc, localField);
8620
8643
  const execution = this.relatedExecution(svc, include, parentAuthorization);
8621
8644
  const prepared = await prepareModelQuery(
8622
8645
  svc,
@@ -8651,15 +8674,15 @@ var Base = class {
8651
8674
  const { model, op, path, localField, foreignField, filter: _filters, args = {}, options = {} } = include;
8652
8675
  const svc = await this.getAuthorizedTargetService(model, op, path, parentAuthorization);
8653
8676
  const includeLocalValues = [];
8654
- (0, import_utils23.forEach)(docs, (doc) => {
8655
- includeLocalValues.push(...this.getForeignKeyValues((0, import_utils23.get)(doc, localField)));
8677
+ (0, import_utils24.forEach)(docs, (doc) => {
8678
+ includeLocalValues.push(...this.getForeignKeyValues((0, import_utils24.get)(doc, localField)));
8656
8679
  });
8657
8680
  const execution = this.relatedExecution(svc, include, parentAuthorization);
8658
8681
  const prepared = await prepareModelQuery(
8659
8682
  svc,
8660
8683
  execution,
8661
8684
  { kind: "client-read", filter: _filters ?? {} },
8662
- { [foreignField]: { $in: (0, import_utils23.flatten)(includeLocalValues) } },
8685
+ { [foreignField]: { $in: (0, import_utils24.flatten)(includeLocalValues) } },
8663
8686
  true
8664
8687
  );
8665
8688
  const trustedArgs = this.sanitizeIncludeArgs(args, "list");
@@ -8702,7 +8725,7 @@ var Base = class {
8702
8725
  }
8703
8726
  for (let y = 0; y < docs.length; y++) {
8704
8727
  const doc = docs[y];
8705
- const matches = this.getIndexedMatches(index, (0, import_utils23.get)(doc, localField));
8728
+ const matches = this.getIndexedMatches(index, (0, import_utils24.get)(doc, localField));
8706
8729
  const isolated = matches.map((m) => copyAuthorizedOutput(m));
8707
8730
  attachIncludeOutput(doc, path, op === "list" ? isolated : isolated[0]);
8708
8731
  }
@@ -8711,7 +8734,7 @@ var Base = class {
8711
8734
  async includeDocsCount(docs, include, parentAuthorization) {
8712
8735
  const { model, path, localField, foreignField, filter: _filters } = include;
8713
8736
  const svc = await this.getAuthorizedTargetService(model, "count", path, parentAuthorization);
8714
- const groups = prepareCountGroups(docs, (doc) => (0, import_utils23.get)(doc, localField));
8737
+ const groups = prepareCountGroups(docs, (doc) => (0, import_utils24.get)(doc, localField));
8715
8738
  const execution = this.relatedExecution(svc, include, parentAuthorization);
8716
8739
  const prepared = await prepareModelQuery(
8717
8740
  svc,
@@ -8765,7 +8788,7 @@ var Base = class {
8765
8788
  }
8766
8789
  const state = this.getCorrelatedExecState();
8767
8790
  docs = docs.map(prepareIncludeOutput);
8768
- const resolvedSnapshots = snapshots2 ?? docs.map((doc) => (0, import_utils23.cloneDeep)(toObject(getIncludeSource(doc))));
8791
+ const resolvedSnapshots = snapshots2 ?? docs.map((doc) => (0, import_utils24.cloneDeep)(toObject(getIncludeSource(doc))));
8769
8792
  for (const include of correlatedIncludes) {
8770
8793
  switch (include.op) {
8771
8794
  case "read":
@@ -9114,10 +9137,10 @@ var Base = class {
9114
9137
  }
9115
9138
  let ret = result2.data;
9116
9139
  if (sqOptions.path) {
9117
- ret = (0, import_utils23.isArray)(ret) ? (0, import_utils23.flatten)(ret.map((v) => (0, import_utils23.get)(v, sqOptions.path))) : (0, import_utils23.get)(ret, sqOptions.path);
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);
9118
9141
  }
9119
9142
  if (sqOptions.compact) {
9120
- ret = (0, import_utils23.compact)((0, import_utils23.castArray)(ret));
9143
+ ret = (0, import_utils24.compact)((0, import_utils24.castArray)(ret));
9121
9144
  }
9122
9145
  return ret;
9123
9146
  }
@@ -9129,11 +9152,11 @@ var Base = class {
9129
9152
  };
9130
9153
 
9131
9154
  // src/services/service.ts
9132
- var import_utils34 = require("@web-ts-toolkit/utils");
9155
+ var import_utils35 = require("@web-ts-toolkit/utils");
9133
9156
  var import_just_diff = require("just-diff");
9134
9157
 
9135
9158
  // src/model.ts
9136
- var import_utils24 = require("@web-ts-toolkit/utils");
9159
+ var import_utils25 = require("@web-ts-toolkit/utils");
9137
9160
  init_runtime_context();
9138
9161
  init_runtime();
9139
9162
  function admitModelPersistence(adapter, scheduler) {
@@ -9209,7 +9232,7 @@ var Model = class {
9209
9232
  }
9210
9233
  /** Cast a copy using this model's query schema/setters, without executing query middleware or persistence. */
9211
9234
  castFilter(filter2) {
9212
- const query = this.mongooseModel.countDocuments((0, import_utils24.cloneDeep)(filter2));
9235
+ const query = this.mongooseModel.countDocuments((0, import_utils25.cloneDeep)(filter2));
9213
9236
  return query.cast(this.mongooseModel);
9214
9237
  }
9215
9238
  // see https://mongoosejs.com/docs/api.html#model_Model.distinct
@@ -9223,7 +9246,7 @@ var Model = class {
9223
9246
  var model_default = Model;
9224
9247
 
9225
9248
  // src/acl/distinct-field-authorization.ts
9226
- var import_utils25 = require("@web-ts-toolkit/utils");
9249
+ var import_utils26 = require("@web-ts-toolkit/utils");
9227
9250
  init_field_authorization();
9228
9251
  init_field_catalog();
9229
9252
  var schemaVariants = (schema) => Object.values(schema.discriminators ?? {});
@@ -9305,8 +9328,8 @@ function isDistinctFieldAuthorized(args) {
9305
9328
  if (path !== field && !path.startsWith(`${field}.`) && !field.startsWith(`${path}.`)) continue;
9306
9329
  if (path.startsWith(`${field}.`) && (!eligible(path) || !schemaShape(schema, path) || !granted(path)))
9307
9330
  return false;
9308
- if ((0, import_utils25.isPlainObject)(raw) && raw.sub !== void 0) {
9309
- if (!(0, import_utils25.isPlainObject)(raw.sub) || !declaredRulesSafe(raw.sub, path, next)) return false;
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;
9310
9333
  }
9311
9334
  }
9312
9335
  return true;
@@ -9483,7 +9506,7 @@ init_document();
9483
9506
  init_populate_target();
9484
9507
 
9485
9508
  // src/helpers/apply-update.ts
9486
- var import_utils29 = require("@web-ts-toolkit/utils");
9509
+ var import_utils30 = require("@web-ts-toolkit/utils");
9487
9510
  init_lib();
9488
9511
  function applyUpdate(target, data, allowedFields) {
9489
9512
  const wholeFields = /* @__PURE__ */ new Set();
@@ -9499,17 +9522,17 @@ function applyUpdate(target, data, allowedFields) {
9499
9522
  }
9500
9523
  };
9501
9524
  for (const field of allowedFields) {
9502
- collectBoundary((0, import_utils29.set)({}, field, true));
9525
+ collectBoundary((0, import_utils30.set)({}, field, true));
9503
9526
  }
9504
9527
  const apply = (values, prefix = "") => {
9505
9528
  for (const [key, value] of Object.entries(values)) {
9506
9529
  const path = prefix ? `${prefix}.${key}` : key;
9507
- if (partialContainers.has(path) && !wholeFields.has(path) && ((0, import_utils29.isPlainObject)(value) || Array.isArray(value))) {
9530
+ if (partialContainers.has(path) && !wholeFields.has(path) && ((0, import_utils30.isPlainObject)(value) || Array.isArray(value))) {
9508
9531
  apply(value, path);
9509
9532
  } else if (isDocument2(target)) {
9510
9533
  target.set(path, value);
9511
9534
  } else {
9512
- (0, import_utils29.set)(target, path, value);
9535
+ (0, import_utils30.set)(target, path, value);
9513
9536
  }
9514
9537
  }
9515
9538
  };
@@ -9517,7 +9540,7 @@ function applyUpdate(target, data, allowedFields) {
9517
9540
  }
9518
9541
 
9519
9542
  // src/acl/model-input-admission.ts
9520
- var import_utils31 = require("@web-ts-toolkit/utils");
9543
+ var import_utils32 = require("@web-ts-toolkit/utils");
9521
9544
  var import_mongoose8 = require("mongoose");
9522
9545
  init_document();
9523
9546
  init_request_work();
@@ -9525,7 +9548,7 @@ init_logger_helpers();
9525
9548
  init_request_complexity();
9526
9549
 
9527
9550
  // src/acl/select-resolution.ts
9528
- var import_utils30 = require("@web-ts-toolkit/utils");
9551
+ var import_utils31 = require("@web-ts-toolkit/utils");
9529
9552
  init_core_shared();
9530
9553
  init_helpers();
9531
9554
  async function collectAllowedFieldsForRequest({
@@ -9599,15 +9622,15 @@ async function resolveSelectForRequest({
9599
9622
  const excludeall = normalizedSelect.every((v) => v.startsWith("-"));
9600
9623
  if (excludeall) {
9601
9624
  normalizedSelect = normalizedSelect.map((v) => v.substring(1));
9602
- fields = (0, import_utils30.difference)(fields, normalizedSelect);
9625
+ fields = (0, import_utils31.difference)(fields, normalizedSelect);
9603
9626
  if (excludeid) fields.push("-_id");
9604
9627
  } else {
9605
- fields = (0, import_utils30.intersection)(normalizedSelect, fields.concat(excludeid ? "-_id" : "_id"));
9628
+ fields = (0, import_utils31.intersection)(normalizedSelect, fields.concat(excludeid ? "-_id" : "_id"));
9606
9629
  }
9607
9630
  }
9608
9631
  return fields.concat(strippedAlways);
9609
9632
  }
9610
- return (0, import_utils30.intersection)(normalizedSelect, fields);
9633
+ return (0, import_utils31.intersection)(normalizedSelect, fields);
9611
9634
  }
9612
9635
  function stripVirtuals(fields, virtualNames) {
9613
9636
  const set13 = virtualNames instanceof Set ? virtualNames : new Set(virtualNames ?? []);
@@ -9638,7 +9661,7 @@ init_field_catalog();
9638
9661
  init_service_authorization();
9639
9662
  var own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
9640
9663
  var inside = (path, root) => path === root || path.startsWith(`${root}.`);
9641
- var record2 = (value) => (0, import_utils31.isPlainObject)(value);
9664
+ var record2 = (value) => (0, import_utils32.isPlainObject)(value);
9642
9665
  function inputValue(value) {
9643
9666
  if (typeof value === "function" || typeof value === "symbol") {
9644
9667
  authorizationError("input values must be persisted data, not functions or symbols");
@@ -9707,7 +9730,7 @@ function requestBoundaries(fields) {
9707
9730
  else visit(value, path);
9708
9731
  }
9709
9732
  };
9710
- for (const field of fields) visit((0, import_utils31.set)({}, field, true));
9733
+ for (const field of fields) visit((0, import_utils32.set)({}, field, true));
9711
9734
  return [...new Set(result2)];
9712
9735
  }
9713
9736
  function ownValue(data, parts) {
@@ -9837,7 +9860,7 @@ function admitModelInput(args) {
9837
9860
  if (forbidden(catalog, path, requested)) continue;
9838
9861
  const supplied = ownValue(data, parts);
9839
9862
  if (!supplied) continue;
9840
- (0, import_utils31.set)(allowedData, field, copyInputValue(supplied.value, path, catalog, scopedRequests, logicalPath(field)));
9863
+ (0, import_utils32.set)(allowedData, field, copyInputValue(supplied.value, path, catalog, scopedRequests, logicalPath(field)));
9841
9864
  selected.push(field);
9842
9865
  }
9843
9866
  return { allowedData, allowedFields };
@@ -9849,7 +9872,7 @@ async function requestInputFields(args) {
9849
9872
  const prefix = configuration.modelPermissionPrefix ?? "";
9850
9873
  return collectModelRequestFields({
9851
9874
  req: args.binding.request,
9852
- permissionSchema: args.scopePath ? (0, import_utils31.get)(configuration.permissionSchema, [args.scopePath, "sub"]) : configuration.permissionSchema,
9875
+ permissionSchema: args.scopePath ? (0, import_utils32.get)(configuration.permissionSchema, [args.scopePath, "sub"]) : configuration.permissionSchema,
9853
9876
  access: args.access,
9854
9877
  permissions,
9855
9878
  grants,
@@ -9893,13 +9916,13 @@ init_logger_helpers();
9893
9916
  init_lib();
9894
9917
 
9895
9918
  // src/services/model-subdocument-service.ts
9896
- var import_utils33 = require("@web-ts-toolkit/utils");
9919
+ var import_utils34 = require("@web-ts-toolkit/utils");
9897
9920
  init_helpers();
9898
9921
  init_document();
9899
9922
  init_public_admission();
9900
9923
 
9901
9924
  // src/acl/subdocument-authorization.ts
9902
- var import_utils32 = require("@web-ts-toolkit/utils");
9925
+ var import_utils33 = require("@web-ts-toolkit/utils");
9903
9926
  init_helpers();
9904
9927
  init_document();
9905
9928
  init_core_shared();
@@ -10088,8 +10111,8 @@ async function subdocumentGateAllowed(service, gate) {
10088
10111
  let guard2;
10089
10112
  if (access.startsWith("subs.")) {
10090
10113
  const [, sub, op] = access.split(".");
10091
- guard2 = (0, import_utils32.get)(configuration, `operationAccess.${access}`);
10092
- if (guard2 === void 0) guard2 = (0, import_utils32.get)(configuration, `operationAccess.subs.${sub}`);
10114
+ guard2 = (0, import_utils33.get)(configuration, `operationAccess.${access}`);
10115
+ if (guard2 === void 0) guard2 = (0, import_utils33.get)(configuration, `operationAccess.subs.${sub}`);
10093
10116
  if (guard2 === void 0) guard2 = getCapturedAuthorizationOption(configuration, `operationAccess.${op}`);
10094
10117
  } else guard2 = getCapturedAuthorizationOption(configuration, `operationAccess.${access}`);
10095
10118
  return evaluateRouteGuard(
@@ -10220,7 +10243,7 @@ async function visibleMutationRows(service, call, parentId, rows2) {
10220
10243
  const read = await subdocumentRows(service, visibility.child, selected, selected, call.sub);
10221
10244
  const list = visibility.list ? await subdocumentRows(service, visibility.list, {}, {}, call.sub) : {};
10222
10245
  if (read === false || list === false) return [];
10223
- const visible = filterCollection((0, import_utils33.get)(parent, call.sub), intersectFilters(read, list));
10246
+ const visible = filterCollection((0, import_utils34.get)(parent, call.sub), intersectFilters(read, list));
10224
10247
  return await finalizeSubdocumentRows(service, call.output, parent, visible);
10225
10248
  } catch {
10226
10249
  return [];
@@ -10245,7 +10268,7 @@ async function listSub(service, id, sub, options) {
10245
10268
  populate: []
10246
10269
  });
10247
10270
  if (!parent) return denied2("not_found" /* NotFound */);
10248
- const rows2 = filterCollection((0, import_utils33.get)(parent, sub), childFilter);
10271
+ const rows2 = filterCollection((0, import_utils34.get)(parent, sub), childFilter);
10249
10272
  const data = await finalizeSubdocumentRows(service, call.output, parent, rows2);
10250
10273
  return { success: true, kind: "list", code: "success" /* Success */, data, count: data.length };
10251
10274
  });
@@ -10269,7 +10292,7 @@ async function readSub(service, id, sub, subId, options) {
10269
10292
  });
10270
10293
  if (!parent) return denied2("not_found" /* NotFound */);
10271
10294
  const row = findElement(
10272
- (0, import_utils33.get)(capture ? parent : copySubdocumentParent(parent), sub),
10295
+ (0, import_utils34.get)(capture ? parent : copySubdocumentParent(parent), sub),
10273
10296
  childFilter
10274
10297
  );
10275
10298
  if (!row) return denied2("not_found" /* NotFound */);
@@ -10290,7 +10313,7 @@ async function updateSub(service, persist, id, sub, subId, data, options) {
10290
10313
  const identity = { _id: subId };
10291
10314
  const filter2 = await subdocumentRows(service, call.child, identity, identity, sub);
10292
10315
  if (filter2 === false) return denied2();
10293
- const row = findElement((0, import_utils33.get)(parent, sub), filter2);
10316
+ const row = findElement((0, import_utils34.get)(parent, sub), filter2);
10294
10317
  if (!row) return denied2("not_found" /* NotFound */);
10295
10318
  const original = isolateDocForOutput(row);
10296
10319
  const admit = await inputAdmission(service, call, parent);
@@ -10317,7 +10340,7 @@ async function bulkUpdateSub(service, persist, id, sub, data, options) {
10317
10340
  const selected = { _id: { $in: data.map((row) => row._id) } };
10318
10341
  const filter2 = await subdocumentRows(service, call.child, selected, selected, sub);
10319
10342
  if (filter2 === false) return denied2();
10320
- const rows2 = filterCollection((0, import_utils33.get)(parent, sub), filter2);
10343
+ const rows2 = filterCollection((0, import_utils34.get)(parent, sub), filter2);
10321
10344
  const originals = rows2.map((row) => isolateDocForOutput(row));
10322
10345
  const admit = await inputAdmission(service, call, parent);
10323
10346
  for (const [index, row] of rows2.entries()) {
@@ -10346,7 +10369,7 @@ async function createSub(service, persist, id, sub, data, options) {
10346
10369
  const lookup = await mutationParent(service, id, call);
10347
10370
  if ("error" in lookup) return lookup.error;
10348
10371
  const { parent } = lookup;
10349
- const rows2 = (0, import_utils33.get)(parent, sub);
10372
+ const rows2 = (0, import_utils34.get)(parent, sub);
10350
10373
  const admit = await inputAdmission(service, call, parent);
10351
10374
  const allowed = (Array.isArray(data) ? data : [data]).map((row) => admit(row).allowedData);
10352
10375
  if (addFirst) rows2.unshift(...allowed);
@@ -10367,7 +10390,7 @@ async function deleteSub(service, persist, id, sub, subId, options) {
10367
10390
  const identity = { _id: subId };
10368
10391
  const filter2 = await subdocumentRows(service, call.child, identity, identity, sub);
10369
10392
  if (filter2 === false) return denied2();
10370
- const row = findElement((0, import_utils33.get)(parent, sub), filter2);
10393
+ const row = findElement((0, import_utils34.get)(parent, sub), filter2);
10371
10394
  if (!row) return denied2("not_found" /* NotFound */);
10372
10395
  await ("deleteOne" in row ? row.deleteOne?.() : row.remove?.());
10373
10396
  await persist(() => parent.save());
@@ -10681,20 +10704,20 @@ var Service = class extends Base {
10681
10704
  const field = configuration.documentPermissionField ?? "_permissions";
10682
10705
  unsetDocPath(output, field);
10683
10706
  if (!configuration.stripPermissionsField) {
10684
- (0, import_utils34.set)(output, field, args.includePermissions || args.includeFieldPermissions ? deepIsolateValue(grants) : {});
10707
+ (0, import_utils35.set)(output, field, args.includePermissions || args.includeFieldPermissions ? deepIsolateValue(grants) : {});
10685
10708
  if (args.includeFieldPermissions && !configuration.disableFieldPermissions) {
10686
10709
  const rowAccess = this.asServiceHookContext(context).fieldPermissionAccess ?? await this.getFieldPermissionAccess([snapshot._id]);
10687
10710
  const id = String(snapshot._id);
10688
10711
  const views = rowAccess.readIds?.has(id) ? await requestOutputFieldPaths(handle, binding, "read") : [];
10689
10712
  const edits = rowAccess.updateIds?.has(id) ? await requestOutputFieldPaths(handle, binding, "update") : [];
10690
10713
  const map2 = (paths) => paths.length ? Object.fromEntries(paths.map((path) => [path, true])) : { $: "_" };
10691
- (0, import_utils34.set)(output, `${field}._view`, map2(views));
10692
- (0, import_utils34.set)(output, `${field}._edit`, map2(edits));
10693
- } else if (!args.includePermissions) (0, import_utils34.set)(output, field, { _view: { $: "_" }, _edit: { $: "_" } });
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: { $: "_" } });
10694
10717
  const exposed = configuration.exposedDocPermissionKeys;
10695
10718
  if (exposed) {
10696
- const metadata = (0, import_utils34.get)(output, field);
10697
- (0, import_utils34.set)(
10719
+ const metadata = (0, import_utils35.get)(output, field);
10720
+ (0, import_utils35.set)(
10698
10721
  output,
10699
10722
  field,
10700
10723
  Object.fromEntries(
@@ -10955,7 +10978,7 @@ var Service = class extends Base {
10955
10978
  return docs.map((doc) => {
10956
10979
  try {
10957
10980
  const plain = toObject(doc);
10958
- const val = (0, import_utils34.get)(plain, associationField);
10981
+ const val = (0, import_utils35.get)(plain, associationField);
10959
10982
  return deepIsolateValue(val);
10960
10983
  } catch {
10961
10984
  return void 0;
@@ -10994,10 +11017,6 @@ var Service = class extends Base {
10994
11017
  const target = captured.relatedTargets.find((target2) => target2.path === descriptor.path);
10995
11018
  const modelName = target?.modelName;
10996
11019
  if (!modelName) continue;
10997
- if (target.kind === "passthrough") {
10998
- result2.push({ path: descriptor.path, select: descriptor.select });
10999
- continue;
11000
- }
11001
11020
  const policy = relatedPolicy(state.authorization, state.binding, descriptor.path);
11002
11021
  const svc = this.requestCore.getPublicService(modelName);
11003
11022
  const child = createRelatedExecution(
@@ -11016,7 +11035,7 @@ var Service = class extends Base {
11016
11035
  if (isExecutionRowDenied(svc, child)) continue;
11017
11036
  const childState = readServiceExecution(svc, child);
11018
11037
  const targetConfiguration = readServiceAuthorization(childState.authorization, childState.binding).configuration;
11019
- if (policy?.operation.mode !== "grant" && !await this.hookGate.run(
11038
+ if (targetConfiguration.requireOperationAccessForPopulateQueries !== false && policy?.operation.mode !== "grant" && !await this.hookGate.run(
11020
11039
  () => evaluateRouteGuard(
11021
11040
  this.req,
11022
11041
  getAuthorizationPermissions(childState.authorization, childState.binding),
@@ -11068,7 +11087,7 @@ var Service = class extends Base {
11068
11087
  if (this.isScalarPopulateValue(rawTarget)) return rawTarget;
11069
11088
  const isDoc = (() => {
11070
11089
  try {
11071
- if ((0, import_utils34.isPlainObject)(rawTarget)) return true;
11090
+ if ((0, import_utils35.isPlainObject)(rawTarget)) return true;
11072
11091
  const maybe = rawTarget;
11073
11092
  if (maybe && typeof maybe === "object" && "_doc" in maybe) return true;
11074
11093
  if (maybe && typeof maybe.toObject === "function") return true;
@@ -11156,7 +11175,7 @@ var Service = class extends Base {
11156
11175
  child = getDocValue(current, key);
11157
11176
  if (child === void 0) {
11158
11177
  try {
11159
- child = (0, import_utils34.get)(current, key);
11178
+ child = (0, import_utils35.get)(current, key);
11160
11179
  } catch {
11161
11180
  return;
11162
11181
  }
@@ -11391,7 +11410,7 @@ var Service = class extends Base {
11391
11410
  originalDocumentSnapshot: toObject(doc),
11392
11411
  resolvedQuery: query
11393
11412
  };
11394
- const correlatedSnapshots = [(0, import_utils34.cloneDeep)(toObject(doc))];
11413
+ const correlatedSnapshots = [(0, import_utils35.cloneDeep)(toObject(doc))];
11395
11414
  try {
11396
11415
  doc = await this.includeDocs(doc, includes, state.authorization);
11397
11416
  if (correlatedIncludes.length > 0) {
@@ -11573,7 +11592,7 @@ var Service = class extends Base {
11573
11592
  const findAssociationField = this.getAssociationFieldFromOptions(options);
11574
11593
  const withAssocSelect = findAssociationField && !finalSelect.includes(findAssociationField) ? [...finalSelect, findAssociationField] : finalSelect;
11575
11594
  const dbSelect = this.buildDbSelectForAssociation(withAssocSelect, findAssociationField);
11576
- const filteredPopulate = (0, import_utils34.isArray)(withAssocSelect) && (0, import_utils34.isArray)(_populate) ? _populate.filter(
11595
+ const filteredPopulate = (0, import_utils35.isArray)(withAssocSelect) && (0, import_utils35.isArray)(_populate) ? _populate.filter(
11577
11596
  (p) => [
11578
11597
  ...virtualPlan.publicPersistedFetchSelection,
11579
11598
  ...findAssociationField ? [findAssociationField] : []
@@ -11633,7 +11652,7 @@ var Service = class extends Base {
11633
11652
  findAssociationField ? [findAssociationField] : []
11634
11653
  );
11635
11654
  const capturedAssociation = findAssociationField ? this.captureAssociationValues(docs, findAssociationField) : void 0;
11636
- const correlatedSnapshots = docs.map((doc) => (0, import_utils34.cloneDeep)(toObject(doc)));
11655
+ const correlatedSnapshots = docs.map((doc) => (0, import_utils35.cloneDeep)(toObject(doc)));
11637
11656
  try {
11638
11657
  docs = await this.includeDocs(docs, includes, state.authorization);
11639
11658
  if (correlatedIncludes.length > 0) {
@@ -11832,12 +11851,12 @@ var Service = class extends Base {
11832
11851
  context.allowedFields = allowedFields;
11833
11852
  context.allowedData = allowedData;
11834
11853
  const validated = await this.validate(allowedData, "create", context);
11835
- if ((0, import_utils34.isBoolean)(validated)) {
11854
+ if ((0, import_utils35.isBoolean)(validated)) {
11836
11855
  if (!validated) {
11837
11856
  validationErrors.push({ index, errors: [] });
11838
11857
  return void 0;
11839
11858
  }
11840
- } else if ((0, import_utils34.isArray)(validated)) {
11859
+ } else if ((0, import_utils35.isArray)(validated)) {
11841
11860
  if (validated.length > 0) {
11842
11861
  validationErrors.push({
11843
11862
  index,
@@ -12048,7 +12067,7 @@ var Service = class extends Base {
12048
12067
  }
12049
12068
  let doc = await this.model.findOne({
12050
12069
  filter: _filter,
12051
- select: (0, import_utils34.uniq)([...updatePlan.persistedFetchSelection, ...inputFetchPaths(captured.configuration.catalog)]).map(
12070
+ select: (0, import_utils35.uniq)([...updatePlan.persistedFetchSelection, ...inputFetchPaths(captured.configuration.catalog)]).map(
12052
12071
  (path) => `+${path}`
12053
12072
  )
12054
12073
  });
@@ -12087,12 +12106,12 @@ var Service = class extends Base {
12087
12106
  context.allowedFields = allowedFields;
12088
12107
  context.allowedData = allowedData;
12089
12108
  const validated = await this.validate(allowedData, "update", context);
12090
- if ((0, import_utils34.isBoolean)(validated)) {
12109
+ if ((0, import_utils35.isBoolean)(validated)) {
12091
12110
  if (!validated) {
12092
12111
  this.completeOp("updateOne", startedAt, "bad_request" /* BadRequest */, _filter);
12093
12112
  return { success: false, kind: "error", code: "bad_request" /* BadRequest */ };
12094
12113
  }
12095
- } else if ((0, import_utils34.isArray)(validated)) {
12114
+ } else if ((0, import_utils35.isArray)(validated)) {
12096
12115
  if (validated.length > 0) {
12097
12116
  this.completeOp("updateOne", startedAt, "bad_request" /* BadRequest */, _filter);
12098
12117
  return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: validated };
@@ -12112,10 +12131,10 @@ var Service = class extends Base {
12112
12131
  const diffExcludeFields = [this.options.documentPermissionField, "__v"];
12113
12132
  this.asServiceHookContext(context).diff = (d) => {
12114
12133
  context.changes = (0, import_just_diff.diff)(
12115
- (0, import_utils34.omit)(context.originalDocumentSnapshot, diffExcludeFields),
12116
- (0, import_utils34.omit)(d.toObject({ virtuals: false }), diffExcludeFields)
12134
+ (0, import_utils35.omit)(context.originalDocumentSnapshot, diffExcludeFields),
12135
+ (0, import_utils35.omit)(d.toObject({ virtuals: false }), diffExcludeFields)
12117
12136
  ) || [];
12118
- context.modifiedPaths = (0, import_utils34.uniq)(context.changes.map((di) => di.path.length > 0 ? String(di.path[0]) : ""));
12137
+ context.modifiedPaths = (0, import_utils35.uniq)(context.changes.map((di) => di.path.length > 0 ? String(di.path[0]) : ""));
12119
12138
  };
12120
12139
  doc = assertModelDocument(await this.afterPersist(doc, "update", context), this.modelName, "afterPersist");
12121
12140
  context.currentDocument = doc;
@@ -12203,7 +12222,7 @@ var Service = class extends Base {
12203
12222
  const upsertOptions = this.resolveUpsertOptions(options);
12204
12223
  const updateIntent = captureModelServiceIntent(this, "updateOne", upsertArgs, upsertOptions);
12205
12224
  const createIntent = captureModelServiceIntent(this, "create", upsertArgs, upsertOptions);
12206
- const related = (0, import_utils34.uniqBy)(
12225
+ const related = (0, import_utils35.uniqBy)(
12207
12226
  [...this.captureRelated(updateIntent.args), ...this.captureRelated(createIntent.args)],
12208
12227
  (target) => target.path
12209
12228
  );
@@ -12644,7 +12663,7 @@ var Service = class extends Base {
12644
12663
  return resolveExistsOptions(this, options);
12645
12664
  }
12646
12665
  async getFieldPermissionAccess(ids) {
12647
- const uniqueIds = (0, import_utils34.compact)((0, import_utils34.uniqBy)(ids, (id) => String(id)).map((id) => String(id)));
12666
+ const uniqueIds = (0, import_utils35.compact)((0, import_utils35.uniqBy)(ids, (id) => String(id)).map((id) => String(id)));
12648
12667
  if (uniqueIds.length === 0) {
12649
12668
  return {
12650
12669
  readIds: /* @__PURE__ */ new Set(),
@@ -12690,7 +12709,7 @@ var Service = class extends Base {
12690
12709
  * (direct/root-entry 200); count measures visible rows, not all updated rows.
12691
12710
  */
12692
12711
  async bulkUpdateSub(id, sub, data, options) {
12693
- return bulkUpdateSub(this, this.persist, id, sub, (0, import_utils34.castArray)(data), options);
12712
+ return bulkUpdateSub(this, this.persist, id, sub, (0, import_utils35.castArray)(data), options);
12694
12713
  }
12695
12714
  /**
12696
12715
  * Append/prepend admitted rows, then return the visible full array (including when
@@ -12714,7 +12733,7 @@ var Service = class extends Base {
12714
12733
  };
12715
12734
 
12716
12735
  // src/services/public-service.ts
12717
- var import_utils35 = require("@web-ts-toolkit/utils");
12736
+ var import_utils36 = require("@web-ts-toolkit/utils");
12718
12737
  init_helpers();
12719
12738
  init_permissions_alias();
12720
12739
  init_document();
@@ -12840,7 +12859,7 @@ var PublicService = class extends Service {
12840
12859
  let d = toObject(doc);
12841
12860
  d = await this.decorate(d, "create", context);
12842
12861
  d = this.runTasks(d, tasks);
12843
- if (select) d = copyPermissionsAlias(d, (0, import_utils35.pick)(d, [...normalizeSelect(select), ...this.baseFieldsExt]));
12862
+ if (select) d = copyPermissionsAlias(d, (0, import_utils36.pick)(d, [...normalizeSelect(select), ...this.baseFieldsExt]));
12844
12863
  return d;
12845
12864
  }
12846
12865
  );
@@ -13059,8 +13078,8 @@ var PublicService = class extends Service {
13059
13078
  let d = toObject(doc);
13060
13079
  d = await this.decorate(d, "update", context);
13061
13080
  d = this.runTasks(d, tasks);
13062
- if (select) d = copyPermissionsAlias(d, (0, import_utils35.pick)(d, [...normalizeSelect(select), ...this.baseFieldsExt]));
13063
- else if (!returningAll) d = copyPermissionsAlias(d, (0, import_utils35.pick)(d, returningKeys));
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));
13064
13083
  return d;
13065
13084
  }
13066
13085
  );
@@ -13143,8 +13162,8 @@ var PublicService = class extends Service {
13143
13162
  let d = toObject(doc);
13144
13163
  d = await this.decorate(d, "update", context);
13145
13164
  d = this.runTasks(d, tasks2);
13146
- if (select) d = copyPermissionsAlias(d, (0, import_utils35.pick)(d, [...normalizeSelect(select), ...this.baseFieldsExt]));
13147
- else if (!returningAll) d = copyPermissionsAlias(d, (0, import_utils35.pick)(d, returningKeys));
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));
13148
13167
  return d;
13149
13168
  }
13150
13169
  );
@@ -13169,7 +13188,7 @@ var PublicService = class extends Service {
13169
13188
  d = await this.decorate(d, "create", context);
13170
13189
  d = this.runTasks(d, tasks);
13171
13190
  if (createSelect)
13172
- d = copyPermissionsAlias(d, (0, import_utils35.pick)(d, [...normalizeSelect(createSelect), ...this.baseFieldsExt]));
13191
+ d = copyPermissionsAlias(d, (0, import_utils36.pick)(d, [...normalizeSelect(createSelect), ...this.baseFieldsExt]));
13173
13192
  return d;
13174
13193
  }
13175
13194
  );
@@ -13314,7 +13333,7 @@ var PublicService = class extends Service {
13314
13333
  init_options();
13315
13334
  init_data_values();
13316
13335
  init_helpers();
13317
- var import_utils36 = require("@web-ts-toolkit/utils");
13336
+ var import_utils37 = require("@web-ts-toolkit/utils");
13318
13337
  init_request_complexity();
13319
13338
  init_runtime_context();
13320
13339
  init_runtime();
@@ -13343,7 +13362,7 @@ var DataService = class {
13343
13362
  let doc = await findElement(this.data, _filter);
13344
13363
  if (!doc) return { success: false, kind: "error", code: "not_found" /* NotFound */, query };
13345
13364
  doc = await this.trimOutputFields(doc, access);
13346
- if (_select.length > 0) doc = (0, import_utils36.pick)(doc, _select);
13365
+ if (_select.length > 0) doc = (0, import_utils37.pick)(doc, _select);
13347
13366
  return {
13348
13367
  success: true,
13349
13368
  kind: "single",
@@ -13389,13 +13408,13 @@ var DataService = class {
13389
13408
  const totalCount = docs.length;
13390
13409
  if (sort) {
13391
13410
  const normalizedSort = normalizeSortForOrderBy(sort);
13392
- docs = (0, import_utils36.orderBy)(docs, normalizedSort.fields, normalizedSort.orders);
13411
+ docs = (0, import_utils37.orderBy)(docs, normalizedSort.fields, normalizedSort.orders);
13393
13412
  }
13394
13413
  const pagedDocs = docs.slice(query.skip, query.limit && query.skip + query.limit);
13395
13414
  const { maxHookConcurrency } = this.getRequestComplexity();
13396
13415
  const trimmed = await mapWithConcurrencyLimit(pagedDocs, maxHookConcurrency, async (doc) => {
13397
13416
  doc = await this.trimOutputFields(doc, "list");
13398
- if (_select.length > 0) doc = (0, import_utils36.pick)(doc, _select);
13417
+ if (_select.length > 0) doc = (0, import_utils37.pick)(doc, _select);
13399
13418
  return copyDataValue(doc);
13400
13419
  });
13401
13420
  if (!hasExplicitLimit && trimmed.length === totalCount) {
@@ -13470,10 +13489,10 @@ var DataService = class {
13470
13489
  init_helpers();
13471
13490
 
13472
13491
  // src/processors.ts
13473
- var import_utils37 = require("@web-ts-toolkit/utils");
13492
+ var import_utils38 = require("@web-ts-toolkit/utils");
13474
13493
  init_permissions_alias();
13475
13494
  function cloneProcessorValue(value) {
13476
- const copy = (0, import_utils37.cloneDeep)(value);
13495
+ const copy = (0, import_utils38.cloneDeep)(value);
13477
13496
  copyPermissionsAliasGraph(value, copy);
13478
13497
  return copy;
13479
13498
  }
@@ -13511,10 +13530,10 @@ function resolveLeafParents(obj, src) {
13511
13530
  for (let ind = 0; ind < segs.length - 1; ind += 1) {
13512
13531
  const seg = segs[ind];
13513
13532
  targets = targets.reduce((ret, target) => {
13514
- if (!(0, import_utils37.isPlainObject)(target)) return ret;
13533
+ if (!(0, import_utils38.isPlainObject)(target)) return ret;
13515
13534
  const targetObject = target;
13516
13535
  const next = targetObject[seg];
13517
- if ((0, import_utils37.isArray)(next)) {
13536
+ if ((0, import_utils38.isArray)(next)) {
13518
13537
  for (const item of next) {
13519
13538
  ret.push(item);
13520
13539
  }
@@ -13524,8 +13543,8 @@ function resolveLeafParents(obj, src) {
13524
13543
  }
13525
13544
  const leaf = segs[segs.length - 1];
13526
13545
  const pairs = [];
13527
- (0, import_utils37.forEach)(targets, (target) => {
13528
- if (!(0, import_utils37.isPlainObject)(target)) return;
13546
+ (0, import_utils38.forEach)(targets, (target) => {
13547
+ if (!(0, import_utils38.isPlainObject)(target)) return;
13529
13548
  pairs.push({ parent: target, leaf });
13530
13549
  });
13531
13550
  return pairs;
@@ -13534,7 +13553,7 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
13534
13553
  const mutable = options.mutable !== false;
13535
13554
  const idField = options.idField ?? "_id";
13536
13555
  const obj = mutable ? docObject : cloneProcessorValue(docObject);
13537
- (0, import_utils37.forEach)(Array.isArray(operations) ? operations : [], (op) => {
13556
+ (0, import_utils38.forEach)(Array.isArray(operations) ? operations : [], (op) => {
13538
13557
  if (!op || typeof op.src !== "string" || typeof op.dest !== "string") return;
13539
13558
  const src = op.src;
13540
13559
  const dest = op.dest;
@@ -13543,19 +13562,19 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
13543
13562
  assertSafePath(dest);
13544
13563
  let targets = [obj];
13545
13564
  const segs = src.split(".");
13546
- (0, import_utils37.forEach)(segs, (seg, ind) => {
13565
+ (0, import_utils38.forEach)(segs, (seg, ind) => {
13547
13566
  if (segs.length === ind + 1) {
13548
- (0, import_utils37.forEach)(targets, (target) => {
13549
- if (!(0, import_utils37.isPlainObject)(target)) return;
13567
+ (0, import_utils38.forEach)(targets, (target) => {
13568
+ if (!(0, import_utils38.isPlainObject)(target)) return;
13550
13569
  const targetObject = target;
13551
13570
  const leaf = targetObject[seg];
13552
13571
  const sourceForDest = leaf;
13553
13572
  let depopulated;
13554
- if ((0, import_utils37.isArray)(leaf)) {
13573
+ if ((0, import_utils38.isArray)(leaf)) {
13555
13574
  if (leaf.length === 0) {
13556
13575
  depopulated = [];
13557
- } else if (leaf.every((item) => (0, import_utils37.isPlainObject)(item))) {
13558
- depopulated = (0, import_utils37.map)(leaf, idField).map((id, i) => {
13576
+ } else if (leaf.every((item) => (0, import_utils38.isPlainObject)(item))) {
13577
+ depopulated = (0, import_utils38.map)(leaf, idField).map((id, i) => {
13559
13578
  if (id === void 0) {
13560
13579
  failMissingId(`${src}[${i}]`);
13561
13580
  }
@@ -13564,8 +13583,8 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
13564
13583
  } else {
13565
13584
  return;
13566
13585
  }
13567
- } else if ((0, import_utils37.isPlainObject)(leaf)) {
13568
- const id = (0, import_utils37.get)(leaf, idField);
13586
+ } else if ((0, import_utils38.isPlainObject)(leaf)) {
13587
+ const id = (0, import_utils38.get)(leaf, idField);
13569
13588
  if (id === void 0) {
13570
13589
  failMissingId(src);
13571
13590
  }
@@ -13573,15 +13592,15 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
13573
13592
  } else {
13574
13593
  return;
13575
13594
  }
13576
- (0, import_utils37.set)(targetObject, dest, sourceForDest);
13577
- (0, import_utils37.set)(targetObject, seg, depopulated);
13595
+ (0, import_utils38.set)(targetObject, dest, sourceForDest);
13596
+ (0, import_utils38.set)(targetObject, seg, depopulated);
13578
13597
  });
13579
13598
  } else {
13580
13599
  targets = targets.reduce((ret, target) => {
13581
- if (!(0, import_utils37.isPlainObject)(target)) return ret;
13600
+ if (!(0, import_utils38.isPlainObject)(target)) return ret;
13582
13601
  const targetObject = target;
13583
13602
  const next = targetObject[seg];
13584
- if ((0, import_utils37.isArray)(next)) {
13603
+ if ((0, import_utils38.isArray)(next)) {
13585
13604
  for (const item of next) {
13586
13605
  ret.push(item);
13587
13606
  }
@@ -13596,7 +13615,7 @@ var copyAndDepopulate = (docObject, operations, options = { mutable: true, idFie
13596
13615
  var copyPaths = (docObject, operations, options = { mutable: true }) => {
13597
13616
  const mutable = options.mutable !== false;
13598
13617
  const obj = mutable ? docObject : cloneProcessorValue(docObject);
13599
- (0, import_utils37.forEach)(Array.isArray(operations) ? operations : [], (op) => {
13618
+ (0, import_utils38.forEach)(Array.isArray(operations) ? operations : [], (op) => {
13600
13619
  if (!op || typeof op.src !== "string" || typeof op.dest !== "string") return;
13601
13620
  const src = op.src;
13602
13621
  const dest = op.dest;
@@ -13604,9 +13623,9 @@ var copyPaths = (docObject, operations, options = { mutable: true }) => {
13604
13623
  assertSafePath(src, "copyPaths");
13605
13624
  assertSafePath(dest, "copyPaths");
13606
13625
  if (src === dest) return;
13607
- (0, import_utils37.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
13608
- if (!(0, import_utils37.hasOwn)(parent, leaf)) return;
13609
- (0, import_utils37.set)(parent, dest, cloneProcessorValue(parent[leaf]));
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]));
13610
13629
  });
13611
13630
  });
13612
13631
  return obj;
@@ -13614,7 +13633,7 @@ var copyPaths = (docObject, operations, options = { mutable: true }) => {
13614
13633
  var movePaths = (docObject, operations, options = { mutable: true }) => {
13615
13634
  const mutable = options.mutable !== false;
13616
13635
  const obj = mutable ? docObject : cloneProcessorValue(docObject);
13617
- (0, import_utils37.forEach)(Array.isArray(operations) ? operations : [], (op) => {
13636
+ (0, import_utils38.forEach)(Array.isArray(operations) ? operations : [], (op) => {
13618
13637
  if (!op || typeof op.src !== "string" || typeof op.dest !== "string") return;
13619
13638
  const src = op.src;
13620
13639
  const dest = op.dest;
@@ -13622,10 +13641,10 @@ var movePaths = (docObject, operations, options = { mutable: true }) => {
13622
13641
  assertSafePath(src, "movePaths");
13623
13642
  assertSafePath(dest, "movePaths");
13624
13643
  if (src === dest) return;
13625
- (0, import_utils37.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
13626
- if (!(0, import_utils37.hasOwn)(parent, leaf)) return;
13644
+ (0, import_utils38.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
13645
+ if (!(0, import_utils38.hasOwn)(parent, leaf)) return;
13627
13646
  const value = cloneProcessorValue(parent[leaf]);
13628
- (0, import_utils37.set)(parent, dest, value);
13647
+ (0, import_utils38.set)(parent, dest, value);
13629
13648
  if (dest === leaf || dest.startsWith(`${leaf}.`)) return;
13630
13649
  delete parent[leaf];
13631
13650
  });
@@ -13637,7 +13656,7 @@ var sliceArrays = (docObject, operations, options = { mutable: true, maxSlice: D
13637
13656
  const maxSlice = options.maxSlice ?? DEFAULT_MAX_SLICE;
13638
13657
  assertNonNegativeSafeInteger(maxSlice, "maxSlice", "sliceArrays");
13639
13658
  const obj = mutable ? docObject : cloneProcessorValue(docObject);
13640
- (0, import_utils37.forEach)(Array.isArray(operations) ? operations : [], (op) => {
13659
+ (0, import_utils38.forEach)(Array.isArray(operations) ? operations : [], (op) => {
13641
13660
  if (!op || typeof op.src !== "string") return;
13642
13661
  const src = op.src;
13643
13662
  if (src.length === 0) return;
@@ -13654,15 +13673,15 @@ var sliceArrays = (docObject, operations, options = { mutable: true, maxSlice: D
13654
13673
  assertNonNegativeSafeInteger(op.limit, "limit", "sliceArrays");
13655
13674
  limit = Math.min(op.limit, maxSlice);
13656
13675
  }
13657
- (0, import_utils37.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
13676
+ (0, import_utils38.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
13658
13677
  const leafValue = parent[leaf];
13659
- if (!(0, import_utils37.isArray)(leafValue)) return;
13678
+ if (!(0, import_utils38.isArray)(leafValue)) return;
13660
13679
  const end = typeof limit === "undefined" ? void 0 : skip + limit;
13661
13680
  const window = leafValue.slice(skip, end);
13662
13681
  if (typeof rawDest === "undefined") {
13663
- (0, import_utils37.set)(parent, leaf, window);
13682
+ (0, import_utils38.set)(parent, leaf, window);
13664
13683
  } else {
13665
- (0, import_utils37.set)(parent, rawDest, window);
13684
+ (0, import_utils38.set)(parent, rawDest, window);
13666
13685
  }
13667
13686
  });
13668
13687
  });
@@ -13671,27 +13690,27 @@ var sliceArrays = (docObject, operations, options = { mutable: true, maxSlice: D
13671
13690
  var countPaths = (docObject, operations, options = { mutable: true }) => {
13672
13691
  const mutable = options.mutable !== false;
13673
13692
  const obj = mutable ? docObject : cloneProcessorValue(docObject);
13674
- (0, import_utils37.forEach)(Array.isArray(operations) ? operations : [], (op) => {
13693
+ (0, import_utils38.forEach)(Array.isArray(operations) ? operations : [], (op) => {
13675
13694
  if (!op || typeof op.src !== "string" || typeof op.dest !== "string") return;
13676
13695
  const src = op.src;
13677
13696
  const dest = op.dest;
13678
13697
  if (src.length === 0 || dest.length === 0) return;
13679
13698
  assertSafePath(src, "countPaths");
13680
13699
  assertSafePath(dest, "countPaths");
13681
- (0, import_utils37.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
13682
- if (!(0, import_utils37.hasOwn)(parent, leaf)) return;
13700
+ (0, import_utils38.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
13701
+ if (!(0, import_utils38.hasOwn)(parent, leaf)) return;
13683
13702
  const leafValue = parent[leaf];
13684
13703
  let count;
13685
- if ((0, import_utils37.isArray)(leafValue)) {
13704
+ if ((0, import_utils38.isArray)(leafValue)) {
13686
13705
  count = leafValue.length;
13687
- } else if ((0, import_utils37.isPlainObject)(leafValue)) {
13706
+ } else if ((0, import_utils38.isPlainObject)(leafValue)) {
13688
13707
  count = Object.keys(leafValue).length;
13689
13708
  } else if (leafValue === null || typeof leafValue === "undefined") {
13690
13709
  count = 0;
13691
13710
  } else {
13692
13711
  count = 1;
13693
13712
  }
13694
- (0, import_utils37.set)(parent, dest, count);
13713
+ (0, import_utils38.set)(parent, dest, count);
13695
13714
  });
13696
13715
  });
13697
13716
  return obj;
@@ -13699,15 +13718,15 @@ var countPaths = (docObject, operations, options = { mutable: true }) => {
13699
13718
  var maskPaths = (docObject, operations, options = { mutable: true }) => {
13700
13719
  const mutable = options.mutable !== false;
13701
13720
  const obj = mutable ? docObject : cloneProcessorValue(docObject);
13702
- (0, import_utils37.forEach)(Array.isArray(operations) ? operations : [], (op) => {
13721
+ (0, import_utils38.forEach)(Array.isArray(operations) ? operations : [], (op) => {
13703
13722
  if (!op || typeof op.src !== "string") return;
13704
13723
  const src = op.src;
13705
13724
  if (src.length === 0) return;
13706
13725
  assertSafePath(src, "maskPaths");
13707
13726
  const replacement = Object.prototype.hasOwnProperty.call(op, "replacement") ? op.replacement : DEFAULT_MASK_REPLACEMENT;
13708
- (0, import_utils37.forEach)(resolveLeafParents(obj, src), ({ parent, leaf }) => {
13709
- if (!(0, import_utils37.hasOwn)(parent, leaf)) return;
13710
- (0, import_utils37.set)(parent, leaf, replacement);
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);
13711
13730
  });
13712
13731
  });
13713
13732
  return obj;
@@ -13762,6 +13781,8 @@ init_core_shared();
13762
13781
  init_virtual_projection();
13763
13782
  init_populate_target();
13764
13783
  init_model_output_planning();
13784
+ init_authorization_snapshot();
13785
+ init_document();
13765
13786
  init_output_field_filter();
13766
13787
  init_request_work();
13767
13788
  var emptyPermissionLeaf = () => ({ $: "_" });
@@ -13779,10 +13800,10 @@ var Core = class {
13779
13800
  getIdentifier(modelName) {
13780
13801
  const resolveIdFilter = getModelOption(modelName, "resolveIdFilter");
13781
13802
  const idField = getModelOption(modelName, "idField");
13782
- if ((0, import_utils38.isFunction)(resolveIdFilter)) {
13803
+ if ((0, import_utils39.isFunction)(resolveIdFilter)) {
13783
13804
  return null;
13784
13805
  }
13785
- if ((0, import_utils38.isString)(idField)) {
13806
+ if ((0, import_utils39.isString)(idField)) {
13786
13807
  return idField;
13787
13808
  }
13788
13809
  return "_id";
@@ -13872,17 +13893,11 @@ var Core = class {
13872
13893
  return this.genSelect(modelName, access, targetFields, options);
13873
13894
  }
13874
13895
  /** Persisted request-only populate admission; fetch planning is not field authority. */
13875
- async requestPopulateSelect(modelName, access, targetFields = null, scopePath = []) {
13896
+ async requestPopulateSelect(configuration, permissions, access, targetFields = null, scopePath = []) {
13876
13897
  const subPaths = scopePath.flatMap((part) => [part, "sub"]);
13877
- const permissionSchema = getModelOption(modelName, ["permissionSchema"].concat(subPaths).join("."));
13878
- const permissions = this.getGlobalPermissions();
13879
- let virtualNames;
13880
- try {
13881
- const runtime = getActiveRuntime() ?? defaultRuntime;
13882
- virtualNames = runtime.getVirtualNames(modelName, subPaths);
13883
- } catch {
13884
- virtualNames = [];
13885
- }
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("."));
13886
13901
  return resolveSelectForRequest({
13887
13902
  req: this.req,
13888
13903
  permissionSchema,
@@ -13901,17 +13916,25 @@ var Core = class {
13901
13916
  assertPublicAdmission(_populate, "populate");
13902
13917
  assertPopulateAccess(access);
13903
13918
  if (!_populate) return [];
13904
- let populate = Array.isArray(_populate) ? _populate : [_populate];
13905
- for (const p of populate) {
13906
- if (!(0, import_utils38.isString)(p)) assertPopulateAccess(p.access);
13907
- }
13908
- populate = (0, import_utils38.compact)(
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)(
13909
13932
  await Promise.all(
13910
- populate.map(async (p) => {
13911
- const populateAccess = !(0, import_utils38.isString)(p) && p.access ? p.access : access;
13933
+ descriptors.map(async (p) => {
13934
+ const populateAccess = !(0, import_utils39.isString)(p) && p.access ? p.access : access;
13912
13935
  assertPopulateAccess(populateAccess);
13913
- const originalSelect = (0, import_utils38.isString)(p) ? void 0 : p.select;
13914
- const ret = (0, import_utils38.isString)(p) ? { path: p } : {
13936
+ const originalSelect = (0, import_utils39.isString)(p) ? void 0 : p.select;
13937
+ const ret = (0, import_utils39.isString)(p) ? { path: p } : {
13915
13938
  path: p.path,
13916
13939
  select: normalizeSelect(p.select)
13917
13940
  };
@@ -13919,78 +13942,86 @@ var Core = class {
13919
13942
  const pathForSourcePermission = scopePrefix && ret.path.startsWith(`${scopePrefix}.`) ? ret.path.slice(scopePrefix.length + 1) : ret.path;
13920
13943
  const parentPath = pathForSourcePermission.includes(".") ? pathForSourcePermission.split(".")[0] : pathForSourcePermission;
13921
13944
  const allowedParentPaths = await this.requestPopulateSelect(
13922
- modelName,
13945
+ sourceConfiguration,
13946
+ permissions,
13923
13947
  populateAccess,
13924
13948
  [parentPath],
13925
13949
  scopePath
13926
13950
  );
13927
13951
  if (!allowedParentPaths.includes(parentPath)) return null;
13928
- const refModelName = getModelRef(modelName, ret.path);
13929
- if (!refModelName) return null;
13930
- const runtime = getActiveRuntime();
13931
- if (!runtime) return null;
13932
- const requireRegisteredPopulateModels = getGlobalOption("requireRegisteredPopulateModels", true);
13933
- if (!runtime.hasModel(refModelName)) {
13934
- return requireRegisteredPopulateModels ? null : ret;
13935
- }
13936
- const allowedTargetOperation = await this.isAllowed(refModelName, populateAccess);
13937
- if (!allowedTargetOperation) {
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
+ )) {
13938
13964
  return null;
13939
13965
  }
13940
- ret.select = await this.requestPopulateSelect(refModelName, populateAccess, ret.select);
13941
- const hookInputs = getModelOption(refModelName, `alwaysSelectFields.${populateAccess}`, []);
13942
- ret.select = (0, import_utils38.uniq)([...ret.select, ...stripVirtuals(hookInputs, runtime.getVirtualNames(refModelName))]);
13943
- const filter2 = await this.genFilter(refModelName, populateAccess, null);
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
+ });
13944
13990
  if (filter2 === false) return null;
13945
- ret.match = filter2;
13946
- try {
13947
- const planAccess = populateAccess;
13948
- const targetSnapshot = {
13949
- permissionSchema: getModelOption(refModelName, "permissionSchema", null) ?? null,
13950
- virtuals: getModelOption(refModelName, "virtuals", null) ?? null,
13951
- alwaysSelectFields: getModelOption(refModelName, "alwaysSelectFields", null) ?? null,
13952
- modelPermissionPrefix: getModelOption(refModelName, "modelPermissionPrefix", "") ?? "",
13953
- requireExplicitSelect: getModelOption(refModelName, "requireExplicitSelect", false) ?? false,
13954
- documentPermissionField: getModelOption(refModelName, "documentPermissionField", "_permissions") ?? "_permissions",
13955
- exposedDocPermissionKeys: getModelOption(refModelName, "exposedDocPermissionKeys", void 0),
13956
- stripPermissionsField: getModelOption(refModelName, "stripPermissionsField", false) ?? false,
13957
- disableFieldPermissions: getModelOption(refModelName, "disableFieldPermissions", false) ?? false
13958
- };
13959
- const perms = this.getPermissions();
13960
- const globalForPlan = perms && typeof perms.has === "function" && typeof perms.hasKey === "function" ? perms : { has: () => false, hasKey: () => false };
13961
- const targetPlan = planVirtualProjection({
13962
- receivingModelName: refModelName,
13963
- snapshot: {
13964
- permissionSchema: targetSnapshot.permissionSchema,
13965
- virtuals: targetSnapshot.virtuals,
13966
- alwaysSelectFields: targetSnapshot.alwaysSelectFields,
13967
- modelPermissionPrefix: targetSnapshot.modelPermissionPrefix,
13968
- requireExplicitSelect: targetSnapshot.requireExplicitSelect,
13969
- documentPermissionField: targetSnapshot.documentPermissionField
13970
- },
13971
- virtualAccess: planAccess,
13972
- outputAccess: planAccess,
13973
- docPermissionsAccess: planAccess,
13974
- requestedSelect: originalSelect,
13975
- internalFetch: { baseFields: ["_id"] },
13976
- globalPermissions: globalForPlan
13977
- });
13978
- const merged = (0, import_utils38.uniq)([...normalizeSelect(ret.select), ...targetPlan.virtualOnlyDeps ?? []]).filter(
13979
- (t) => t !== "-_id" && !t.includes(".sub.")
13980
- );
13981
- if (!merged.includes("_id")) merged.push("_id");
13982
- ret.select = merged;
13983
- setPopulateTargetMeta(ret, {
13984
- targetModelName: refModelName,
13985
- virtualAccess: planAccess,
13986
- outputAccess: planAccess,
13987
- docPermissionsAccess: planAccess,
13988
- requestedSelect: originalSelect,
13989
- plan: targetPlan,
13990
- snapshot: targetSnapshot
13991
- });
13992
- } catch {
13993
- }
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
+ });
13994
14025
  return ret;
13995
14026
  })
13996
14027
  )
@@ -13999,10 +14030,10 @@ var Core = class {
13999
14030
  }
14000
14031
  async validate(modelName, allowedData, access, context) {
14001
14032
  const validate = getModelOption(modelName, `validate.${access}`, null);
14002
- if ((0, import_utils38.isFunction)(validate)) {
14033
+ if ((0, import_utils39.isFunction)(validate)) {
14003
14034
  const permissions = this.getGlobalPermissions();
14004
14035
  return validate.call(this.req, allowedData, permissions, context);
14005
- } else if ((0, import_utils38.isBoolean)(validate) || (0, import_utils38.isArray)(validate)) {
14036
+ } else if ((0, import_utils39.isBoolean)(validate) || (0, import_utils39.isArray)(validate)) {
14006
14037
  return validate;
14007
14038
  } else {
14008
14039
  return true;
@@ -14027,7 +14058,7 @@ var Core = class {
14027
14058
  const changeOptions = getModelOption(modelName, `onChange`, {});
14028
14059
  for (let x = 0; x < context.modifiedPaths.length; x++) {
14029
14060
  const mpath = context.modifiedPaths[x];
14030
- if ((0, import_utils38.isFunction)(changeOptions[mpath])) {
14061
+ if ((0, import_utils39.isFunction)(changeOptions[mpath])) {
14031
14062
  await changeOptions[mpath].call(
14032
14063
  this.req,
14033
14064
  context.originalDocumentSnapshot[mpath],
@@ -14051,7 +14082,7 @@ var Core = class {
14051
14082
  async genDocPermissions(modelName, doc, access, context) {
14052
14083
  const docPermissionsFn = getModelOption(modelName, `docPermissions.${access}`, null);
14053
14084
  let docPermissions = {};
14054
- if ((0, import_utils38.isFunction)(docPermissionsFn)) {
14085
+ if ((0, import_utils39.isFunction)(docPermissionsFn)) {
14055
14086
  const permissions = this.getGlobalPermissions();
14056
14087
  try {
14057
14088
  docPermissions = await getRequestWorkState(this.req, this.requestRuntime).hookGate.run(
@@ -14135,7 +14166,7 @@ var Core = class {
14135
14166
  readExists ? requestFields("read") : [],
14136
14167
  updateExists ? requestFields("update") : []
14137
14168
  ]);
14138
- const viewObj = (0, import_utils38.reduce)(
14169
+ const viewObj = (0, import_utils39.reduce)(
14139
14170
  views,
14140
14171
  (ret, view) => {
14141
14172
  ret[view] = true;
@@ -14143,7 +14174,7 @@ var Core = class {
14143
14174
  },
14144
14175
  {}
14145
14176
  );
14146
- const editObj = (0, import_utils38.reduce)(
14177
+ const editObj = (0, import_utils39.reduce)(
14147
14178
  edits,
14148
14179
  (ret, view) => {
14149
14180
  ret[view] = true;
@@ -14174,9 +14205,9 @@ var Core = class {
14174
14205
  });
14175
14206
  }
14176
14207
  runTasks(modelName, docObject, task) {
14177
- const tasks = (0, import_utils38.compact)((0, import_utils38.castArray)(task));
14208
+ const tasks = (0, import_utils39.compact)((0, import_utils39.castArray)(task));
14178
14209
  if (tasks.length === 0) return docObject;
14179
- (0, import_utils38.forEach)(tasks, (task2) => {
14210
+ (0, import_utils39.forEach)(tasks, (task2) => {
14180
14211
  const { type, args, options } = task2;
14181
14212
  switch (type) {
14182
14213
  case "COPY_AND_DEPOPULATE":
@@ -14246,9 +14277,9 @@ var Core = class {
14246
14277
  }
14247
14278
  const [, field, op] = keys2;
14248
14279
  const subOption = getExactModelOption(modelName, `operationAccess.${access}`);
14249
- if ((0, import_utils38.isUndefined)(subOption)) {
14280
+ if ((0, import_utils39.isUndefined)(subOption)) {
14250
14281
  const subFieldOption = getExactModelOption(modelName, `operationAccess.subs.${field}`);
14251
- if ((0, import_utils38.isUndefined)(subFieldOption)) {
14282
+ if ((0, import_utils39.isUndefined)(subFieldOption)) {
14252
14283
  const opOption = getModelOption(modelName, `operationAccess.${op}`);
14253
14284
  return this.canActivate(opOption);
14254
14285
  }
@@ -14314,25 +14345,25 @@ function guard(condition) {
14314
14345
  const permissions = req[PERMISSIONS];
14315
14346
  let cond = condition;
14316
14347
  let phas = (key) => permissions.has(key);
14317
- if ((0, import_utils39.isPlainObject)(condition)) {
14348
+ if ((0, import_utils40.isPlainObject)(condition)) {
14318
14349
  const { modelName, id, condition: _cond } = condition;
14319
14350
  const svc = req.macl.getPublicService(modelName);
14320
14351
  const select = getModelOption(modelName, `alwaysSelectFields.read`, void 0);
14321
- let _id = (0, import_utils39.isString)(id) ? id : null;
14322
- if ((0, import_utils39.isPlainObject)(id)) {
14352
+ let _id = (0, import_utils40.isString)(id) ? id : null;
14353
+ if ((0, import_utils40.isPlainObject)(id)) {
14323
14354
  const { type = "param", key } = id;
14324
14355
  if (type === "param") {
14325
14356
  const paramValue = req.params[key];
14326
- _id = (0, import_utils39.isArray)(paramValue) ? paramValue[0] ?? null : paramValue ?? null;
14357
+ _id = (0, import_utils40.isArray)(paramValue) ? paramValue[0] ?? null : paramValue ?? null;
14327
14358
  } else if (type === "query") {
14328
14359
  const _qval = req.query[key];
14329
- if ((0, import_utils39.isArray)(_qval)) _id = _qval.length > 0 ? _qval[0] : null;
14360
+ if ((0, import_utils40.isArray)(_qval)) _id = _qval.length > 0 ? _qval[0] : null;
14330
14361
  else _id = _qval;
14331
14362
  } else {
14332
14363
  _id = null;
14333
14364
  }
14334
14365
  }
14335
- if (!(0, import_utils39.isString)(_id) || !_id) {
14366
+ if (!(0, import_utils40.isString)(_id) || !_id) {
14336
14367
  return next(new import_express_json_router5.default.clientErrors.BadRequestError());
14337
14368
  }
14338
14369
  const result2 = await svc._read(_id, { select });
@@ -14344,11 +14375,11 @@ function guard(condition) {
14344
14375
  cond = _cond;
14345
14376
  }
14346
14377
  const { stringHandler, arrayHandler } = createValidator(phas);
14347
- if ((0, import_utils39.isString)(cond)) {
14378
+ if ((0, import_utils40.isString)(cond)) {
14348
14379
  if (stringHandler(cond)) return next();
14349
- } else if ((0, import_utils39.isArray)(cond)) {
14380
+ } else if ((0, import_utils40.isArray)(cond)) {
14350
14381
  if (arrayHandler(cond)) return next();
14351
- } else if ((0, import_utils39.isFunction)(cond)) {
14382
+ } else if ((0, import_utils40.isFunction)(cond)) {
14352
14383
  const result2 = await cond.call(req, permissions);
14353
14384
  if (!!result2) return next();
14354
14385
  }
@@ -14361,7 +14392,7 @@ var import_express2 = __toESM(require("express"));
14361
14392
 
14362
14393
  // src/routers/model-router.ts
14363
14394
  var import_express_json_router8 = __toESM(require("@web-ts-toolkit/express-json-router"));
14364
- var import_utils43 = require("@web-ts-toolkit/utils");
14395
+ var import_utils44 = require("@web-ts-toolkit/utils");
14365
14396
  init_logger_helpers();
14366
14397
  init_runtime();
14367
14398
  init_runtime_context();
@@ -14495,7 +14526,7 @@ init_request_complexity();
14495
14526
 
14496
14527
  // src/validation/common.ts
14497
14528
  var import_zod2 = require("zod");
14498
- var import_utils40 = require("@web-ts-toolkit/utils");
14529
+ var import_utils41 = require("@web-ts-toolkit/utils");
14499
14530
 
14500
14531
  // src/validation/public-admission-schema.ts
14501
14532
  init_public_admission();
@@ -14624,7 +14655,7 @@ var correlatedFilterSchema = import_zod2.z.record(import_zod2.z.string(), import
14624
14655
  }
14625
14656
  });
14626
14657
  var correlatedEmptyOptionsSchema = import_zod2.z.unknown().refine(
14627
- (value) => value === void 0 || (0, import_utils40.isPlainObject)(value) && Object.keys(value).length === 0,
14658
+ (value) => value === void 0 || (0, import_utils41.isPlainObject)(value) && Object.keys(value).length === 0,
14628
14659
  "Correlated include options must be absent or empty"
14629
14660
  ).optional();
14630
14661
  var correlatedPathSchema = import_zod2.z.string().min(1).superRefine((path, ctx) => {
@@ -14661,7 +14692,7 @@ var correlatedListArgsSchema = import_zod2.z.object({
14661
14692
  include: import_zod2.z.lazy(() => correlatedNestedIncludeSchema).optional()
14662
14693
  }).strict().superRefine((args, ctx) => checkArgsMarkers(args.select, args.sort, ctx));
14663
14694
  var correlatedCountArgsSchema = import_zod2.z.unknown().refine(
14664
- (value) => value === void 0 || (0, import_utils40.isPlainObject)(value) && Object.keys(value).length === 0,
14695
+ (value) => value === void 0 || (0, import_utils41.isPlainObject)(value) && Object.keys(value).length === 0,
14665
14696
  "Count includes accept no args"
14666
14697
  ).optional();
14667
14698
  var correlatedReadByIdSchema = import_zod2.z.object({
@@ -14714,7 +14745,7 @@ var correlatedNestedIncludeSchema = import_zod2.z.union([includeItemSchema, impo
14714
14745
  var rejectDuplicateCorrelatedPaths = (items, ctx) => {
14715
14746
  const seen = /* @__PURE__ */ new Set();
14716
14747
  items.forEach((item, index) => {
14717
- if ((0, import_utils40.isPlainObject)(item) && item.mode === "correlated" && typeof item.path === "string") {
14748
+ if ((0, import_utils41.isPlainObject)(item) && item.mode === "correlated" && typeof item.path === "string") {
14718
14749
  if (seen.has(item.path)) {
14719
14750
  ctx.addIssue({
14720
14751
  code: import_zod2.z.ZodIssueCode.custom,
@@ -15687,7 +15718,7 @@ var rootQuerySchema = publicBoundarySchema(
15687
15718
  init_helpers();
15688
15719
 
15689
15720
  // src/routers/shared.ts
15690
- var import_utils41 = require("@web-ts-toolkit/utils");
15721
+ var import_utils42 = require("@web-ts-toolkit/utils");
15691
15722
 
15692
15723
  // src/routers/model-router-collection-routes.ts
15693
15724
  init_schemas();
@@ -15718,15 +15749,15 @@ function setModelCollectionRoutes(context) {
15718
15749
  sort
15719
15750
  } = parseQuery(requestSchemas.listQuery, req.query);
15720
15751
  const svc = context.getPublicService(req);
15721
- const includeCount = (0, import_utils41.parseBooleanString)(include_count);
15722
- const includeExtraHeaders = (0, import_utils41.parseBooleanString)(include_extra_headers);
15752
+ const includeCount = (0, import_utils42.parseBooleanString)(include_count);
15753
+ const includeExtraHeaders = (0, import_utils42.parseBooleanString)(include_extra_headers);
15723
15754
  const result2 = await svc._list(
15724
15755
  {},
15725
15756
  { select: parseSelectParam(select), sort, skip, limit, page, pageSize: page_size },
15726
15757
  {
15727
- skim: (0, import_utils41.parseBooleanString)(skim),
15728
- includePermissions: (0, import_utils41.parseBooleanString)(include_permissions),
15729
- includeFieldPermissions: (0, import_utils41.parseBooleanString)(include_field_permissions),
15758
+ skim: (0, import_utils42.parseBooleanString)(skim),
15759
+ includePermissions: (0, import_utils42.parseBooleanString)(include_permissions),
15760
+ includeFieldPermissions: (0, import_utils42.parseBooleanString)(include_field_permissions),
15730
15761
  includeCount
15731
15762
  }
15732
15763
  );
@@ -15786,8 +15817,8 @@ function setModelCollectionRoutes(context) {
15786
15817
  data,
15787
15818
  {},
15788
15819
  {
15789
- includePermissions: (0, import_utils41.parseBooleanString)(include_permissions),
15790
- includeFieldPermissions: (0, import_utils41.parseBooleanString)(include_field_permissions)
15820
+ includePermissions: (0, import_utils42.parseBooleanString)(include_permissions),
15821
+ includeFieldPermissions: (0, import_utils42.parseBooleanString)(include_field_permissions)
15791
15822
  }
15792
15823
  );
15793
15824
  handleResultError(result2);
@@ -15825,8 +15856,8 @@ function setModelCollectionRoutes(context) {
15825
15856
  finalData,
15826
15857
  { select: finalSelect, populate: finalPopulate, tasks: finalTasks },
15827
15858
  {
15828
- includePermissions: includePermissions ?? (0, import_utils41.parseBooleanString)(include_permissions),
15829
- includeFieldPermissions: includeFieldPermissions ?? (0, import_utils41.parseBooleanString)(include_field_permissions),
15859
+ includePermissions: includePermissions ?? (0, import_utils42.parseBooleanString)(include_permissions),
15860
+ includeFieldPermissions: includeFieldPermissions ?? (0, import_utils42.parseBooleanString)(include_field_permissions),
15830
15861
  populateAccess
15831
15862
  }
15832
15863
  );
@@ -15923,9 +15954,9 @@ function setModelDocumentRoutes(context) {
15923
15954
  id,
15924
15955
  { select: parseSelectParam(select) },
15925
15956
  {
15926
- includePermissions: (0, import_utils41.parseBooleanString)(include_permissions),
15927
- includeFieldPermissions: (0, import_utils41.parseBooleanString)(include_field_permissions),
15928
- tryList: (0, import_utils41.parseBooleanString)(try_list)
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)
15929
15960
  }
15930
15961
  );
15931
15962
  handleResultError(result2);
@@ -16025,9 +16056,9 @@ function setModelDocumentRoutes(context) {
16025
16056
  data,
16026
16057
  { select: parseSelectParam(select) },
16027
16058
  {
16028
- returningAll: (0, import_utils41.parseBooleanString)(returning_all),
16029
- includePermissions: (0, import_utils41.parseBooleanString)(include_permissions),
16030
- includeFieldPermissions: (0, import_utils41.parseBooleanString)(include_field_permissions)
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)
16031
16062
  }
16032
16063
  );
16033
16064
  handleResultError(result2);
@@ -16076,9 +16107,9 @@ function setModelDocumentRoutes(context) {
16076
16107
  finalData,
16077
16108
  { select: finalSelect, populate: finalPopulate, tasks: finalTasks },
16078
16109
  {
16079
- returningAll: returningAll ?? (0, import_utils41.parseBooleanString)(returning_all),
16080
- includePermissions: includePermissions ?? (0, import_utils41.parseBooleanString)(include_permissions),
16081
- includeFieldPermissions: includeFieldPermissions ?? (0, import_utils41.parseBooleanString)(include_field_permissions),
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),
16082
16113
  populateAccess
16083
16114
  }
16084
16115
  );
@@ -16109,9 +16140,9 @@ function setModelDocumentRoutes(context) {
16109
16140
  body,
16110
16141
  {},
16111
16142
  {
16112
- returningAll: (0, import_utils41.parseBooleanString)(returning_all),
16113
- includePermissions: (0, import_utils41.parseBooleanString)(include_permissions),
16114
- includeFieldPermissions: (0, import_utils41.parseBooleanString)(include_field_permissions)
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)
16115
16146
  }
16116
16147
  );
16117
16148
  handleResultError(result2);
@@ -16158,9 +16189,9 @@ function setModelDocumentRoutes(context) {
16158
16189
  finalData,
16159
16190
  { select: finalSelect, populate: finalPopulate, tasks: finalTasks },
16160
16191
  {
16161
- returningAll: returningAll ?? (0, import_utils41.parseBooleanString)(returning_all),
16162
- includePermissions: includePermissions ?? (0, import_utils41.parseBooleanString)(include_permissions),
16163
- includeFieldPermissions: includeFieldPermissions ?? (0, import_utils41.parseBooleanString)(include_field_permissions),
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),
16164
16195
  populateAccess
16165
16196
  }
16166
16197
  );
@@ -16400,11 +16431,11 @@ function setModelSubDocumentRoutes(context) {
16400
16431
  }
16401
16432
 
16402
16433
  // src/openapi/route-registration.ts
16403
- var import_utils42 = require("@web-ts-toolkit/utils");
16434
+ var import_utils43 = require("@web-ts-toolkit/utils");
16404
16435
  function registerOpenApiRoute(runtime, basePath, defaultTag, route) {
16405
16436
  runtime.registerOpenApiRoute({
16406
16437
  ...route,
16407
- path: (0, import_utils42.normalizeUrlPath)(basePath + route.path),
16438
+ path: (0, import_utils43.normalizeUrlPath)(basePath + route.path),
16408
16439
  tags: route.tags ?? [defaultTag]
16409
16440
  });
16410
16441
  }
@@ -16412,8 +16443,8 @@ function registerOpenApiRoute(runtime, basePath, defaultTag, route) {
16412
16443
  // src/routers/model-router.ts
16413
16444
  var clientErrors2 = import_express_json_router8.default.clientErrors;
16414
16445
  function setOption(parentKey, optionKey, option) {
16415
- const key = (0, import_utils43.isUndefined)(option) ? parentKey : `${parentKey}.${optionKey}`;
16416
- const value = (0, import_utils43.isUndefined)(option) ? optionKey : option;
16446
+ const key = (0, import_utils44.isUndefined)(option) ? parentKey : `${parentKey}.${optionKey}`;
16447
+ const value = (0, import_utils44.isUndefined)(option) ? optionKey : option;
16417
16448
  assertMutableRouterOption("model", key);
16418
16449
  this.runtime.setModelOption(
16419
16450
  this.modelName,
@@ -16615,7 +16646,7 @@ var ModelRouter = class _ModelRouter {
16615
16646
  this.runtime = runtime;
16616
16647
  this.runtime.setModelOptions(modelName, initialOptions);
16617
16648
  this.options = this.runtime.getModelOptions(modelName);
16618
- this.fullBasePath = (0, import_utils43.normalizeUrlPath)(this.options.parentPath + this.options.basePath);
16649
+ this.fullBasePath = (0, import_utils44.normalizeUrlPath)(this.options.parentPath + this.options.basePath);
16619
16650
  this.modelName = modelName;
16620
16651
  this.router = new import_express_json_router8.default(this.options.basePath, createSetCore(this.runtime), accessRouterResponseHandler);
16621
16652
  this.model = new model_default(modelName, this.runtime);
@@ -16701,13 +16732,13 @@ var ModelRouter = class _ModelRouter {
16701
16732
  }
16702
16733
  logEndpoints() {
16703
16734
  runWithRuntime(this.runtime, () => {
16704
- (0, import_utils43.forEach)(this.router.getEndpoints(), ({ method, path }) => {
16705
- logInfoMessage(`${(0, import_utils43.padEnd)(method, 6)} ${(0, import_utils43.normalizeUrlPath)(this.options.parentPath + path)}`);
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)}`);
16706
16737
  });
16707
16738
  });
16708
16739
  }
16709
16740
  set(keyOrOptions, value) {
16710
- if (arguments.length === 2 && (0, import_utils43.isString)(keyOrOptions)) {
16741
+ if (arguments.length === 2 && (0, import_utils44.isString)(keyOrOptions)) {
16711
16742
  assertMutableRouterOption("model", keyOrOptions);
16712
16743
  this.runtime.setModelOption(
16713
16744
  this.modelName,
@@ -16715,7 +16746,7 @@ var ModelRouter = class _ModelRouter {
16715
16746
  value
16716
16747
  );
16717
16748
  }
16718
- if (arguments.length === 1 && (0, import_utils43.isPlainObject)(keyOrOptions)) {
16749
+ if (arguments.length === 1 && (0, import_utils44.isPlainObject)(keyOrOptions)) {
16719
16750
  assertMutableRouterOptions("model", keyOrOptions);
16720
16751
  this.runtime.setModelOptions(
16721
16752
  this.modelName,
@@ -16743,7 +16774,7 @@ var ModelRouter = class _ModelRouter {
16743
16774
 
16744
16775
  // src/routers/root-router.ts
16745
16776
  var import_express_json_router9 = __toESM(require("@web-ts-toolkit/express-json-router"));
16746
- var import_utils44 = require("@web-ts-toolkit/utils");
16777
+ var import_utils45 = require("@web-ts-toolkit/utils");
16747
16778
 
16748
16779
  // src/core-data.ts
16749
16780
  init_options();
@@ -17051,7 +17082,7 @@ var RootRouter = class {
17051
17082
  this.setRoutes();
17052
17083
  }
17053
17084
  registerOpenApiRoute(route) {
17054
- registerOpenApiRoute(this.runtime, (0, import_utils44.normalizeUrlPath)(this.basename), "root", route);
17085
+ registerOpenApiRoute(this.runtime, (0, import_utils45.normalizeUrlPath)(this.basename), "root", route);
17055
17086
  }
17056
17087
  wrapResult(index, item, result2) {
17057
17088
  return {
@@ -17160,7 +17191,7 @@ var RootRouter = class {
17160
17191
  groupItemsByOrder(items) {
17161
17192
  const groups = /* @__PURE__ */ new Map();
17162
17193
  items.forEach((item, index) => {
17163
- const order = (0, import_utils44.isNumber)(item.order) ? item.order : 0;
17194
+ const order = (0, import_utils45.isNumber)(item.order) ? item.order : 0;
17164
17195
  const group = groups.get(order);
17165
17196
  if (group) {
17166
17197
  group.push({ index, item });
@@ -17231,7 +17262,7 @@ var RootRouter = class {
17231
17262
  const arrResult = await this.runGroup(req, groupedItems[x]);
17232
17263
  results.push(...arrResult);
17233
17264
  }
17234
- return (0, import_utils44.orderBy)(results, ["index"], ["asc"]);
17265
+ return (0, import_utils45.orderBy)(results, ["index"], ["asc"]);
17235
17266
  });
17236
17267
  this.registerOpenApiRoute({
17237
17268
  method: "post",
@@ -17249,14 +17280,14 @@ var RootRouter = class {
17249
17280
 
17250
17281
  // src/routers/data-router.ts
17251
17282
  var import_express_json_router10 = __toESM(require("@web-ts-toolkit/express-json-router"));
17252
- var import_utils45 = require("@web-ts-toolkit/utils");
17283
+ var import_utils46 = require("@web-ts-toolkit/utils");
17253
17284
  init_runtime();
17254
17285
  init_helpers();
17255
17286
  init_schemas();
17256
17287
  var clientErrors4 = import_express_json_router10.default.clientErrors;
17257
17288
  function setOption2(parentKey, optionKey, option) {
17258
- const key = (0, import_utils45.isUndefined)(option) ? parentKey : `${parentKey}.${optionKey}`;
17259
- const value = (0, import_utils45.isUndefined)(option) ? optionKey : option;
17289
+ const key = (0, import_utils46.isUndefined)(option) ? parentKey : `${parentKey}.${optionKey}`;
17290
+ const value = (0, import_utils46.isUndefined)(option) ? optionKey : option;
17260
17291
  assertMutableRouterOption("data", key);
17261
17292
  this.runtime.setDataOption(this.dataName, key, value);
17262
17293
  return this;
@@ -17305,7 +17336,7 @@ var DataRouter = class {
17305
17336
  this.runtime = runtime;
17306
17337
  this.runtime.setDataOptions(dataName, initialOptions);
17307
17338
  this.options = this.runtime.getDataOptions(dataName);
17308
- this.fullBasePath = (0, import_utils45.normalizeUrlPath)(this.options.parentPath + this.options.basePath);
17339
+ this.fullBasePath = (0, import_utils46.normalizeUrlPath)(this.options.parentPath + this.options.basePath);
17309
17340
  this.dataName = dataName;
17310
17341
  this.router = new import_express_json_router10.default(this.options.basePath, createSetDataCore(this.runtime), accessRouterResponseHandler);
17311
17342
  this.setCollectionRoutes();
@@ -17338,8 +17369,8 @@ var DataRouter = class {
17338
17369
  req.query
17339
17370
  );
17340
17371
  const svc = this.getService(req);
17341
- const includeCount = (0, import_utils41.parseBooleanString)(include_count);
17342
- const includeExtraHeaders = (0, import_utils41.parseBooleanString)(include_extra_headers);
17372
+ const includeCount = (0, import_utils42.parseBooleanString)(include_count);
17373
+ const includeExtraHeaders = (0, import_utils42.parseBooleanString)(include_extra_headers);
17343
17374
  const result2 = await svc.find(
17344
17375
  {},
17345
17376
  { select: parseSelectParam(select), sort, skip, limit, page, pageSize: page_size },
@@ -17457,7 +17488,7 @@ var DataRouter = class {
17457
17488
  });
17458
17489
  }
17459
17490
  set(keyOrOptions, value) {
17460
- if (arguments.length === 2 && (0, import_utils45.isString)(keyOrOptions)) {
17491
+ if (arguments.length === 2 && (0, import_utils46.isString)(keyOrOptions)) {
17461
17492
  assertMutableRouterOption("data", keyOrOptions);
17462
17493
  this.runtime.setDataOption(
17463
17494
  this.dataName,
@@ -17465,7 +17496,7 @@ var DataRouter = class {
17465
17496
  value
17466
17497
  );
17467
17498
  }
17468
- if (arguments.length === 1 && (0, import_utils45.isPlainObject)(keyOrOptions)) {
17499
+ if (arguments.length === 1 && (0, import_utils46.isPlainObject)(keyOrOptions)) {
17469
17500
  assertMutableRouterOptions("data", keyOrOptions);
17470
17501
  this.runtime.setDataOptions(this.dataName, keyOrOptions);
17471
17502
  }
@@ -17600,7 +17631,7 @@ function createRuntimeApi(runtime) {
17600
17631
  const wtt2 = runtimeMiddleware;
17601
17632
  wtt2.runtime = runtime;
17602
17633
  wtt2.createRouter = function(modelName, options) {
17603
- if ((0, import_utils46.isUndefined)(options)) {
17634
+ if ((0, import_utils47.isUndefined)(options)) {
17604
17635
  return new RootRouter(modelName, runtime);
17605
17636
  }
17606
17637
  if (typeof modelName === "string") {
@@ -17621,10 +17652,10 @@ function createRuntimeApi(runtime) {
17621
17652
  };
17622
17653
  wtt2.combineRoutes = combineRoutes;
17623
17654
  wtt2.set = function(keyOrOptions, value) {
17624
- if (arguments.length === 2 && (0, import_utils46.isString)(keyOrOptions)) {
17655
+ if (arguments.length === 2 && (0, import_utils47.isString)(keyOrOptions)) {
17625
17656
  return runtime.setGlobalOption(keyOrOptions, value);
17626
17657
  }
17627
- if (arguments.length === 1 && (0, import_utils46.isPlainObject)(keyOrOptions)) {
17658
+ if (arguments.length === 1 && (0, import_utils47.isPlainObject)(keyOrOptions)) {
17628
17659
  return runtime.setGlobalOptions(keyOrOptions);
17629
17660
  }
17630
17661
  };