@web-ts-toolkit/access-router 0.56.0 → 0.58.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/advanced.js CHANGED
@@ -260,7 +260,7 @@ function normalizeHydrationUpdate(current, key, value) {
260
260
 
261
261
  // src/runtime.ts
262
262
  var import_mongoose_schema_jsonschema = __toESM(require("mongoose-schema-jsonschema"));
263
- var import_utils12 = require("@web-ts-toolkit/utils");
263
+ var import_utils13 = require("@web-ts-toolkit/utils");
264
264
 
265
265
  // src/helpers/query.ts
266
266
  var import_utils2 = require("@web-ts-toolkit/utils");
@@ -1237,7 +1237,7 @@ function resolveSnapshotDescriptor(scopeVirtuals, virtualName, access) {
1237
1237
  }
1238
1238
 
1239
1239
  // src/acl/virtual-populate-dependencies.ts
1240
- var import_utils11 = require("@web-ts-toolkit/utils");
1240
+ var import_utils12 = require("@web-ts-toolkit/utils");
1241
1241
 
1242
1242
  // src/acl/authorization-snapshot.ts
1243
1243
  var import_node_util3 = require("util");
@@ -1445,6 +1445,25 @@ function captureAuthorizationFieldCatalog(schema, virtuals, documentPermissionFi
1445
1445
  });
1446
1446
  }
1447
1447
 
1448
+ // src/acl/populate-target-configuration.ts
1449
+ var import_utils11 = require("@web-ts-toolkit/utils");
1450
+ function capturePopulateTargetConfiguration(runtime, modelName, source, proposedOptions) {
1451
+ const label = `Populate target "${modelName}" for ${source}`;
1452
+ if (!proposedOptions && !runtime.hasModel(modelName))
1453
+ authorizationError(
1454
+ `${label} must be configured first in this runtime; register its Mongoose model and setModelOptions with an object permissionSchema`
1455
+ );
1456
+ const model = runtime.getModelInstance(modelName);
1457
+ if (!model) authorizationError(`${label} requires an actual registered Mongoose model in this runtime`);
1458
+ const options = proposedOptions ?? runtime.getModelOptions(modelName);
1459
+ const permissionSchema = options.permissionSchema === void 0 ? runtime.getDefaultModelOption("permissionSchema") : options.permissionSchema;
1460
+ if (!(0, import_utils11.isPlainObject)(permissionSchema))
1461
+ authorizationError(
1462
+ `${label} requires an effective object permissionSchema; configure the model or runtime model defaults ({} explicitly closes business fields)`
1463
+ );
1464
+ return { model, options: { ...options, permissionSchema } };
1465
+ }
1466
+
1448
1467
  // src/acl/virtual-populate-dependencies.ts
1449
1468
  var elementType = (type) => type.$embeddedSchemaType ?? type.embeddedSchemaType ?? type.caster;
1450
1469
  var join = (prefix, path) => prefix ? `${prefix}.${path}` : path;
@@ -1456,7 +1475,7 @@ var fail = (label, message) => {
1456
1475
  var varyingSchema = (schema) => Object.keys(schema.discriminators ?? {}).length > 0 || schema.discriminatorMapping?.isRoot === false;
1457
1476
  var varyingModel = (model) => !!model.baseModelName || Object.keys(model.discriminators ?? {}).length > 0 || varyingSchema(model.schema);
1458
1477
  function record(value, label) {
1459
- if (!(0, import_utils11.isPlainObject)(value)) return fail(label, "entries must be plain { path, select? } objects");
1478
+ if (!(0, import_utils12.isPlainObject)(value)) return fail(label, "entries must be plain { path, select? } objects");
1460
1479
  for (const key of Reflect.ownKeys(value)) {
1461
1480
  const property = Object.getOwnPropertyDescriptor(value, key);
1462
1481
  if (typeof key !== "string" || !property.enumerable || !("value" in property))
@@ -1545,7 +1564,8 @@ function normalizeSelection(select, catalog, label) {
1545
1564
  };
1546
1565
  }
1547
1566
  function captureVirtualPopulateDependencies(runtime, modelName, options, globalOptions = runtime.getGlobalOptions()) {
1548
- const requireReadOperationAccessForPopulateDependencies = globalOptions.requireReadOperationAccessForPopulateDependencies !== false;
1567
+ const requireOperationAccessForPopulateDependencies = globalOptions.requireOperationAccessForPopulateDependencies !== false;
1568
+ const requireOperationAccessForPopulateQueries = globalOptions.requireOperationAccessForPopulateQueries !== false;
1549
1569
  const model = runtime.getModelInstance(modelName);
1550
1570
  const targets = /* @__PURE__ */ new Map();
1551
1571
  const scopes = [];
@@ -1585,16 +1605,23 @@ function captureVirtualPopulateDependencies(runtime, modelName, options, globalO
1585
1605
  label,
1586
1606
  `target "${ref}" requires a registered same-connection non-discriminator ObjectId model bound to the source ref`
1587
1607
  );
1588
- const targetOptions = ref === modelName ? options : runtime.getModelOptions(ref);
1608
+ const { options: targetOptions } = capturePopulateTargetConfiguration(
1609
+ runtime,
1610
+ ref,
1611
+ `dependsOnPopulate virtual "${label}"`,
1612
+ ref === modelName ? options : void 0
1613
+ );
1589
1614
  const defaults = runtime.getDefaultModelOptions();
1590
- const readOption = (key) => resolveNestedOption((path2, fallback) => (0, import_utils11.get)(targetOptions, path2, fallback), key, (0, import_utils11.get)(defaults, key));
1615
+ const readOption = (key) => resolveNestedOption((path2, fallback) => (0, import_utils12.get)(targetOptions, path2, fallback), key, (0, import_utils12.get)(defaults, key));
1591
1616
  const documentPermissionField = targetOptions.documentPermissionField ?? defaults.documentPermissionField;
1592
1617
  const catalog = captureAuthorizationFieldCatalog(targetModel.schema, void 0, documentPermissionField);
1593
1618
  const configuration = copyAuthorizationValue(
1594
1619
  {
1595
1620
  catalog,
1596
1621
  documentPermissionField,
1597
- requireReadOperationAccessForPopulateDependencies,
1622
+ requireOperationAccessForPopulateDependencies,
1623
+ requireOperationAccessForPopulateQueries,
1624
+ permissionSchema: targetOptions.permissionSchema,
1598
1625
  operationAccess: { read: readOption("operationAccess.read") },
1599
1626
  baseFilter: { read: readOption("baseFilter.read") },
1600
1627
  overrideFilter: { read: readOption("overrideFilter.read") },
@@ -1643,13 +1670,13 @@ function captureVirtualPopulateDependencies(runtime, modelName, options, globalO
1643
1670
  );
1644
1671
  continue;
1645
1672
  }
1646
- if (!(0, import_utils11.isPlainObject)(raw)) continue;
1673
+ if (!(0, import_utils12.isPlainObject)(raw)) continue;
1647
1674
  const entry = raw;
1648
1675
  const label = join(sourcePrefix, name);
1649
1676
  captureList(entry.dependsOnPopulate, label);
1650
1677
  if (!("get" in entry))
1651
1678
  for (const access of accesses) {
1652
- if ((0, import_utils11.isPlainObject)(entry[access]))
1679
+ if ((0, import_utils12.isPlainObject)(entry[access]))
1653
1680
  captureList(entry[access].dependsOnPopulate, `${label}.${access}`);
1654
1681
  }
1655
1682
  const byAccess = {};
@@ -1695,44 +1722,44 @@ var defaultDataOptions = {
1695
1722
  listHardLimit: DEFAULT_LIST_HARD_LIMIT
1696
1723
  };
1697
1724
  var normalizeBasePath = (name, value) => {
1698
- if ((0, import_utils12.isNil)(value)) {
1725
+ if ((0, import_utils13.isNil)(value)) {
1699
1726
  return `/${pluralize(name)}`;
1700
1727
  }
1701
- return (0, import_utils12.isString)(value) ? (0, import_utils12.addLeadingSlash)(value) : "";
1728
+ return (0, import_utils13.isString)(value) ? (0, import_utils13.addLeadingSlash)(value) : "";
1702
1729
  };
1703
1730
  var hasModelPermission = (value, modelPermissionPrefix) => {
1704
1731
  if (!modelPermissionPrefix) {
1705
1732
  return true;
1706
1733
  }
1707
- if ((0, import_utils12.isString)(value)) {
1734
+ if ((0, import_utils13.isString)(value)) {
1708
1735
  return value.trim().split(" ").some((item) => item.startsWith(modelPermissionPrefix));
1709
1736
  }
1710
- if ((0, import_utils12.isArray)(value)) {
1737
+ if ((0, import_utils13.isArray)(value)) {
1711
1738
  return value.some((item) => {
1712
- if ((0, import_utils12.isString)(item) || (0, import_utils12.isArray)(item)) {
1739
+ if ((0, import_utils13.isString)(item) || (0, import_utils13.isArray)(item)) {
1713
1740
  return hasModelPermission(item, modelPermissionPrefix);
1714
1741
  }
1715
1742
  return true;
1716
1743
  });
1717
1744
  }
1718
- return (0, import_utils12.isFunction)(value);
1745
+ return (0, import_utils13.isFunction)(value);
1719
1746
  };
1720
1747
  var classifyPermissionSchema = (permissionSchema, modelPermissionPrefix) => {
1721
1748
  const schemaKeys = Object.keys(permissionSchema);
1722
1749
  const globalPermissionKeys = {};
1723
1750
  const modelPermissionKeys = {};
1724
- (0, import_utils12.forEach)(schemaKeys, (schemaKey) => {
1751
+ (0, import_utils13.forEach)(schemaKeys, (schemaKey) => {
1725
1752
  const schemaRule = permissionSchema[schemaKey];
1726
- const ruleEntries = (0, import_utils12.isPlainObject)(schemaRule) ? Object.entries(schemaRule) : FIELD_ACCESS_KEYS.map((accessKey) => [accessKey, schemaRule]);
1753
+ const ruleEntries = (0, import_utils13.isPlainObject)(schemaRule) ? Object.entries(schemaRule) : FIELD_ACCESS_KEYS.map((accessKey) => [accessKey, schemaRule]);
1727
1754
  for (let x = 0; x < ruleEntries.length; x++) {
1728
1755
  const [accessKey, value] = ruleEntries[x];
1729
- if (!(0, import_utils12.isArray)(globalPermissionKeys[accessKey])) {
1756
+ if (!(0, import_utils13.isArray)(globalPermissionKeys[accessKey])) {
1730
1757
  globalPermissionKeys[accessKey] = [];
1731
1758
  }
1732
- if (!(0, import_utils12.isArray)(modelPermissionKeys[accessKey])) {
1759
+ if (!(0, import_utils13.isArray)(modelPermissionKeys[accessKey])) {
1733
1760
  modelPermissionKeys[accessKey] = [];
1734
1761
  }
1735
- if ((0, import_utils12.isBoolean)(value)) {
1762
+ if ((0, import_utils13.isBoolean)(value)) {
1736
1763
  globalPermissionKeys[accessKey].push(schemaKey);
1737
1764
  continue;
1738
1765
  }
@@ -1764,13 +1791,13 @@ var VIRTUAL_UNSUPPORTED_ACCESSES = ["delete", "distinct", "count"];
1764
1791
  var VIRTUAL_RESERVED_NAMES = /* @__PURE__ */ new Set(["_id", "__v", "id"]);
1765
1792
  var VIRTUAL_DANGEROUS_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
1766
1793
  var VIRTUAL_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
1767
- var isVirtualContainerValue2 = (value) => (0, import_utils12.isPlainObject)(value) && "sub" in value;
1794
+ var isVirtualContainerValue2 = (value) => (0, import_utils13.isPlainObject)(value) && "sub" in value;
1768
1795
  var virtualFullPath = (prefix, name) => prefix ? `${prefix}.${name}` : name;
1769
1796
  var virtualPathsOverlap = (virtualPath, permissionField) => {
1770
1797
  if (!virtualPath || !permissionField) return false;
1771
1798
  try {
1772
- if ((0, import_utils12.get)((0, import_utils12.set)({}, virtualPath, true), permissionField) !== void 0) return true;
1773
- if ((0, import_utils12.get)((0, import_utils12.set)({}, permissionField, true), virtualPath) !== void 0) return true;
1799
+ if ((0, import_utils13.get)((0, import_utils13.set)({}, virtualPath, true), permissionField) !== void 0) return true;
1800
+ if ((0, import_utils13.get)((0, import_utils13.set)({}, permissionField, true), virtualPath) !== void 0) return true;
1774
1801
  } catch {
1775
1802
  return false;
1776
1803
  }
@@ -1831,12 +1858,12 @@ var cloneVirtualsForValidation = (value) => {
1831
1858
  };
1832
1859
  var validateVirtualDependsOn = (dependsOn, entryLabel, storedFields, siblingVirtualNames) => {
1833
1860
  if (dependsOn === void 0) return [];
1834
- if (!(0, import_utils12.isArray)(dependsOn)) {
1861
+ if (!(0, import_utils13.isArray)(dependsOn)) {
1835
1862
  throw new Error(`Virtual ${entryLabel}: dependsOn must be an array of top-level persisted field names`);
1836
1863
  }
1837
1864
  const list = dependsOn;
1838
1865
  for (const dep of list) {
1839
- if (!(0, import_utils12.isString)(dep) || dep.length === 0) {
1866
+ if (!(0, import_utils13.isString)(dep) || dep.length === 0) {
1840
1867
  throw new Error(`Virtual ${entryLabel}: dependsOn entries must be non-empty strings`);
1841
1868
  }
1842
1869
  if (dep.includes(".")) {
@@ -1858,12 +1885,12 @@ var validateVirtualDependsOn = (dependsOn, entryLabel, storedFields, siblingVirt
1858
1885
  return list;
1859
1886
  };
1860
1887
  var validateVirtualLeafValue = (value, entryLabel, storedFields, siblingVirtualNames, sharedDependsOn) => {
1861
- if ((0, import_utils12.isFunction)(value)) return;
1862
- if (!(0, import_utils12.isPlainObject)(value)) {
1888
+ if ((0, import_utils13.isFunction)(value)) return;
1889
+ if (!(0, import_utils13.isPlainObject)(value)) {
1863
1890
  throw new Error(`Virtual ${entryLabel}: descriptor must be a getter function or { get, dependsOn }`);
1864
1891
  }
1865
1892
  const record2 = value;
1866
- if (!(0, import_utils12.isFunction)(record2.get)) {
1893
+ if (!(0, import_utils13.isFunction)(record2.get)) {
1867
1894
  throw new Error(`Virtual ${entryLabel}: descriptor.get must be a callable getter function`);
1868
1895
  }
1869
1896
  validateVirtualDependsOn(record2.dependsOn ?? sharedDependsOn, entryLabel, storedFields, siblingVirtualNames);
@@ -1905,7 +1932,7 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
1905
1932
  `Virtual ${scopeLabel}${name}: scope-container must only hold "sub" (embedded container "${name}" is not a virtual-leaf collision)`
1906
1933
  );
1907
1934
  }
1908
- if (!(0, import_utils12.isPlainObject)(record3.sub)) {
1935
+ if (!(0, import_utils13.isPlainObject)(record3.sub)) {
1909
1936
  throw new Error(`Virtual ${scopeLabel}${name}: scope-container "sub" must be a plain object`);
1910
1937
  }
1911
1938
  continue;
@@ -1915,8 +1942,8 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
1915
1942
  `Virtual ${scopeLabel}${name}: collides with a stored path (inspected actual Mongoose schema/child scope; getModelAtt alone is insufficient)`
1916
1943
  );
1917
1944
  }
1918
- if ((0, import_utils12.isFunction)(raw)) continue;
1919
- if (!(0, import_utils12.isPlainObject)(raw)) {
1945
+ if ((0, import_utils13.isFunction)(raw)) continue;
1946
+ if (!(0, import_utils13.isPlainObject)(raw)) {
1920
1947
  throw new Error(
1921
1948
  `Virtual ${scopeLabel}${name}: malformed descriptor (expected getter, { get, dependsOn }, or per-access record)`
1922
1949
  );
@@ -1970,7 +1997,7 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
1970
1997
  };
1971
1998
  var validateVirtualsTree = (model, virtuals, documentPermissionField, modelName) => {
1972
1999
  if (virtuals === void 0 || virtuals === null) return;
1973
- if (!(0, import_utils12.isPlainObject)(virtuals)) {
2000
+ if (!(0, import_utils13.isPlainObject)(virtuals)) {
1974
2001
  throw new Error(`Virtuals for model "${modelName}": virtuals must be a plain object mapping names to descriptors`);
1975
2002
  }
1976
2003
  const rootSchema = model?.schema ?? null;
@@ -2022,8 +2049,8 @@ var AccessRuntime = class {
2022
2049
  {
2023
2050
  requestPermissionField: "_permissions",
2024
2051
  globalPermissions: () => ({}),
2025
- requireRegisteredPopulateModels: true,
2026
- requireReadOperationAccessForPopulateDependencies: true,
2052
+ requireOperationAccessForPopulateQueries: true,
2053
+ requireOperationAccessForPopulateDependencies: true,
2027
2054
  logger: defaultLogger,
2028
2055
  requestComplexity: defaultRequestComplexity
2029
2056
  },
@@ -2078,7 +2105,7 @@ var AccessRuntime = class {
2078
2105
  }
2079
2106
  registerOpenApiRoute(route) {
2080
2107
  this.openApiRegistry.register(
2081
- this.openApiPathPrefix ? { ...route, path: (0, import_utils12.normalizeUrlPath)(`${this.openApiPathPrefix}/${route.path}`) } : route
2108
+ this.openApiPathPrefix ? { ...route, path: (0, import_utils13.normalizeUrlPath)(`${this.openApiPathPrefix}/${route.path}`) } : route
2082
2109
  );
2083
2110
  }
2084
2111
  /**
@@ -2089,7 +2116,7 @@ var AccessRuntime = class {
2089
2116
  */
2090
2117
  withOpenApiPathPrefix(prefix, build) {
2091
2118
  const previous = this.openApiPathPrefix;
2092
- this.openApiPathPrefix = (0, import_utils12.normalizeUrlPath)(`${previous}/${prefix}`);
2119
+ this.openApiPathPrefix = (0, import_utils13.normalizeUrlPath)(`${previous}/${prefix}`);
2093
2120
  try {
2094
2121
  return build();
2095
2122
  } finally {
@@ -2197,13 +2224,15 @@ var AccessRuntime = class {
2197
2224
  /** Shallowly replace supplied global values; nested objects such as requestComplexity are not deep-merged. */
2198
2225
  setGlobalOptions(options) {
2199
2226
  const next = { ...options };
2200
- if ("requireReadOperationAccessForPopulateDependencies" in next)
2201
- next.requireReadOperationAccessForPopulateDependencies = next.requireReadOperationAccessForPopulateDependencies !== false;
2227
+ if ("requireOperationAccessForPopulateQueries" in next)
2228
+ next.requireOperationAccessForPopulateQueries = next.requireOperationAccessForPopulateQueries !== false;
2229
+ if ("requireOperationAccessForPopulateDependencies" in next)
2230
+ next.requireOperationAccessForPopulateDependencies = next.requireOperationAccessForPopulateDependencies !== false;
2202
2231
  this.globalOptions.assign(next);
2203
2232
  }
2204
2233
  setGlobalOption(key, value) {
2205
- if (key === "requireReadOperationAccessForPopulateDependencies") {
2206
- this.globalOptions.set("requireReadOperationAccessForPopulateDependencies", value !== false);
2234
+ if (key === "requireOperationAccessForPopulateQueries" || key === "requireOperationAccessForPopulateDependencies") {
2235
+ this.globalOptions.set(key, value !== false);
2207
2236
  return;
2208
2237
  }
2209
2238
  this.globalOptions.set(key, value);
@@ -2232,7 +2261,7 @@ var AccessRuntime = class {
2232
2261
  if (keyStr === "defaults") assertPublicDefaults(value);
2233
2262
  else if (keyStr.startsWith("defaults.")) {
2234
2263
  const proposed = {};
2235
- (0, import_utils12.set)(proposed, keyStr.slice("defaults.".length), value);
2264
+ (0, import_utils13.set)(proposed, keyStr.slice("defaults.".length), value);
2236
2265
  assertPublicDefaults(proposed);
2237
2266
  }
2238
2267
  this.defaultModelOptions.set(key, value);
@@ -2261,7 +2290,7 @@ var AccessRuntime = class {
2261
2290
  }).onchange("basePath", function(newval, key, target) {
2262
2291
  target[key] = normalizeBasePath(
2263
2292
  modelName,
2264
- (0, import_utils12.isString)(newval) || (0, import_utils12.isNil)(newval) ? newval : void 0
2293
+ (0, import_utils13.isString)(newval) || (0, import_utils13.isNil)(newval) ? newval : void 0
2265
2294
  );
2266
2295
  }).build();
2267
2296
  this.modelJsonSchemas[modelName] = model.jsonSchema();
@@ -2305,7 +2334,7 @@ var AccessRuntime = class {
2305
2334
  if (keyStr === "defaults") assertPublicDefaults(value);
2306
2335
  else if (keyStr.startsWith("defaults.")) {
2307
2336
  const proposed = {};
2308
- (0, import_utils12.set)(proposed, keyStr.slice("defaults.".length), value);
2337
+ (0, import_utils13.set)(proposed, keyStr.slice("defaults.".length), value);
2309
2338
  assertPublicDefaults(proposed);
2310
2339
  }
2311
2340
  const manager = this.modelOptions[modelName];
@@ -2326,15 +2355,15 @@ var AccessRuntime = class {
2326
2355
  const segments = nestedPath.split(".");
2327
2356
  let cursor = cloned;
2328
2357
  for (let i = 0; i < segments.length - 1; i++) {
2329
- if (!(0, import_utils12.isPlainObject)(cursor)) break;
2358
+ if (!(0, import_utils13.isPlainObject)(cursor)) break;
2330
2359
  cursor = cursor[segments[i]];
2331
2360
  }
2332
- if ((0, import_utils12.isPlainObject)(cursor)) {
2361
+ if ((0, import_utils13.isPlainObject)(cursor)) {
2333
2362
  delete cursor[segments[segments.length - 1]];
2334
2363
  }
2335
2364
  proposedVirtuals = cloned;
2336
2365
  } else {
2337
- (0, import_utils12.set)(cloned, nestedPath, value);
2366
+ (0, import_utils13.set)(cloned, nestedPath, value);
2338
2367
  proposedVirtuals = cloned;
2339
2368
  }
2340
2369
  }
@@ -2435,7 +2464,7 @@ var AccessRuntime = class {
2435
2464
  manager.onchange("basePath", function(newval, key, target) {
2436
2465
  target[key] = normalizeBasePath(
2437
2466
  dataName,
2438
- (0, import_utils12.isString)(newval) || (0, import_utils12.isNil)(newval) ? newval : void 0
2467
+ (0, import_utils13.isString)(newval) || (0, import_utils13.isNil)(newval) ? newval : void 0
2439
2468
  );
2440
2469
  }).build();
2441
2470
  return manager;
@@ -2495,20 +2524,20 @@ var AccessRuntime = class {
2495
2524
  const schema = model.schema;
2496
2525
  this.modelRefs[modelName] = buildRefs(schema.tree);
2497
2526
  this.modelSubs[modelName] = buildSubPaths(schema.tree);
2498
- this.modelAtts[modelName] = (0, import_utils12.keys)(schema.obj);
2527
+ this.modelAtts[modelName] = (0, import_utils13.keys)(schema.obj);
2499
2528
  }
2500
2529
  getModelRef(modelName, refPath) {
2501
2530
  this.ensureModelMeta(modelName);
2502
- const value = (0, import_utils12.get)(this.modelRefs, `${modelName}.${refPath}`, null);
2503
- return (0, import_utils12.isString)(value) ? value : null;
2531
+ const value = (0, import_utils13.get)(this.modelRefs, `${modelName}.${refPath}`, null);
2532
+ return (0, import_utils13.isString)(value) ? value : null;
2504
2533
  }
2505
2534
  getModelSub(modelName) {
2506
2535
  this.ensureModelMeta(modelName);
2507
- return (0, import_utils12.get)(this.modelSubs, modelName, []);
2536
+ return (0, import_utils13.get)(this.modelSubs, modelName, []);
2508
2537
  }
2509
2538
  getModelAtt(modelName) {
2510
2539
  this.ensureModelMeta(modelName);
2511
- return (0, import_utils12.get)(this.modelAtts, modelName, []);
2540
+ return (0, import_utils13.get)(this.modelAtts, modelName, []);
2512
2541
  }
2513
2542
  };
2514
2543
  var defaultRuntime = new AccessRuntime({ allowGlobalModelLookup: true });
@@ -2528,7 +2557,7 @@ var getGlobalOption = (key, defaultValue) => {
2528
2557
 
2529
2558
  // src/validation/common.ts
2530
2559
  var import_zod2 = require("zod");
2531
- var import_utils14 = require("@web-ts-toolkit/utils");
2560
+ var import_utils15 = require("@web-ts-toolkit/utils");
2532
2561
 
2533
2562
  // src/validation/public-admission-schema.ts
2534
2563
  var admissions = /* @__PURE__ */ new WeakMap();
@@ -2550,7 +2579,7 @@ function assertTransformedPublicAdmission(schema, value) {
2550
2579
  }
2551
2580
 
2552
2581
  // src/correlated-includes.ts
2553
- var import_utils13 = require("@web-ts-toolkit/utils");
2582
+ var import_utils14 = require("@web-ts-toolkit/utils");
2554
2583
  var PARENT_MARKER_KEY = "$parent";
2555
2584
  var ESCAPE_WRAPPER_KEY = "$escape";
2556
2585
  var SUBQUERY_PAYLOAD_KEYS = /* @__PURE__ */ new Set(["$$sq", "$$date"]);
@@ -2561,10 +2590,10 @@ var FIELD_SEGMENT_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
2561
2590
  var ARRAY_INDEX_SEGMENT_PATTERN = /^(0|[1-9]\d*)$/;
2562
2591
  var ownKeys = (value) => Object.keys(value);
2563
2592
  function isParentRefMarker(value) {
2564
- return (0, import_utils13.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === PARENT_MARKER_KEY;
2593
+ return (0, import_utils14.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === PARENT_MARKER_KEY;
2565
2594
  }
2566
2595
  function isEscapedParentRef(value) {
2567
- return (0, import_utils13.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === ESCAPE_WRAPPER_KEY;
2596
+ return (0, import_utils14.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === ESCAPE_WRAPPER_KEY;
2568
2597
  }
2569
2598
  function hasMarkerKey(value) {
2570
2599
  return ownKeys(value).includes(PARENT_MARKER_KEY) || ownKeys(value).includes(ESCAPE_WRAPPER_KEY);
@@ -2583,12 +2612,12 @@ function containsParentMarkerShape(value) {
2583
2612
  const seen = /* @__PURE__ */ new Set();
2584
2613
  const visit = (current) => {
2585
2614
  if (isParentRefMarker(current) || isEscapedParentRef(current)) return true;
2586
- if ((0, import_utils13.isArray)(current)) {
2615
+ if ((0, import_utils14.isArray)(current)) {
2587
2616
  if (seen.has(current)) return false;
2588
2617
  seen.add(current);
2589
2618
  return current.some(visit);
2590
2619
  }
2591
- if ((0, import_utils13.isPlainObject)(current)) {
2620
+ if ((0, import_utils14.isPlainObject)(current)) {
2592
2621
  if (seen.has(current)) return false;
2593
2622
  seen.add(current);
2594
2623
  if (hasMarkerKey(current)) return true;
@@ -2618,7 +2647,7 @@ function scanTemplateValueNode(value, path, issues) {
2618
2647
  }
2619
2648
  return;
2620
2649
  }
2621
- if ((0, import_utils13.isPlainObject)(value)) {
2650
+ if ((0, import_utils14.isPlainObject)(value)) {
2622
2651
  if (hasMarkerKey(value)) {
2623
2652
  issues.push({
2624
2653
  message: 'Malformed $parent reference: objects carrying $parent must be exactly { "$parent": "<field>" }',
@@ -2629,7 +2658,7 @@ function scanTemplateValueNode(value, path, issues) {
2629
2658
  scanTemplateObjectEntries(value, path, issues);
2630
2659
  return;
2631
2660
  }
2632
- if ((0, import_utils13.isArray)(value)) {
2661
+ if ((0, import_utils14.isArray)(value)) {
2633
2662
  value.forEach((item, index) => scanTemplateValueNode(item, [...path, index], issues));
2634
2663
  }
2635
2664
  }
@@ -2670,7 +2699,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
2670
2699
  continue;
2671
2700
  }
2672
2701
  if (LOGICAL_CLAUSE_KEYS.has(key)) {
2673
- if (!(0, import_utils13.isArray)(child)) {
2702
+ if (!(0, import_utils14.isArray)(child)) {
2674
2703
  scanTemplateValueNode(child, childPath, issues);
2675
2704
  continue;
2676
2705
  }
@@ -2683,7 +2712,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
2683
2712
  });
2684
2713
  return;
2685
2714
  }
2686
- if ((0, import_utils13.isPlainObject)(clause)) {
2715
+ if ((0, import_utils14.isPlainObject)(clause)) {
2687
2716
  scanTemplateObjectEntries(clause, clausePath, issues);
2688
2717
  }
2689
2718
  });
@@ -2694,7 +2723,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
2694
2723
  }
2695
2724
  function validateCorrelatedFilterTemplate(filter) {
2696
2725
  const issues = [];
2697
- if (!(0, import_utils13.isPlainObject)(filter)) {
2726
+ if (!(0, import_utils14.isPlainObject)(filter)) {
2698
2727
  issues.push({ message: "Correlated include filter must be an object", path: [] });
2699
2728
  return issues;
2700
2729
  }
@@ -2822,7 +2851,7 @@ var correlatedFilterSchema = import_zod2.z.record(import_zod2.z.string(), import
2822
2851
  }
2823
2852
  });
2824
2853
  var correlatedEmptyOptionsSchema = import_zod2.z.unknown().refine(
2825
- (value) => value === void 0 || (0, import_utils14.isPlainObject)(value) && Object.keys(value).length === 0,
2854
+ (value) => value === void 0 || (0, import_utils15.isPlainObject)(value) && Object.keys(value).length === 0,
2826
2855
  "Correlated include options must be absent or empty"
2827
2856
  ).optional();
2828
2857
  var correlatedPathSchema = import_zod2.z.string().min(1).superRefine((path, ctx) => {
@@ -2859,7 +2888,7 @@ var correlatedListArgsSchema = import_zod2.z.object({
2859
2888
  include: import_zod2.z.lazy(() => correlatedNestedIncludeSchema).optional()
2860
2889
  }).strict().superRefine((args, ctx) => checkArgsMarkers(args.select, args.sort, ctx));
2861
2890
  var correlatedCountArgsSchema = import_zod2.z.unknown().refine(
2862
- (value) => value === void 0 || (0, import_utils14.isPlainObject)(value) && Object.keys(value).length === 0,
2891
+ (value) => value === void 0 || (0, import_utils15.isPlainObject)(value) && Object.keys(value).length === 0,
2863
2892
  "Count includes accept no args"
2864
2893
  ).optional();
2865
2894
  var correlatedReadByIdSchema = import_zod2.z.object({
@@ -2912,7 +2941,7 @@ var correlatedNestedIncludeSchema = import_zod2.z.union([includeItemSchema, impo
2912
2941
  var rejectDuplicateCorrelatedPaths = (items, ctx) => {
2913
2942
  const seen = /* @__PURE__ */ new Set();
2914
2943
  items.forEach((item, index) => {
2915
- if ((0, import_utils14.isPlainObject)(item) && item.mode === "correlated" && typeof item.path === "string") {
2944
+ if ((0, import_utils15.isPlainObject)(item) && item.mode === "correlated" && typeof item.path === "string") {
2916
2945
  if (seen.has(item.path)) {
2917
2946
  ctx.addIssue({
2918
2947
  code: import_zod2.z.ZodIssueCode.custom,