@web-ts-toolkit/access-router 0.55.0 → 0.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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))
@@ -1544,7 +1563,9 @@ function normalizeSelection(select, catalog, label) {
1544
1563
  includeId: selection.includes("_id")
1545
1564
  };
1546
1565
  }
1547
- function captureVirtualPopulateDependencies(runtime, modelName, options) {
1566
+ function captureVirtualPopulateDependencies(runtime, modelName, options, globalOptions = runtime.getGlobalOptions()) {
1567
+ const requireOperationAccessForPopulateDependencies = globalOptions.requireOperationAccessForPopulateDependencies !== false;
1568
+ const requireOperationAccessForPopulateQueries = globalOptions.requireOperationAccessForPopulateQueries !== false;
1548
1569
  const model = runtime.getModelInstance(modelName);
1549
1570
  const targets = /* @__PURE__ */ new Map();
1550
1571
  const scopes = [];
@@ -1584,15 +1605,23 @@ function captureVirtualPopulateDependencies(runtime, modelName, options) {
1584
1605
  label,
1585
1606
  `target "${ref}" requires a registered same-connection non-discriminator ObjectId model bound to the source ref`
1586
1607
  );
1587
- 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
+ );
1588
1614
  const defaults = runtime.getDefaultModelOptions();
1589
- 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));
1590
1616
  const documentPermissionField = targetOptions.documentPermissionField ?? defaults.documentPermissionField;
1591
1617
  const catalog = captureAuthorizationFieldCatalog(targetModel.schema, void 0, documentPermissionField);
1592
1618
  const configuration = copyAuthorizationValue(
1593
1619
  {
1594
1620
  catalog,
1595
1621
  documentPermissionField,
1622
+ requireOperationAccessForPopulateDependencies,
1623
+ requireOperationAccessForPopulateQueries,
1624
+ permissionSchema: targetOptions.permissionSchema,
1596
1625
  operationAccess: { read: readOption("operationAccess.read") },
1597
1626
  baseFilter: { read: readOption("baseFilter.read") },
1598
1627
  overrideFilter: { read: readOption("overrideFilter.read") },
@@ -1641,13 +1670,13 @@ function captureVirtualPopulateDependencies(runtime, modelName, options) {
1641
1670
  );
1642
1671
  continue;
1643
1672
  }
1644
- if (!(0, import_utils11.isPlainObject)(raw)) continue;
1673
+ if (!(0, import_utils12.isPlainObject)(raw)) continue;
1645
1674
  const entry = raw;
1646
1675
  const label = join(sourcePrefix, name);
1647
1676
  captureList(entry.dependsOnPopulate, label);
1648
1677
  if (!("get" in entry))
1649
1678
  for (const access of accesses) {
1650
- if ((0, import_utils11.isPlainObject)(entry[access]))
1679
+ if ((0, import_utils12.isPlainObject)(entry[access]))
1651
1680
  captureList(entry[access].dependsOnPopulate, `${label}.${access}`);
1652
1681
  }
1653
1682
  const byAccess = {};
@@ -1693,44 +1722,44 @@ var defaultDataOptions = {
1693
1722
  listHardLimit: DEFAULT_LIST_HARD_LIMIT
1694
1723
  };
1695
1724
  var normalizeBasePath = (name, value) => {
1696
- if ((0, import_utils12.isNil)(value)) {
1725
+ if ((0, import_utils13.isNil)(value)) {
1697
1726
  return `/${pluralize(name)}`;
1698
1727
  }
1699
- return (0, import_utils12.isString)(value) ? (0, import_utils12.addLeadingSlash)(value) : "";
1728
+ return (0, import_utils13.isString)(value) ? (0, import_utils13.addLeadingSlash)(value) : "";
1700
1729
  };
1701
1730
  var hasModelPermission = (value, modelPermissionPrefix) => {
1702
1731
  if (!modelPermissionPrefix) {
1703
1732
  return true;
1704
1733
  }
1705
- if ((0, import_utils12.isString)(value)) {
1734
+ if ((0, import_utils13.isString)(value)) {
1706
1735
  return value.trim().split(" ").some((item) => item.startsWith(modelPermissionPrefix));
1707
1736
  }
1708
- if ((0, import_utils12.isArray)(value)) {
1737
+ if ((0, import_utils13.isArray)(value)) {
1709
1738
  return value.some((item) => {
1710
- if ((0, import_utils12.isString)(item) || (0, import_utils12.isArray)(item)) {
1739
+ if ((0, import_utils13.isString)(item) || (0, import_utils13.isArray)(item)) {
1711
1740
  return hasModelPermission(item, modelPermissionPrefix);
1712
1741
  }
1713
1742
  return true;
1714
1743
  });
1715
1744
  }
1716
- return (0, import_utils12.isFunction)(value);
1745
+ return (0, import_utils13.isFunction)(value);
1717
1746
  };
1718
1747
  var classifyPermissionSchema = (permissionSchema, modelPermissionPrefix) => {
1719
1748
  const schemaKeys = Object.keys(permissionSchema);
1720
1749
  const globalPermissionKeys = {};
1721
1750
  const modelPermissionKeys = {};
1722
- (0, import_utils12.forEach)(schemaKeys, (schemaKey) => {
1751
+ (0, import_utils13.forEach)(schemaKeys, (schemaKey) => {
1723
1752
  const schemaRule = permissionSchema[schemaKey];
1724
- 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]);
1725
1754
  for (let x = 0; x < ruleEntries.length; x++) {
1726
1755
  const [accessKey, value] = ruleEntries[x];
1727
- if (!(0, import_utils12.isArray)(globalPermissionKeys[accessKey])) {
1756
+ if (!(0, import_utils13.isArray)(globalPermissionKeys[accessKey])) {
1728
1757
  globalPermissionKeys[accessKey] = [];
1729
1758
  }
1730
- if (!(0, import_utils12.isArray)(modelPermissionKeys[accessKey])) {
1759
+ if (!(0, import_utils13.isArray)(modelPermissionKeys[accessKey])) {
1731
1760
  modelPermissionKeys[accessKey] = [];
1732
1761
  }
1733
- if ((0, import_utils12.isBoolean)(value)) {
1762
+ if ((0, import_utils13.isBoolean)(value)) {
1734
1763
  globalPermissionKeys[accessKey].push(schemaKey);
1735
1764
  continue;
1736
1765
  }
@@ -1762,13 +1791,13 @@ var VIRTUAL_UNSUPPORTED_ACCESSES = ["delete", "distinct", "count"];
1762
1791
  var VIRTUAL_RESERVED_NAMES = /* @__PURE__ */ new Set(["_id", "__v", "id"]);
1763
1792
  var VIRTUAL_DANGEROUS_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
1764
1793
  var VIRTUAL_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
1765
- var isVirtualContainerValue2 = (value) => (0, import_utils12.isPlainObject)(value) && "sub" in value;
1794
+ var isVirtualContainerValue2 = (value) => (0, import_utils13.isPlainObject)(value) && "sub" in value;
1766
1795
  var virtualFullPath = (prefix, name) => prefix ? `${prefix}.${name}` : name;
1767
1796
  var virtualPathsOverlap = (virtualPath, permissionField) => {
1768
1797
  if (!virtualPath || !permissionField) return false;
1769
1798
  try {
1770
- if ((0, import_utils12.get)((0, import_utils12.set)({}, virtualPath, true), permissionField) !== void 0) return true;
1771
- 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;
1772
1801
  } catch {
1773
1802
  return false;
1774
1803
  }
@@ -1829,12 +1858,12 @@ var cloneVirtualsForValidation = (value) => {
1829
1858
  };
1830
1859
  var validateVirtualDependsOn = (dependsOn, entryLabel, storedFields, siblingVirtualNames) => {
1831
1860
  if (dependsOn === void 0) return [];
1832
- if (!(0, import_utils12.isArray)(dependsOn)) {
1861
+ if (!(0, import_utils13.isArray)(dependsOn)) {
1833
1862
  throw new Error(`Virtual ${entryLabel}: dependsOn must be an array of top-level persisted field names`);
1834
1863
  }
1835
1864
  const list = dependsOn;
1836
1865
  for (const dep of list) {
1837
- if (!(0, import_utils12.isString)(dep) || dep.length === 0) {
1866
+ if (!(0, import_utils13.isString)(dep) || dep.length === 0) {
1838
1867
  throw new Error(`Virtual ${entryLabel}: dependsOn entries must be non-empty strings`);
1839
1868
  }
1840
1869
  if (dep.includes(".")) {
@@ -1856,12 +1885,12 @@ var validateVirtualDependsOn = (dependsOn, entryLabel, storedFields, siblingVirt
1856
1885
  return list;
1857
1886
  };
1858
1887
  var validateVirtualLeafValue = (value, entryLabel, storedFields, siblingVirtualNames, sharedDependsOn) => {
1859
- if ((0, import_utils12.isFunction)(value)) return;
1860
- if (!(0, import_utils12.isPlainObject)(value)) {
1888
+ if ((0, import_utils13.isFunction)(value)) return;
1889
+ if (!(0, import_utils13.isPlainObject)(value)) {
1861
1890
  throw new Error(`Virtual ${entryLabel}: descriptor must be a getter function or { get, dependsOn }`);
1862
1891
  }
1863
1892
  const record2 = value;
1864
- if (!(0, import_utils12.isFunction)(record2.get)) {
1893
+ if (!(0, import_utils13.isFunction)(record2.get)) {
1865
1894
  throw new Error(`Virtual ${entryLabel}: descriptor.get must be a callable getter function`);
1866
1895
  }
1867
1896
  validateVirtualDependsOn(record2.dependsOn ?? sharedDependsOn, entryLabel, storedFields, siblingVirtualNames);
@@ -1903,7 +1932,7 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
1903
1932
  `Virtual ${scopeLabel}${name}: scope-container must only hold "sub" (embedded container "${name}" is not a virtual-leaf collision)`
1904
1933
  );
1905
1934
  }
1906
- if (!(0, import_utils12.isPlainObject)(record3.sub)) {
1935
+ if (!(0, import_utils13.isPlainObject)(record3.sub)) {
1907
1936
  throw new Error(`Virtual ${scopeLabel}${name}: scope-container "sub" must be a plain object`);
1908
1937
  }
1909
1938
  continue;
@@ -1913,8 +1942,8 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
1913
1942
  `Virtual ${scopeLabel}${name}: collides with a stored path (inspected actual Mongoose schema/child scope; getModelAtt alone is insufficient)`
1914
1943
  );
1915
1944
  }
1916
- if ((0, import_utils12.isFunction)(raw)) continue;
1917
- if (!(0, import_utils12.isPlainObject)(raw)) {
1945
+ if ((0, import_utils13.isFunction)(raw)) continue;
1946
+ if (!(0, import_utils13.isPlainObject)(raw)) {
1918
1947
  throw new Error(
1919
1948
  `Virtual ${scopeLabel}${name}: malformed descriptor (expected getter, { get, dependsOn }, or per-access record)`
1920
1949
  );
@@ -1968,7 +1997,7 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
1968
1997
  };
1969
1998
  var validateVirtualsTree = (model, virtuals, documentPermissionField, modelName) => {
1970
1999
  if (virtuals === void 0 || virtuals === null) return;
1971
- if (!(0, import_utils12.isPlainObject)(virtuals)) {
2000
+ if (!(0, import_utils13.isPlainObject)(virtuals)) {
1972
2001
  throw new Error(`Virtuals for model "${modelName}": virtuals must be a plain object mapping names to descriptors`);
1973
2002
  }
1974
2003
  const rootSchema = model?.schema ?? null;
@@ -2020,7 +2049,8 @@ var AccessRuntime = class {
2020
2049
  {
2021
2050
  requestPermissionField: "_permissions",
2022
2051
  globalPermissions: () => ({}),
2023
- requireRegisteredPopulateModels: true,
2052
+ requireOperationAccessForPopulateQueries: true,
2053
+ requireOperationAccessForPopulateDependencies: true,
2024
2054
  logger: defaultLogger,
2025
2055
  requestComplexity: defaultRequestComplexity
2026
2056
  },
@@ -2075,7 +2105,7 @@ var AccessRuntime = class {
2075
2105
  }
2076
2106
  registerOpenApiRoute(route) {
2077
2107
  this.openApiRegistry.register(
2078
- 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
2079
2109
  );
2080
2110
  }
2081
2111
  /**
@@ -2086,7 +2116,7 @@ var AccessRuntime = class {
2086
2116
  */
2087
2117
  withOpenApiPathPrefix(prefix, build) {
2088
2118
  const previous = this.openApiPathPrefix;
2089
- this.openApiPathPrefix = (0, import_utils12.normalizeUrlPath)(`${previous}/${prefix}`);
2119
+ this.openApiPathPrefix = (0, import_utils13.normalizeUrlPath)(`${previous}/${prefix}`);
2090
2120
  try {
2091
2121
  return build();
2092
2122
  } finally {
@@ -2193,9 +2223,18 @@ var AccessRuntime = class {
2193
2223
  }
2194
2224
  /** Shallowly replace supplied global values; nested objects such as requestComplexity are not deep-merged. */
2195
2225
  setGlobalOptions(options) {
2196
- this.globalOptions.assign(options);
2226
+ const next = { ...options };
2227
+ if ("requireOperationAccessForPopulateQueries" in next)
2228
+ next.requireOperationAccessForPopulateQueries = next.requireOperationAccessForPopulateQueries !== false;
2229
+ if ("requireOperationAccessForPopulateDependencies" in next)
2230
+ next.requireOperationAccessForPopulateDependencies = next.requireOperationAccessForPopulateDependencies !== false;
2231
+ this.globalOptions.assign(next);
2197
2232
  }
2198
2233
  setGlobalOption(key, value) {
2234
+ if (key === "requireOperationAccessForPopulateQueries" || key === "requireOperationAccessForPopulateDependencies") {
2235
+ this.globalOptions.set(key, value !== false);
2236
+ return;
2237
+ }
2199
2238
  this.globalOptions.set(key, value);
2200
2239
  }
2201
2240
  getGlobalOptions() {
@@ -2222,7 +2261,7 @@ var AccessRuntime = class {
2222
2261
  if (keyStr === "defaults") assertPublicDefaults(value);
2223
2262
  else if (keyStr.startsWith("defaults.")) {
2224
2263
  const proposed = {};
2225
- (0, import_utils12.set)(proposed, keyStr.slice("defaults.".length), value);
2264
+ (0, import_utils13.set)(proposed, keyStr.slice("defaults.".length), value);
2226
2265
  assertPublicDefaults(proposed);
2227
2266
  }
2228
2267
  this.defaultModelOptions.set(key, value);
@@ -2251,7 +2290,7 @@ var AccessRuntime = class {
2251
2290
  }).onchange("basePath", function(newval, key, target) {
2252
2291
  target[key] = normalizeBasePath(
2253
2292
  modelName,
2254
- (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
2255
2294
  );
2256
2295
  }).build();
2257
2296
  this.modelJsonSchemas[modelName] = model.jsonSchema();
@@ -2295,7 +2334,7 @@ var AccessRuntime = class {
2295
2334
  if (keyStr === "defaults") assertPublicDefaults(value);
2296
2335
  else if (keyStr.startsWith("defaults.")) {
2297
2336
  const proposed = {};
2298
- (0, import_utils12.set)(proposed, keyStr.slice("defaults.".length), value);
2337
+ (0, import_utils13.set)(proposed, keyStr.slice("defaults.".length), value);
2299
2338
  assertPublicDefaults(proposed);
2300
2339
  }
2301
2340
  const manager = this.modelOptions[modelName];
@@ -2316,15 +2355,15 @@ var AccessRuntime = class {
2316
2355
  const segments = nestedPath.split(".");
2317
2356
  let cursor = cloned;
2318
2357
  for (let i = 0; i < segments.length - 1; i++) {
2319
- if (!(0, import_utils12.isPlainObject)(cursor)) break;
2358
+ if (!(0, import_utils13.isPlainObject)(cursor)) break;
2320
2359
  cursor = cursor[segments[i]];
2321
2360
  }
2322
- if ((0, import_utils12.isPlainObject)(cursor)) {
2361
+ if ((0, import_utils13.isPlainObject)(cursor)) {
2323
2362
  delete cursor[segments[segments.length - 1]];
2324
2363
  }
2325
2364
  proposedVirtuals = cloned;
2326
2365
  } else {
2327
- (0, import_utils12.set)(cloned, nestedPath, value);
2366
+ (0, import_utils13.set)(cloned, nestedPath, value);
2328
2367
  proposedVirtuals = cloned;
2329
2368
  }
2330
2369
  }
@@ -2425,7 +2464,7 @@ var AccessRuntime = class {
2425
2464
  manager.onchange("basePath", function(newval, key, target) {
2426
2465
  target[key] = normalizeBasePath(
2427
2466
  dataName,
2428
- (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
2429
2468
  );
2430
2469
  }).build();
2431
2470
  return manager;
@@ -2485,20 +2524,20 @@ var AccessRuntime = class {
2485
2524
  const schema = model.schema;
2486
2525
  this.modelRefs[modelName] = buildRefs(schema.tree);
2487
2526
  this.modelSubs[modelName] = buildSubPaths(schema.tree);
2488
- this.modelAtts[modelName] = (0, import_utils12.keys)(schema.obj);
2527
+ this.modelAtts[modelName] = (0, import_utils13.keys)(schema.obj);
2489
2528
  }
2490
2529
  getModelRef(modelName, refPath) {
2491
2530
  this.ensureModelMeta(modelName);
2492
- const value = (0, import_utils12.get)(this.modelRefs, `${modelName}.${refPath}`, null);
2493
- 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;
2494
2533
  }
2495
2534
  getModelSub(modelName) {
2496
2535
  this.ensureModelMeta(modelName);
2497
- return (0, import_utils12.get)(this.modelSubs, modelName, []);
2536
+ return (0, import_utils13.get)(this.modelSubs, modelName, []);
2498
2537
  }
2499
2538
  getModelAtt(modelName) {
2500
2539
  this.ensureModelMeta(modelName);
2501
- return (0, import_utils12.get)(this.modelAtts, modelName, []);
2540
+ return (0, import_utils13.get)(this.modelAtts, modelName, []);
2502
2541
  }
2503
2542
  };
2504
2543
  var defaultRuntime = new AccessRuntime({ allowGlobalModelLookup: true });
@@ -2518,7 +2557,7 @@ var getGlobalOption = (key, defaultValue) => {
2518
2557
 
2519
2558
  // src/validation/common.ts
2520
2559
  var import_zod2 = require("zod");
2521
- var import_utils14 = require("@web-ts-toolkit/utils");
2560
+ var import_utils15 = require("@web-ts-toolkit/utils");
2522
2561
 
2523
2562
  // src/validation/public-admission-schema.ts
2524
2563
  var admissions = /* @__PURE__ */ new WeakMap();
@@ -2540,7 +2579,7 @@ function assertTransformedPublicAdmission(schema, value) {
2540
2579
  }
2541
2580
 
2542
2581
  // src/correlated-includes.ts
2543
- var import_utils13 = require("@web-ts-toolkit/utils");
2582
+ var import_utils14 = require("@web-ts-toolkit/utils");
2544
2583
  var PARENT_MARKER_KEY = "$parent";
2545
2584
  var ESCAPE_WRAPPER_KEY = "$escape";
2546
2585
  var SUBQUERY_PAYLOAD_KEYS = /* @__PURE__ */ new Set(["$$sq", "$$date"]);
@@ -2551,10 +2590,10 @@ var FIELD_SEGMENT_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
2551
2590
  var ARRAY_INDEX_SEGMENT_PATTERN = /^(0|[1-9]\d*)$/;
2552
2591
  var ownKeys = (value) => Object.keys(value);
2553
2592
  function isParentRefMarker(value) {
2554
- 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;
2555
2594
  }
2556
2595
  function isEscapedParentRef(value) {
2557
- 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;
2558
2597
  }
2559
2598
  function hasMarkerKey(value) {
2560
2599
  return ownKeys(value).includes(PARENT_MARKER_KEY) || ownKeys(value).includes(ESCAPE_WRAPPER_KEY);
@@ -2573,12 +2612,12 @@ function containsParentMarkerShape(value) {
2573
2612
  const seen = /* @__PURE__ */ new Set();
2574
2613
  const visit = (current) => {
2575
2614
  if (isParentRefMarker(current) || isEscapedParentRef(current)) return true;
2576
- if ((0, import_utils13.isArray)(current)) {
2615
+ if ((0, import_utils14.isArray)(current)) {
2577
2616
  if (seen.has(current)) return false;
2578
2617
  seen.add(current);
2579
2618
  return current.some(visit);
2580
2619
  }
2581
- if ((0, import_utils13.isPlainObject)(current)) {
2620
+ if ((0, import_utils14.isPlainObject)(current)) {
2582
2621
  if (seen.has(current)) return false;
2583
2622
  seen.add(current);
2584
2623
  if (hasMarkerKey(current)) return true;
@@ -2608,7 +2647,7 @@ function scanTemplateValueNode(value, path, issues) {
2608
2647
  }
2609
2648
  return;
2610
2649
  }
2611
- if ((0, import_utils13.isPlainObject)(value)) {
2650
+ if ((0, import_utils14.isPlainObject)(value)) {
2612
2651
  if (hasMarkerKey(value)) {
2613
2652
  issues.push({
2614
2653
  message: 'Malformed $parent reference: objects carrying $parent must be exactly { "$parent": "<field>" }',
@@ -2619,7 +2658,7 @@ function scanTemplateValueNode(value, path, issues) {
2619
2658
  scanTemplateObjectEntries(value, path, issues);
2620
2659
  return;
2621
2660
  }
2622
- if ((0, import_utils13.isArray)(value)) {
2661
+ if ((0, import_utils14.isArray)(value)) {
2623
2662
  value.forEach((item, index) => scanTemplateValueNode(item, [...path, index], issues));
2624
2663
  }
2625
2664
  }
@@ -2660,7 +2699,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
2660
2699
  continue;
2661
2700
  }
2662
2701
  if (LOGICAL_CLAUSE_KEYS.has(key)) {
2663
- if (!(0, import_utils13.isArray)(child)) {
2702
+ if (!(0, import_utils14.isArray)(child)) {
2664
2703
  scanTemplateValueNode(child, childPath, issues);
2665
2704
  continue;
2666
2705
  }
@@ -2673,7 +2712,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
2673
2712
  });
2674
2713
  return;
2675
2714
  }
2676
- if ((0, import_utils13.isPlainObject)(clause)) {
2715
+ if ((0, import_utils14.isPlainObject)(clause)) {
2677
2716
  scanTemplateObjectEntries(clause, clausePath, issues);
2678
2717
  }
2679
2718
  });
@@ -2684,7 +2723,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
2684
2723
  }
2685
2724
  function validateCorrelatedFilterTemplate(filter) {
2686
2725
  const issues = [];
2687
- if (!(0, import_utils13.isPlainObject)(filter)) {
2726
+ if (!(0, import_utils14.isPlainObject)(filter)) {
2688
2727
  issues.push({ message: "Correlated include filter must be an object", path: [] });
2689
2728
  return issues;
2690
2729
  }
@@ -2812,7 +2851,7 @@ var correlatedFilterSchema = import_zod2.z.record(import_zod2.z.string(), import
2812
2851
  }
2813
2852
  });
2814
2853
  var correlatedEmptyOptionsSchema = import_zod2.z.unknown().refine(
2815
- (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,
2816
2855
  "Correlated include options must be absent or empty"
2817
2856
  ).optional();
2818
2857
  var correlatedPathSchema = import_zod2.z.string().min(1).superRefine((path, ctx) => {
@@ -2849,7 +2888,7 @@ var correlatedListArgsSchema = import_zod2.z.object({
2849
2888
  include: import_zod2.z.lazy(() => correlatedNestedIncludeSchema).optional()
2850
2889
  }).strict().superRefine((args, ctx) => checkArgsMarkers(args.select, args.sort, ctx));
2851
2890
  var correlatedCountArgsSchema = import_zod2.z.unknown().refine(
2852
- (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,
2853
2892
  "Count includes accept no args"
2854
2893
  ).optional();
2855
2894
  var correlatedReadByIdSchema = import_zod2.z.object({
@@ -2902,7 +2941,7 @@ var correlatedNestedIncludeSchema = import_zod2.z.union([includeItemSchema, impo
2902
2941
  var rejectDuplicateCorrelatedPaths = (items, ctx) => {
2903
2942
  const seen = /* @__PURE__ */ new Set();
2904
2943
  items.forEach((item, index) => {
2905
- 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") {
2906
2945
  if (seen.has(item.path)) {
2907
2946
  ctx.addIssue({
2908
2947
  code: import_zod2.z.ZodIssueCode.custom,