@web-ts-toolkit/access-router 0.51.0 → 0.53.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
@@ -123,15 +123,147 @@ var FilterOperator = /* @__PURE__ */ ((FilterOperator2) => {
123
123
  })(FilterOperator || {});
124
124
 
125
125
  // src/validation/parsers.ts
126
- var import_express_json_router = __toESM(require("@web-ts-toolkit/express-json-router"));
126
+ var import_express_json_router2 = __toESM(require("@web-ts-toolkit/express-json-router"));
127
127
 
128
128
  // src/runtime.ts
129
129
  var import_mongoose2 = __toESM(require("mongoose"));
130
+
131
+ // src/validation/public-admission.ts
132
+ var import_express_json_router = __toESM(require("@web-ts-toolkit/express-json-router"));
133
+ var import_utils = require("@web-ts-toolkit/utils");
134
+ var privateControls = [
135
+ "authorization",
136
+ "overrides",
137
+ "documentAuthorization",
138
+ "documentAuthorizationStage",
139
+ "execution",
140
+ "executionContext",
141
+ "serviceExecutionContext",
142
+ "resolvedAuthorization",
143
+ "preparedQuery",
144
+ "preparedFilter",
145
+ "preparedModelQuery",
146
+ "resolvedIdentifier",
147
+ "skipParsing",
148
+ "skipAuthorization",
149
+ "alreadyAuthorized",
150
+ "operation"
151
+ ];
152
+ var PublicAdmissionError = class extends import_express_json_router.default.clientErrors.BadRequestError {
153
+ constructor(detail) {
154
+ const errors = [{ detail }];
155
+ super("Bad Request", { errors });
156
+ this.result = { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors };
157
+ }
158
+ };
159
+ function assertPublicAdmission(input, kind = "envelope") {
160
+ const pending = [{ value: input, kind, path: "request" }];
161
+ const seen = /* @__PURE__ */ new WeakMap();
162
+ while (pending.length) {
163
+ const { value, kind: slot, path } = pending.pop();
164
+ if (!value || typeof value !== "object" && typeof value !== "function") continue;
165
+ const kinds = seen.get(value) ?? /* @__PURE__ */ new Set();
166
+ if (kinds.has(slot)) continue;
167
+ kinds.add(slot);
168
+ seen.set(value, kinds);
169
+ const add = (child, childKind, key) => {
170
+ pending.push({ value: child, kind: childKind, path: `${path}.${key}` });
171
+ };
172
+ const record = value;
173
+ if (slot !== "data") {
174
+ for (const key of privateControls) {
175
+ if (key in record) {
176
+ throw new PublicAdmissionError(
177
+ `Unsupported public control ${path}.${key}; use explicit per-call internal service options for backend authorization`
178
+ );
179
+ }
180
+ }
181
+ }
182
+ if (Array.isArray(value)) {
183
+ value.forEach((child, index) => add(child, slot, String(index)));
184
+ continue;
185
+ }
186
+ if (slot === "data") {
187
+ if (!(0, import_utils.isPlainObject)(value)) continue;
188
+ for (const [key, child] of Object.entries(value)) add(child, key === "$$sq" ? "envelope" : "data", key);
189
+ continue;
190
+ }
191
+ for (const key of ["args", "options", "sqOptions"]) add(record[key], "envelope", key);
192
+ add(record.include, "include", "include");
193
+ add(record.populate, "populate", "populate");
194
+ for (const key of ["filter", "match", "data"]) add(record[key], "data", key);
195
+ }
196
+ }
197
+ function assertHydrationDefaults(defaults) {
198
+ if (defaults && typeof defaults === "object") {
199
+ const record = defaults;
200
+ if ("hydration" in record)
201
+ throw new TypeError("defaults.hydration is unsupported; use model hydration configuration");
202
+ for (const bucket of [
203
+ "publicListOptions",
204
+ "publicReadOptions",
205
+ "findOptions",
206
+ "findOneOptions",
207
+ "findByIdOptions",
208
+ "createOptions",
209
+ "updateOneOptions",
210
+ "updateByIdOptions",
211
+ "upsertOptions",
212
+ "existsOptions",
213
+ "publicCreateOptions",
214
+ "publicUpdateOptions"
215
+ ]) {
216
+ const options = record[bucket];
217
+ if (!options || typeof options !== "object" && typeof options !== "function") continue;
218
+ for (const key of ["lean", "hydration"]) {
219
+ if (!(key in options)) continue;
220
+ const method = bucket.slice(0, -"Options".length);
221
+ const migration = ["publicList", "publicRead", "find", "findOne", "findById"].includes(method) ? `use model hydration.${method} ('lean' or 'hydrated')` : "this method has a fixed fetch mode";
222
+ throw new TypeError(`defaults.${bucket}.${key} is unsupported; ${migration}`);
223
+ }
224
+ }
225
+ }
226
+ }
227
+ function assertPublicDefaults(defaults) {
228
+ assertHydrationDefaults(defaults);
229
+ assertPublicAdmission(defaults);
230
+ if (defaults && typeof defaults === "object") {
231
+ for (const value of Object.values(defaults)) assertPublicAdmission(value);
232
+ }
233
+ }
234
+ var requestAuthorization = Object.freeze({ outputFields: Object.freeze({ mode: "request" }) });
235
+
236
+ // src/options/hydration.ts
237
+ var methods = ["publicList", "publicRead", "find", "findOne", "findById"];
238
+ function normalizeHydration(value, path = "hydration") {
239
+ if (value === void 0) return void 0;
240
+ if (value === null || typeof value !== "object" || ![Object.prototype, null].includes(Object.getPrototypeOf(value)))
241
+ throw new TypeError(`${path} must be a plain record of model hydration modes`);
242
+ const result = {};
243
+ for (const key of Reflect.ownKeys(value)) {
244
+ if (typeof key !== "string" || !methods.includes(key))
245
+ throw new TypeError(`${path}.${String(key)} is not a supported hydration method`);
246
+ const mode = value[key];
247
+ if (mode !== void 0 && mode !== "lean" && mode !== "hydrated")
248
+ throw new TypeError(`${path}.${key} must be 'lean', 'hydrated', or undefined`);
249
+ result[key] = mode;
250
+ }
251
+ return Object.freeze(result);
252
+ }
253
+ function normalizeHydrationUpdate(current, key, value) {
254
+ if (key === "hydration") return normalizeHydration(value);
255
+ const method = key.slice("hydration.".length);
256
+ if (!methods.includes(method))
257
+ throw new TypeError(`${key} is not a supported hydration method`);
258
+ return normalizeHydration({ ...normalizeHydration(current), [method]: value });
259
+ }
260
+
261
+ // src/runtime.ts
130
262
  var import_mongoose_schema_jsonschema = __toESM(require("mongoose-schema-jsonschema"));
131
- var import_utils8 = require("@web-ts-toolkit/utils");
263
+ var import_utils10 = require("@web-ts-toolkit/utils");
132
264
 
133
265
  // src/helpers/query.ts
134
- var import_utils = require("@web-ts-toolkit/utils");
266
+ var import_utils2 = require("@web-ts-toolkit/utils");
135
267
  var DEFAULT_LIST_HARD_LIMIT = 1e3;
136
268
 
137
269
  // src/helpers/sort-policy.ts
@@ -141,44 +273,44 @@ function isValidFieldPath(field) {
141
273
  }
142
274
 
143
275
  // src/helpers/index.ts
144
- var import_utils3 = require("@web-ts-toolkit/utils");
276
+ var import_utils4 = require("@web-ts-toolkit/utils");
145
277
 
146
278
  // src/lib.ts
147
279
  var import_mongoose = require("mongoose");
148
- var import_utils2 = require("@web-ts-toolkit/utils");
280
+ var import_utils3 = require("@web-ts-toolkit/utils");
149
281
  var isSchema = (val) => val instanceof import_mongoose.Schema;
150
282
  var isObjectIdType = (val) => val === "ObjectId" || val === import_mongoose.Schema.Types.ObjectId;
151
- var isReference = (val) => (0, import_utils2.isPlainObject)(val) && !!val.ref && isObjectIdType(val.type);
283
+ var isReference = (val) => (0, import_utils3.isPlainObject)(val) && !!val.ref && isObjectIdType(val.type);
152
284
 
153
285
  // src/helpers/index.ts
154
286
  function recurseObject(obj) {
155
287
  if (isSchema(obj)) {
156
288
  return buildRefs(obj.tree);
157
289
  }
158
- if (!(0, import_utils3.isObject)(obj)) return null;
290
+ if (!(0, import_utils4.isObject)(obj)) return null;
159
291
  if (isReference(obj)) {
160
292
  return obj.ref;
161
293
  }
162
294
  let ret = null;
163
- (0, import_utils3.forEach)(obj, (val) => {
295
+ (0, import_utils4.forEach)(obj, (val) => {
164
296
  ret = recurseObject(val);
165
- if (!(0, import_utils3.isEmpty)(ret)) {
297
+ if (!(0, import_utils4.isEmpty)(ret)) {
166
298
  return false;
167
299
  }
168
300
  });
169
301
  return ret;
170
302
  }
171
303
  function buildRefs(schema) {
172
- if (!(0, import_utils3.isObject)(schema)) return {};
304
+ if (!(0, import_utils4.isObject)(schema)) return {};
173
305
  const references = {};
174
- (0, import_utils3.forEach)(schema, (val, key) => {
306
+ (0, import_utils4.forEach)(schema, (val, key) => {
175
307
  const paths = recurseObject(val);
176
- if (!(0, import_utils3.isEmpty)(paths)) {
308
+ if (!(0, import_utils4.isEmpty)(paths)) {
177
309
  references[key] = paths;
178
310
  }
179
- const target = (0, import_utils3.isObject)(val) && "type" in val ? val.type ?? val : val;
180
- if ((0, import_utils3.isArray)(target) && target.length > 0) {
181
- if (isSchema(target[0]) || (0, import_utils3.isPlainObject)(target[0])) {
311
+ const target = (0, import_utils4.isObject)(val) && "type" in val ? val.type ?? val : val;
312
+ if ((0, import_utils4.isArray)(target) && target.length > 0) {
313
+ if (isSchema(target[0]) || (0, import_utils4.isPlainObject)(target[0])) {
182
314
  return;
183
315
  }
184
316
  }
@@ -186,12 +318,12 @@ function buildRefs(schema) {
186
318
  return references;
187
319
  }
188
320
  function buildSubPaths(schema) {
189
- if (!(0, import_utils3.isObject)(schema)) return [];
321
+ if (!(0, import_utils4.isObject)(schema)) return [];
190
322
  const subPaths = [];
191
- (0, import_utils3.forEach)(schema, (val, key) => {
192
- const target = (0, import_utils3.isObject)(val) && "type" in val ? val.type ?? val : val;
193
- if ((0, import_utils3.isArray)(target) && target.length > 0) {
194
- if (isSchema(target[0]) || (0, import_utils3.isPlainObject)(target[0]) && !isReference(target[0])) {
323
+ (0, import_utils4.forEach)(schema, (val, key) => {
324
+ const target = (0, import_utils4.isObject)(val) && "type" in val ? val.type ?? val : val;
325
+ if ((0, import_utils4.isArray)(target) && target.length > 0) {
326
+ if (isSchema(target[0]) || (0, import_utils4.isPlainObject)(target[0]) && !isReference(target[0])) {
195
327
  subPaths.push(key);
196
328
  }
197
329
  }
@@ -200,7 +332,7 @@ function buildSubPaths(schema) {
200
332
  }
201
333
 
202
334
  // src/openapi/build-spec.ts
203
- var import_utils5 = require("@web-ts-toolkit/utils");
335
+ var import_utils6 = require("@web-ts-toolkit/utils");
204
336
 
205
337
  // src/openapi/responses.ts
206
338
  var json = (schema) => ({
@@ -271,19 +403,19 @@ var openApiResponses = {
271
403
 
272
404
  // src/openapi/schemas.ts
273
405
  var import_zod = require("zod");
274
- var import_utils4 = require("@web-ts-toolkit/utils");
406
+ var import_utils5 = require("@web-ts-toolkit/utils");
275
407
  var fallbackObjectSchema = { type: "object", additionalProperties: true };
276
408
  function isOpenApiSchemaPatch(source) {
277
- return (0, import_utils4.isPlainObject)(source) && source.kind === "objectProperties";
409
+ return (0, import_utils5.isPlainObject)(source) && source.kind === "objectProperties";
278
410
  }
279
411
  function isOpenApiSchemaResolver(source) {
280
- return (0, import_utils4.isPlainObject)(source) && source.kind === "schemaResolver" && typeof source.resolve === "function";
412
+ return (0, import_utils5.isPlainObject)(source) && source.kind === "schemaResolver" && typeof source.resolve === "function";
281
413
  }
282
414
  function isJsonSchemaLike(source) {
283
- return (0, import_utils4.isPlainObject)(source) && ("type" in source || "properties" in source || "$ref" in source || "anyOf" in source);
415
+ return (0, import_utils5.isPlainObject)(source) && ("type" in source || "properties" in source || "$ref" in source || "anyOf" in source);
284
416
  }
285
417
  function hasOpenApiSchema(source) {
286
- return (0, import_utils4.isPlainObject)(source) && isJsonSchemaLike(source.openapi);
418
+ return (0, import_utils5.isPlainObject)(source) && isJsonSchemaLike(source.openapi);
287
419
  }
288
420
  function toOpenApiSchema(source) {
289
421
  if (!source) return void 0;
@@ -291,7 +423,7 @@ function toOpenApiSchema(source) {
291
423
  if (!resolvedSource) return void 0;
292
424
  if (isOpenApiSchemaPatch(resolvedSource)) {
293
425
  const schema = toOpenApiSchema(resolvedSource.source) ?? { ...fallbackObjectSchema };
294
- const properties = (0, import_utils4.isPlainObject)(schema.properties) ? { ...schema.properties } : {};
426
+ const properties = (0, import_utils5.isPlainObject)(schema.properties) ? { ...schema.properties } : {};
295
427
  for (const [key, value] of Object.entries(resolvedSource.properties)) {
296
428
  properties[key] = toOpenApiSchema(value) ?? fallbackObjectSchema;
297
429
  }
@@ -324,9 +456,9 @@ var toOpenApiPath = (path) => normalizePath(path).replace(/:([A-Za-z0-9_]+)/g, "
324
456
  var schemaToQueryParameters = (schema) => {
325
457
  const jsonSchema = toOpenApiSchema(schema);
326
458
  if (!jsonSchema || jsonSchema.type !== "object") return [];
327
- const properties = (0, import_utils5.isPlainObject)(jsonSchema.properties) ? jsonSchema.properties : {};
459
+ const properties = (0, import_utils6.isPlainObject)(jsonSchema.properties) ? jsonSchema.properties : {};
328
460
  const required = new Set(
329
- (0, import_utils5.isArray)(jsonSchema.required) ? jsonSchema.required.filter((item) => typeof item === "string") : []
461
+ (0, import_utils6.isArray)(jsonSchema.required) ? jsonSchema.required.filter((item) => typeof item === "string") : []
330
462
  );
331
463
  return Object.entries(properties).map(([name, value]) => ({
332
464
  name,
@@ -417,7 +549,7 @@ var OpenApiCollisionError = class extends Error {
417
549
  };
418
550
 
419
551
  // src/openapi/registry.ts
420
- var isPlainObject6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
552
+ var isPlainObject7 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
421
553
  var stableKey = (value) => {
422
554
  if (value === null || typeof value === "undefined") return "null";
423
555
  if (typeof value === "function") return "[Function]";
@@ -452,7 +584,7 @@ var OpenApiRegistry = class {
452
584
  this.routes[existingIndex] = route;
453
585
  return;
454
586
  }
455
- if (descriptorsEqual(existing, route) && (route.idempotent || isPlainObject6(existing) && existing.idempotent)) {
587
+ if (descriptorsEqual(existing, route) && (route.idempotent || isPlainObject7(existing) && existing.idempotent)) {
456
588
  return;
457
589
  }
458
590
  if (this.options.rejectConflicts) {
@@ -541,7 +673,7 @@ var defaultLogger = (0, import_winston.createLogger)({
541
673
  });
542
674
 
543
675
  // src/options/manager.ts
544
- var import_utils6 = require("@web-ts-toolkit/utils");
676
+ var import_utils7 = require("@web-ts-toolkit/utils");
545
677
  var toPath = (key) => {
546
678
  if (Array.isArray(key)) return key;
547
679
  return typeof key === "string" ? key.split(".") : [key];
@@ -602,19 +734,20 @@ var freezeConfigValue = (value) => {
602
734
  return value;
603
735
  };
604
736
  var cloneAndFreezeForStore = (value) => freezeConfigValue(cloneForRead(value));
605
- var getNestedOption = (manager, key, defaultValue) => {
606
- const keys2 = String(key).split(".");
737
+ var getNestedOption = (manager, key, defaultValue) => resolveNestedOption((path, fallback) => manager.get(path, fallback), String(key), defaultValue);
738
+ var resolveNestedOption = (read, key, defaultValue) => {
739
+ const keys2 = key.split(".");
607
740
  if (keys2.length === 1) {
608
- return manager.get(key, defaultValue);
741
+ return read(key, defaultValue);
609
742
  }
610
- let option = manager.get(key, void 0);
743
+ let option = read(key);
611
744
  if (option !== void 0) {
612
745
  return option;
613
746
  }
614
747
  const parentKey = keys2.slice(0, -1).join(".");
615
- option = manager.get(`${parentKey}.default`, void 0);
748
+ option = read(`${parentKey}.default`);
616
749
  if (option === void 0) {
617
- option = manager.get(parentKey, defaultValue);
750
+ option = read(parentKey, defaultValue);
618
751
  }
619
752
  return option;
620
753
  };
@@ -647,20 +780,20 @@ var OptionsManager = class {
647
780
  return this;
648
781
  }
649
782
  get(key, defaultValue) {
650
- return (0, import_utils6.get)(this.currentOptions, key, defaultValue);
783
+ return (0, import_utils7.get)(this.currentOptions, key, defaultValue);
651
784
  }
652
785
  set(key, value) {
653
786
  const path = toPath(key);
654
787
  if (path.length <= 1) {
655
- (0, import_utils6.set)(this.currentOptions, path, this.preserveKeys.has(String(path[0])) ? value : cloneAndFreezeForStore(value));
788
+ (0, import_utils7.set)(this.currentOptions, path, this.preserveKeys.has(String(path[0])) ? value : cloneAndFreezeForStore(value));
656
789
  return;
657
790
  }
658
791
  const [rootKey, ...nestedPath] = path;
659
- const currentRoot = (0, import_utils6.get)(this.currentOptions, [rootKey], void 0);
660
- const baseRoot = (0, import_utils6.isPlainObject)(currentRoot) ? currentRoot : {};
792
+ const currentRoot = (0, import_utils7.get)(this.currentOptions, [rootKey], void 0);
793
+ const baseRoot = (0, import_utils7.isPlainObject)(currentRoot) ? currentRoot : {};
661
794
  const nextRoot = cloneConfigValue(baseRoot);
662
- (0, import_utils6.set)(nextRoot, nestedPath, cloneForRead(value));
663
- (0, import_utils6.set)(this.currentOptions, [rootKey], freezeConfigValue(nextRoot));
795
+ (0, import_utils7.set)(nextRoot, nestedPath, cloneForRead(value));
796
+ (0, import_utils7.set)(this.currentOptions, [rootKey], freezeConfigValue(nextRoot));
664
797
  }
665
798
  fetch() {
666
799
  const cloned = cloneForRead(this.currentOptions);
@@ -678,10 +811,10 @@ var OptionsManager = class {
678
811
  cloned[key] = options[key];
679
812
  }
680
813
  }
681
- (0, import_utils6.assign)(this.currentOptions, freezeConfigValue(cloned));
814
+ (0, import_utils7.assign)(this.currentOptions, freezeConfigValue(cloned));
682
815
  }
683
816
  onchange(key, func) {
684
- (0, import_utils6.set)(this.listeners, key, func);
817
+ (0, import_utils7.set)(this.listeners, key, func);
685
818
  return this;
686
819
  }
687
820
  snapshot() {
@@ -707,12 +840,230 @@ var OptionsManager = class {
707
840
  cloned[key] = snap[key];
708
841
  }
709
842
  }
710
- (0, import_utils6.assign)(current, freezeConfigValue(cloned));
843
+ (0, import_utils7.assign)(current, freezeConfigValue(cloned));
844
+ }
845
+ };
846
+
847
+ // src/options/data-manager.ts
848
+ var import_utils8 = require("@web-ts-toolkit/utils");
849
+
850
+ // src/options/data-values.ts
851
+ var import_node_util2 = require("util");
852
+ var typedArrays = [
853
+ Int8Array,
854
+ Uint8Array,
855
+ Uint8ClampedArray,
856
+ Int16Array,
857
+ Uint16Array,
858
+ Int32Array,
859
+ Uint32Array,
860
+ Float32Array,
861
+ Float64Array,
862
+ BigInt64Array,
863
+ BigUint64Array
864
+ ];
865
+ var unsupported = (path, reason) => {
866
+ throw new TypeError(`Unsupported data value at ${path}: ${reason}`);
867
+ };
868
+ var isPlainContainer = (value) => {
869
+ const prototype = Object.getPrototypeOf(value);
870
+ return prototype === Object.prototype || prototype === null || prototype === Array.prototype;
871
+ };
872
+ var defineValue = (target, key, value) => {
873
+ Object.defineProperty(target, key, { value, enumerable: true, configurable: true, writable: true });
874
+ };
875
+ var assertNativeProperties = (value, path, allowed = () => false) => {
876
+ for (const key of Reflect.ownKeys(value)) {
877
+ if (typeof key !== "string" || !allowed(key)) unsupported(path, "custom native properties are not supported");
878
+ }
879
+ };
880
+ var copyBytes = (buffer, path, start = 0, end) => {
881
+ if (!import_node_util2.types.isArrayBuffer(buffer) || Object.getPrototypeOf(buffer) !== ArrayBuffer.prototype) {
882
+ return unsupported(path, "binary storage must be a fixed, non-shared ArrayBuffer");
883
+ }
884
+ assertNativeProperties(buffer, path);
885
+ if (buffer.resizable) {
886
+ return unsupported(path, "resizable binary storage is not supported");
887
+ }
888
+ try {
889
+ return ArrayBuffer.prototype.slice.call(buffer, start, end);
890
+ } catch {
891
+ return unsupported(path, "detached binary storage is not supported");
892
+ }
893
+ };
894
+ function copyValue(input, freezePlain, rootPath) {
895
+ const copies = /* @__PURE__ */ new WeakMap();
896
+ const active = /* @__PURE__ */ new WeakSet();
897
+ const visit = (value, path) => {
898
+ if (typeof value === "function" || typeof value === "symbol") {
899
+ return unsupported(path, `${typeof value} values are not supported`);
900
+ }
901
+ if (value === null || typeof value !== "object") return value;
902
+ if (import_node_util2.types.isProxy(value)) return unsupported(path, "proxies are not supported");
903
+ if (active.has(value)) return unsupported(path, "cycles are not supported");
904
+ const previous = copies.get(value);
905
+ if (previous) return previous;
906
+ active.add(value);
907
+ try {
908
+ const prototype = Object.getPrototypeOf(value);
909
+ if (isPlainContainer(value)) {
910
+ const array = Array.isArray(value);
911
+ if (array && prototype !== Array.prototype) return unsupported(path, "unsupported array prototype");
912
+ if (prototype === Array.prototype && !array) return unsupported(path, "unsupported object prototype");
913
+ if (Object.getOwnPropertySymbols(value).length) return unsupported(path, "symbol keys are not supported");
914
+ const output2 = array ? new Array(value.length) : Object.create(prototype);
915
+ copies.set(value, output2);
916
+ for (const key of Object.keys(value)) {
917
+ const childPath = array ? `${path}[${key}]` : `${path}.${key}`;
918
+ defineValue(output2, key, visit(value[key], childPath));
919
+ }
920
+ return freezePlain ? Object.freeze(output2) : output2;
921
+ }
922
+ let output;
923
+ if (prototype === Date.prototype && import_node_util2.types.isDate(value)) {
924
+ assertNativeProperties(value, path);
925
+ output = new Date(Date.prototype.getTime.call(value));
926
+ } else if (prototype === Map.prototype && import_node_util2.types.isMap(value)) {
927
+ assertNativeProperties(value, path);
928
+ const map = /* @__PURE__ */ new Map();
929
+ copies.set(value, map);
930
+ let index = 0;
931
+ for (const [key, entry] of Map.prototype.entries.call(value)) {
932
+ map.set(visit(key, `${path}.<key:${index}>`), visit(entry, `${path}.<value:${index}>`));
933
+ index += 1;
934
+ }
935
+ output = map;
936
+ } else if (prototype === Set.prototype && import_node_util2.types.isSet(value)) {
937
+ assertNativeProperties(value, path);
938
+ const set4 = /* @__PURE__ */ new Set();
939
+ copies.set(value, set4);
940
+ let index = 0;
941
+ for (const entry of Set.prototype.values.call(value)) {
942
+ set4.add(visit(entry, `${path}.<entry:${index}>`));
943
+ index += 1;
944
+ }
945
+ output = set4;
946
+ } else if (prototype === RegExp.prototype && import_node_util2.types.isRegExp(value)) {
947
+ assertNativeProperties(value, path, (key) => key === "lastIndex");
948
+ const regexp = value;
949
+ if (typeof regexp.lastIndex !== "number") return unsupported(path, "RegExp.lastIndex must be a number");
950
+ const copy = new RegExp(regexp.source, regexp.flags);
951
+ copy.lastIndex = regexp.lastIndex;
952
+ output = copy;
953
+ } else if (prototype === ArrayBuffer.prototype) {
954
+ output = copyBytes(value, path);
955
+ } else if (ArrayBuffer.isView(value)) {
956
+ const Type = typedArrays.find((candidate) => candidate.prototype === prototype);
957
+ const buffer = prototype === Buffer.prototype && Buffer.isBuffer(value);
958
+ const dataView = prototype === DataView.prototype;
959
+ if (!Type && !buffer && !dataView) return unsupported(path, "unsupported binary view prototype");
960
+ assertNativeProperties(
961
+ value,
962
+ path,
963
+ (key) => !dataView && /^(0|[1-9]\d*)$/.test(key) && Number(key) < value.length
964
+ );
965
+ let bytes;
966
+ try {
967
+ bytes = copyBytes(value.buffer, path, value.byteOffset, value.byteOffset + value.byteLength);
968
+ } catch (error) {
969
+ if (error instanceof TypeError && error.message.startsWith("Unsupported data value at ")) throw error;
970
+ return unsupported(path, "detached binary storage is not supported");
971
+ }
972
+ output = buffer ? Buffer.from(bytes) : dataView ? new DataView(bytes) : new Type(bytes);
973
+ } else {
974
+ return unsupported(path, "unsupported object prototype");
975
+ }
976
+ copies.set(value, output);
977
+ return output;
978
+ } finally {
979
+ active.delete(value);
980
+ }
981
+ };
982
+ return visit(input, rootPath);
983
+ }
984
+ var copyDataValue = (value) => copyValue(value, false, "data");
985
+ function exposeSnapshot(root) {
986
+ const views = /* @__PURE__ */ new WeakMap();
987
+ const visit = (value) => {
988
+ const previous = views.get(value);
989
+ if (previous) return previous;
990
+ let exposed;
991
+ const keys2 = Object.keys(value);
992
+ const mutableView = () => {
993
+ if (!exposed) {
994
+ exposed = Array.isArray(value) ? new Array(value.length) : Object.create(Object.getPrototypeOf(value));
995
+ for (const key of keys2) defineValue(exposed, key, value[key]);
996
+ }
997
+ return exposed;
998
+ };
999
+ for (const key of keys2) {
1000
+ const child = value[key];
1001
+ if (child === null || typeof child !== "object") continue;
1002
+ if (isPlainContainer(child)) {
1003
+ const view2 = visit(child);
1004
+ if (view2 !== child) defineValue(mutableView(), key, view2);
1005
+ } else {
1006
+ Object.defineProperty(mutableView(), key, {
1007
+ enumerable: true,
1008
+ configurable: true,
1009
+ get: () => copyDataValue(child)
1010
+ });
1011
+ }
1012
+ }
1013
+ const view = exposed ? Object.freeze(exposed) : value;
1014
+ views.set(value, view);
1015
+ return view;
1016
+ };
1017
+ return visit(root);
1018
+ }
1019
+ var emptyDataSnapshot = Object.freeze([]);
1020
+ var ownedSnapshots = new WeakMap([[emptyDataSnapshot, emptyDataSnapshot]]);
1021
+ function createDataSnapshot(data) {
1022
+ if (data === void 0) return void 0;
1023
+ if (!Array.isArray(data) || import_node_util2.types.isProxy(data) || Object.getPrototypeOf(data) !== Array.prototype) {
1024
+ return unsupported("data", "expected an ordinary array or undefined");
1025
+ }
1026
+ if (ownedSnapshots.has(data)) return data;
1027
+ const owned = copyValue(data, true, "data");
1028
+ const exposed = exposeSnapshot(owned);
1029
+ ownedSnapshots.set(exposed, owned);
1030
+ return exposed;
1031
+ }
1032
+ function getOwnedDataSnapshot(snapshot = emptyDataSnapshot) {
1033
+ const owned = ownedSnapshots.get(snapshot);
1034
+ if (!owned) throw new TypeError("DataService requires an admitted data snapshot");
1035
+ return owned;
1036
+ }
1037
+
1038
+ // src/options/data-manager.ts
1039
+ var admitData = (options) => {
1040
+ if (!Object.hasOwn(options, "data")) return options;
1041
+ const { data, ...otherOptions } = options;
1042
+ return { ...otherOptions, data: createDataSnapshot(data) };
1043
+ };
1044
+ var DataOptionsManager = class extends OptionsManager {
1045
+ assign(options) {
1046
+ super.assign(admitData(options));
1047
+ }
1048
+ set(key, value) {
1049
+ const path = String(key);
1050
+ if (path === "data") {
1051
+ super.set("data", createDataSnapshot(value));
1052
+ } else if (path.startsWith("data.")) {
1053
+ const next = copyDataValue(getOwnedDataSnapshot(super.get("data")));
1054
+ (0, import_utils8.set)(next, path.slice("data.".length), value);
1055
+ super.set("data", createDataSnapshot(next));
1056
+ } else {
1057
+ super.set(key, value);
1058
+ }
1059
+ }
1060
+ restore(snapshot) {
1061
+ super.restore(admitData(snapshot));
711
1062
  }
712
1063
  };
713
1064
 
714
1065
  // src/request-complexity.ts
715
- var import_utils7 = require("@web-ts-toolkit/utils");
1066
+ var import_utils9 = require("@web-ts-toolkit/utils");
716
1067
  var defaultRequestComplexity = {
717
1068
  maxDepth: 8,
718
1069
  maxNodes: 500,
@@ -778,7 +1129,7 @@ function validateRequestComplexity(value, options, scope = "request") {
778
1129
  pushError(`Request exceeds maximum depth of ${limits.maxDepth}`, path);
779
1130
  return;
780
1131
  }
781
- if ((0, import_utils7.isArray)(current)) {
1132
+ if ((0, import_utils9.isArray)(current)) {
782
1133
  if (parentKey === "$and" || parentKey === "$or" || parentKey === "$nor") {
783
1134
  logicalClauses += current.length;
784
1135
  if (logicalClauses > limits.maxLogicalClauses) {
@@ -798,14 +1149,14 @@ function validateRequestComplexity(value, options, scope = "request") {
798
1149
  }
799
1150
  return;
800
1151
  }
801
- if (!(0, import_utils7.isPlainObject)(current)) return;
1152
+ if (!(0, import_utils9.isPlainObject)(current)) return;
802
1153
  for (const [key, child] of Object.entries(current)) {
803
1154
  if (key === "__proto__" || key === "prototype" || key === "constructor") {
804
1155
  pushError(`Unsupported key: ${key}`, path.concat(key));
805
1156
  return;
806
1157
  }
807
1158
  if (scope === "request" && key === "include") {
808
- includeCount += (0, import_utils7.isArray)(child) ? child.length : 1;
1159
+ includeCount += (0, import_utils9.isArray)(child) ? child.length : 1;
809
1160
  if (includeCount > limits.maxIncludeCount) {
810
1161
  pushError(`Request exceeds maximum include count of ${limits.maxIncludeCount}`, path.concat(key));
811
1162
  return;
@@ -849,44 +1200,44 @@ var defaultDataOptions = {
849
1200
  listHardLimit: DEFAULT_LIST_HARD_LIMIT
850
1201
  };
851
1202
  var normalizeBasePath = (name, value) => {
852
- if ((0, import_utils8.isNil)(value)) {
1203
+ if ((0, import_utils10.isNil)(value)) {
853
1204
  return `/${pluralize(name)}`;
854
1205
  }
855
- return (0, import_utils8.isString)(value) ? (0, import_utils8.addLeadingSlash)(value) : "";
1206
+ return (0, import_utils10.isString)(value) ? (0, import_utils10.addLeadingSlash)(value) : "";
856
1207
  };
857
1208
  var hasModelPermission = (value, modelPermissionPrefix) => {
858
1209
  if (!modelPermissionPrefix) {
859
1210
  return true;
860
1211
  }
861
- if ((0, import_utils8.isString)(value)) {
1212
+ if ((0, import_utils10.isString)(value)) {
862
1213
  return value.trim().split(" ").some((item) => item.startsWith(modelPermissionPrefix));
863
1214
  }
864
- if ((0, import_utils8.isArray)(value)) {
1215
+ if ((0, import_utils10.isArray)(value)) {
865
1216
  return value.some((item) => {
866
- if ((0, import_utils8.isString)(item) || (0, import_utils8.isArray)(item)) {
1217
+ if ((0, import_utils10.isString)(item) || (0, import_utils10.isArray)(item)) {
867
1218
  return hasModelPermission(item, modelPermissionPrefix);
868
1219
  }
869
1220
  return true;
870
1221
  });
871
1222
  }
872
- return (0, import_utils8.isFunction)(value);
1223
+ return (0, import_utils10.isFunction)(value);
873
1224
  };
874
1225
  var classifyPermissionSchema = (permissionSchema, modelPermissionPrefix) => {
875
1226
  const schemaKeys = Object.keys(permissionSchema);
876
1227
  const globalPermissionKeys = {};
877
1228
  const modelPermissionKeys = {};
878
- (0, import_utils8.forEach)(schemaKeys, (schemaKey) => {
1229
+ (0, import_utils10.forEach)(schemaKeys, (schemaKey) => {
879
1230
  const schemaRule = permissionSchema[schemaKey];
880
- const ruleEntries = (0, import_utils8.isPlainObject)(schemaRule) ? Object.entries(schemaRule) : FIELD_ACCESS_KEYS.map((accessKey) => [accessKey, schemaRule]);
1231
+ const ruleEntries = (0, import_utils10.isPlainObject)(schemaRule) ? Object.entries(schemaRule) : FIELD_ACCESS_KEYS.map((accessKey) => [accessKey, schemaRule]);
881
1232
  for (let x = 0; x < ruleEntries.length; x++) {
882
1233
  const [accessKey, value] = ruleEntries[x];
883
- if (!(0, import_utils8.isArray)(globalPermissionKeys[accessKey])) {
1234
+ if (!(0, import_utils10.isArray)(globalPermissionKeys[accessKey])) {
884
1235
  globalPermissionKeys[accessKey] = [];
885
1236
  }
886
- if (!(0, import_utils8.isArray)(modelPermissionKeys[accessKey])) {
1237
+ if (!(0, import_utils10.isArray)(modelPermissionKeys[accessKey])) {
887
1238
  modelPermissionKeys[accessKey] = [];
888
1239
  }
889
- if ((0, import_utils8.isBoolean)(value)) {
1240
+ if ((0, import_utils10.isBoolean)(value)) {
890
1241
  globalPermissionKeys[accessKey].push(schemaKey);
891
1242
  continue;
892
1243
  }
@@ -918,13 +1269,13 @@ var VIRTUAL_UNSUPPORTED_ACCESSES = ["delete", "distinct", "count"];
918
1269
  var VIRTUAL_RESERVED_NAMES = /* @__PURE__ */ new Set(["_id", "__v", "id"]);
919
1270
  var VIRTUAL_DANGEROUS_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
920
1271
  var VIRTUAL_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
921
- var isVirtualContainerValue = (value) => (0, import_utils8.isPlainObject)(value) && "sub" in value;
1272
+ var isVirtualContainerValue = (value) => (0, import_utils10.isPlainObject)(value) && "sub" in value;
922
1273
  var virtualFullPath = (prefix, name) => prefix ? `${prefix}.${name}` : name;
923
1274
  var virtualPathsOverlap = (virtualPath, permissionField) => {
924
1275
  if (!virtualPath || !permissionField) return false;
925
1276
  try {
926
- if ((0, import_utils8.get)((0, import_utils8.set)({}, virtualPath, true), permissionField) !== void 0) return true;
927
- if ((0, import_utils8.get)((0, import_utils8.set)({}, permissionField, true), virtualPath) !== void 0) return true;
1277
+ if ((0, import_utils10.get)((0, import_utils10.set)({}, virtualPath, true), permissionField) !== void 0) return true;
1278
+ if ((0, import_utils10.get)((0, import_utils10.set)({}, permissionField, true), virtualPath) !== void 0) return true;
928
1279
  } catch {
929
1280
  return false;
930
1281
  }
@@ -985,12 +1336,12 @@ var cloneVirtualsForValidation = (value) => {
985
1336
  };
986
1337
  var validateVirtualDependsOn = (dependsOn, entryLabel, storedFields, siblingVirtualNames) => {
987
1338
  if (dependsOn === void 0) return [];
988
- if (!(0, import_utils8.isArray)(dependsOn)) {
1339
+ if (!(0, import_utils10.isArray)(dependsOn)) {
989
1340
  throw new Error(`Virtual ${entryLabel}: dependsOn must be an array of top-level persisted field names`);
990
1341
  }
991
1342
  const list = dependsOn;
992
1343
  for (const dep of list) {
993
- if (!(0, import_utils8.isString)(dep) || dep.length === 0) {
1344
+ if (!(0, import_utils10.isString)(dep) || dep.length === 0) {
994
1345
  throw new Error(`Virtual ${entryLabel}: dependsOn entries must be non-empty strings`);
995
1346
  }
996
1347
  if (dep.includes(".")) {
@@ -1012,12 +1363,12 @@ var validateVirtualDependsOn = (dependsOn, entryLabel, storedFields, siblingVirt
1012
1363
  return list;
1013
1364
  };
1014
1365
  var validateVirtualLeafValue = (value, entryLabel, storedFields, siblingVirtualNames, sharedDependsOn) => {
1015
- if ((0, import_utils8.isFunction)(value)) return;
1016
- if (!(0, import_utils8.isPlainObject)(value)) {
1366
+ if ((0, import_utils10.isFunction)(value)) return;
1367
+ if (!(0, import_utils10.isPlainObject)(value)) {
1017
1368
  throw new Error(`Virtual ${entryLabel}: descriptor must be a getter function or { get, dependsOn }`);
1018
1369
  }
1019
1370
  const record = value;
1020
- if (!(0, import_utils8.isFunction)(record.get)) {
1371
+ if (!(0, import_utils10.isFunction)(record.get)) {
1021
1372
  throw new Error(`Virtual ${entryLabel}: descriptor.get must be a callable getter function`);
1022
1373
  }
1023
1374
  validateVirtualDependsOn(record.dependsOn ?? sharedDependsOn, entryLabel, storedFields, siblingVirtualNames);
@@ -1057,7 +1408,7 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
1057
1408
  `Virtual ${scopeLabel}${name}: scope-container must only hold "sub" (embedded container "${name}" is not a virtual-leaf collision)`
1058
1409
  );
1059
1410
  }
1060
- if (!(0, import_utils8.isPlainObject)(record2.sub)) {
1411
+ if (!(0, import_utils10.isPlainObject)(record2.sub)) {
1061
1412
  throw new Error(`Virtual ${scopeLabel}${name}: scope-container "sub" must be a plain object`);
1062
1413
  }
1063
1414
  continue;
@@ -1067,8 +1418,8 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
1067
1418
  `Virtual ${scopeLabel}${name}: collides with a stored path (inspected actual Mongoose schema/child scope; getModelAtt alone is insufficient)`
1068
1419
  );
1069
1420
  }
1070
- if ((0, import_utils8.isFunction)(raw)) continue;
1071
- if (!(0, import_utils8.isPlainObject)(raw)) {
1421
+ if ((0, import_utils10.isFunction)(raw)) continue;
1422
+ if (!(0, import_utils10.isPlainObject)(raw)) {
1072
1423
  throw new Error(
1073
1424
  `Virtual ${scopeLabel}${name}: malformed descriptor (expected getter, { get, dependsOn }, or per-access record)`
1074
1425
  );
@@ -1076,7 +1427,7 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
1076
1427
  const record = raw;
1077
1428
  const hasGet = "get" in record;
1078
1429
  const accessKeys = Object.keys(record).filter((k) => VIRTUAL_SUPPORTED_ACCESSES.includes(k));
1079
- const unsupported = Object.keys(record).filter(
1430
+ const unsupported2 = Object.keys(record).filter(
1080
1431
  (k) => k !== "get" && k !== "dependsOn" && k !== "sub" && !VIRTUAL_SUPPORTED_ACCESSES.includes(k)
1081
1432
  );
1082
1433
  for (const key of Object.keys(record)) {
@@ -1086,9 +1437,9 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
1086
1437
  );
1087
1438
  }
1088
1439
  }
1089
- if (unsupported.length > 0) {
1440
+ if (unsupported2.length > 0) {
1090
1441
  throw new Error(
1091
- `Virtual ${scopeLabel}${name}: unsupported access/key "${unsupported[0]}" (supported: default + list/create/read/update)`
1442
+ `Virtual ${scopeLabel}${name}: unsupported access/key "${unsupported2[0]}" (supported: default + list/create/read/update)`
1092
1443
  );
1093
1444
  }
1094
1445
  if (hasGet) {
@@ -1122,7 +1473,7 @@ var validateVirtualsScope = (scope, documentPermissionField) => {
1122
1473
  };
1123
1474
  var validateVirtualsTree = (model, virtuals, documentPermissionField, modelName) => {
1124
1475
  if (virtuals === void 0 || virtuals === null) return;
1125
- if (!(0, import_utils8.isPlainObject)(virtuals)) {
1476
+ if (!(0, import_utils10.isPlainObject)(virtuals)) {
1126
1477
  throw new Error(`Virtuals for model "${modelName}": virtuals must be a plain object mapping names to descriptors`);
1127
1478
  }
1128
1479
  const rootSchema = model?.schema ?? null;
@@ -1169,27 +1520,27 @@ var validateVirtualsTree = (model, virtuals, documentPermissionField, modelName)
1169
1520
  visitContainers(rootVirtuals, rootSchema, "");
1170
1521
  };
1171
1522
  var getScopeVirtualsObject = (rootVirtuals, scopePath) => {
1172
- if (!rootVirtuals || !(0, import_utils8.isPlainObject)(rootVirtuals)) return null;
1523
+ if (!rootVirtuals || !(0, import_utils10.isPlainObject)(rootVirtuals)) return null;
1173
1524
  if (!scopePath || scopePath.length === 0) return rootVirtuals;
1174
1525
  let current = rootVirtuals;
1175
1526
  for (let i = 0; i < scopePath.length; i += 2) {
1176
1527
  const field = scopePath[i];
1177
1528
  const subMarker = scopePath[i + 1];
1178
1529
  if (!field || subMarker !== "sub") return null;
1179
- if (!(0, import_utils8.isPlainObject)(current)) return null;
1530
+ if (!(0, import_utils10.isPlainObject)(current)) return null;
1180
1531
  const container = current[field];
1181
1532
  if (!isVirtualContainerValue(container)) return null;
1182
1533
  current = container.sub;
1183
- if (!(0, import_utils8.isPlainObject)(current)) return null;
1534
+ if (!(0, import_utils10.isPlainObject)(current)) return null;
1184
1535
  }
1185
1536
  return current;
1186
1537
  };
1187
1538
  var toVirtualDescriptor = (leaf, sharedDependsOn) => {
1188
- if ((0, import_utils8.isFunction)(leaf))
1539
+ if ((0, import_utils10.isFunction)(leaf))
1189
1540
  return { get: leaf, dependsOn: sharedDependsOn ?? [] };
1190
- if (!(0, import_utils8.isPlainObject)(leaf)) return null;
1541
+ if (!(0, import_utils10.isPlainObject)(leaf)) return null;
1191
1542
  const record = leaf;
1192
- if (!(0, import_utils8.isFunction)(record.get)) return null;
1543
+ if (!(0, import_utils10.isFunction)(record.get)) return null;
1193
1544
  const dependsOn = record.dependsOn ?? sharedDependsOn ?? [];
1194
1545
  return { get: record.get, dependsOn };
1195
1546
  };
@@ -1254,7 +1605,7 @@ var AccessRuntime = class {
1254
1605
  }
1255
1606
  registerOpenApiRoute(route) {
1256
1607
  this.openApiRegistry.register(
1257
- this.openApiPathPrefix ? { ...route, path: (0, import_utils8.normalizeUrlPath)(`${this.openApiPathPrefix}/${route.path}`) } : route
1608
+ this.openApiPathPrefix ? { ...route, path: (0, import_utils10.normalizeUrlPath)(`${this.openApiPathPrefix}/${route.path}`) } : route
1258
1609
  );
1259
1610
  }
1260
1611
  /**
@@ -1265,7 +1616,7 @@ var AccessRuntime = class {
1265
1616
  */
1266
1617
  withOpenApiPathPrefix(prefix, build) {
1267
1618
  const previous = this.openApiPathPrefix;
1268
- this.openApiPathPrefix = (0, import_utils8.normalizeUrlPath)(`${previous}/${prefix}`);
1619
+ this.openApiPathPrefix = (0, import_utils10.normalizeUrlPath)(`${previous}/${prefix}`);
1269
1620
  try {
1270
1621
  return build();
1271
1622
  } finally {
@@ -1370,6 +1721,7 @@ var AccessRuntime = class {
1370
1721
  Object.assign(this.modelAtts, snapshot.modelAtts);
1371
1722
  this.openApiRegistry.restore(snapshot.openApi);
1372
1723
  }
1724
+ /** Shallowly replace supplied global values; nested objects such as requestComplexity are not deep-merged. */
1373
1725
  setGlobalOptions(options) {
1374
1726
  this.globalOptions.assign(options);
1375
1727
  }
@@ -1382,10 +1734,27 @@ var AccessRuntime = class {
1382
1734
  getGlobalOption(key, defaultValue) {
1383
1735
  return this.globalOptions.get(key, defaultValue);
1384
1736
  }
1737
+ /** Update model starting defaults shallowly; already-stored model values are not broadcast-replaced. */
1385
1738
  setDefaultModelOptions(options) {
1739
+ assertPublicDefaults(options.defaults);
1740
+ if ("hydration" in options) options = { ...options, hydration: normalizeHydration(options.hydration) };
1386
1741
  this.defaultModelOptions.assign(options);
1387
1742
  }
1388
1743
  setDefaultModelOption(key, value) {
1744
+ const keyStr = String(key);
1745
+ if (keyStr === "hydration" || keyStr.startsWith("hydration.")) {
1746
+ this.defaultModelOptions.set(
1747
+ "hydration",
1748
+ normalizeHydrationUpdate(this.getDefaultModelOptions().hydration, keyStr, value)
1749
+ );
1750
+ return;
1751
+ }
1752
+ if (keyStr === "defaults") assertPublicDefaults(value);
1753
+ else if (keyStr.startsWith("defaults.")) {
1754
+ const proposed = {};
1755
+ (0, import_utils10.set)(proposed, keyStr.slice("defaults.".length), value);
1756
+ assertPublicDefaults(proposed);
1757
+ }
1389
1758
  this.defaultModelOptions.set(key, value);
1390
1759
  }
1391
1760
  getDefaultModelOptions() {
@@ -1412,7 +1781,7 @@ var AccessRuntime = class {
1412
1781
  }).onchange("basePath", function(newval, key, target) {
1413
1782
  target[key] = normalizeBasePath(
1414
1783
  modelName,
1415
- (0, import_utils8.isString)(newval) || (0, import_utils8.isNil)(newval) ? newval : void 0
1784
+ (0, import_utils10.isString)(newval) || (0, import_utils10.isNil)(newval) ? newval : void 0
1416
1785
  );
1417
1786
  }).build();
1418
1787
  this.modelJsonSchemas[modelName] = model.jsonSchema();
@@ -1426,7 +1795,16 @@ var AccessRuntime = class {
1426
1795
  }
1427
1796
  return manager;
1428
1797
  }
1798
+ /**
1799
+ * Assign `{ ...modelDefaults, ...storedOptions, ...options }` shallowly. A supplied
1800
+ * operationAccess/defaults object replaces that whole value. Defaults accept only
1801
+ * query/presentation settings; virtual configuration is validated before assignment.
1802
+ * Existing router.options remains its construction-time snapshot. Fresh model-service
1803
+ * calls capture the owner's current options/defaults; in-flight calls retain their snapshot.
1804
+ */
1429
1805
  setModelOptions(modelName, options) {
1806
+ assertPublicDefaults(options.defaults);
1807
+ if ("hydration" in options) options = { ...options, hydration: normalizeHydration(options.hydration) };
1430
1808
  const manager = this.getOrCreateModelOptions(modelName);
1431
1809
  const defaultOptions = this.getDefaultModelOptions();
1432
1810
  const currentModelOptions = manager.fetch();
@@ -1437,8 +1815,19 @@ var AccessRuntime = class {
1437
1815
  manager.assign({ ...defaultOptions, ...currentModelOptions, ...options });
1438
1816
  }
1439
1817
  setModelOption(modelName, key, value) {
1440
- const manager = this.getOrCreateModelOptions(modelName);
1441
1818
  const keyStr = String(key);
1819
+ if (keyStr === "hydration" || keyStr.startsWith("hydration.")) {
1820
+ const hydration = normalizeHydrationUpdate(this.modelOptions[modelName]?.get("hydration"), keyStr, value);
1821
+ this.getOrCreateModelOptions(modelName).set("hydration", hydration);
1822
+ return;
1823
+ }
1824
+ if (keyStr === "defaults") assertPublicDefaults(value);
1825
+ else if (keyStr.startsWith("defaults.")) {
1826
+ const proposed = {};
1827
+ (0, import_utils10.set)(proposed, keyStr.slice("defaults.".length), value);
1828
+ assertPublicDefaults(proposed);
1829
+ }
1830
+ const manager = this.getOrCreateModelOptions(modelName);
1442
1831
  if (keyStr === "virtuals" || keyStr.startsWith("virtuals.") || keyStr === "documentPermissionField") {
1443
1832
  const model = this.getModelInstance(modelName);
1444
1833
  const currentVirtuals = manager.get("virtuals");
@@ -1456,15 +1845,15 @@ var AccessRuntime = class {
1456
1845
  const segments = nestedPath.split(".");
1457
1846
  let cursor = cloned;
1458
1847
  for (let i = 0; i < segments.length - 1; i++) {
1459
- if (!(0, import_utils8.isPlainObject)(cursor)) break;
1848
+ if (!(0, import_utils10.isPlainObject)(cursor)) break;
1460
1849
  cursor = cursor[segments[i]];
1461
1850
  }
1462
- if ((0, import_utils8.isPlainObject)(cursor)) {
1851
+ if ((0, import_utils10.isPlainObject)(cursor)) {
1463
1852
  delete cursor[segments[segments.length - 1]];
1464
1853
  }
1465
1854
  proposedVirtuals = cloned;
1466
1855
  } else {
1467
- (0, import_utils8.set)(cloned, nestedPath, value);
1856
+ (0, import_utils10.set)(cloned, nestedPath, value);
1468
1857
  proposedVirtuals = cloned;
1469
1858
  }
1470
1859
  }
@@ -1472,10 +1861,17 @@ var AccessRuntime = class {
1472
1861
  }
1473
1862
  manager.set(key, value);
1474
1863
  }
1864
+ /** Frozen stored snapshot, not fully resolved per-path defaults. Read again for current configuration. */
1475
1865
  getModelOptions(modelName) {
1476
1866
  const manager = this.getOrCreateModelOptions(modelName);
1477
1867
  return manager.fetch();
1478
1868
  }
1869
+ /**
1870
+ * Generic stored exact → parent.default → parent lookup; only undefined falls through.
1871
+ * The exact runtime-model-default path is the final fallback if the stored parent is
1872
+ * absent. This is not the route-specific variant-to-base resolver; use
1873
+ * getExactModelOption to inspect a variant including its exact model-default fallback.
1874
+ */
1479
1875
  getModelOption(modelName, key, defaultValue) {
1480
1876
  const manager = this.getOrCreateModelOptions(modelName);
1481
1877
  const defaultModelValue = this.getDefaultModelOption(
@@ -1484,6 +1880,7 @@ var AccessRuntime = class {
1484
1880
  );
1485
1881
  return getNestedOption(manager, key, defaultModelValue);
1486
1882
  }
1883
+ /** Exact stored path, then the same runtime-model-default path; no parent/default or variant-to-base lookup. */
1487
1884
  getExactModelOption(modelName, key) {
1488
1885
  const manager = this.getOrCreateModelOptions(modelName);
1489
1886
  const defaultModelValue = this.getDefaultModelOption(key);
@@ -1534,8 +1931,8 @@ var AccessRuntime = class {
1534
1931
  if (!scopeVirtuals || !(virtualName in scopeVirtuals)) return void 0;
1535
1932
  const entry = scopeVirtuals[virtualName];
1536
1933
  if (entry === void 0 || isVirtualContainerValue(entry)) return void 0;
1537
- if ((0, import_utils8.isFunction)(entry)) return { get: entry, dependsOn: [] };
1538
- if (!(0, import_utils8.isPlainObject)(entry)) return void 0;
1934
+ if ((0, import_utils10.isFunction)(entry)) return { get: entry, dependsOn: [] };
1935
+ if (!(0, import_utils10.isPlainObject)(entry)) return void 0;
1539
1936
  const record = entry;
1540
1937
  if ("get" in record) {
1541
1938
  const descriptor = toVirtualDescriptor(entry, void 0);
@@ -1564,14 +1961,14 @@ var AccessRuntime = class {
1564
1961
  return this.modelJsonSchemas[modelName];
1565
1962
  }
1566
1963
  createDataOptions(dataName) {
1567
- const manager = new OptionsManager({
1964
+ const manager = new DataOptionsManager({
1568
1965
  ...defaultDataOptions,
1569
1966
  dataName
1570
1967
  });
1571
1968
  manager.onchange("basePath", function(newval, key, target) {
1572
1969
  target[key] = normalizeBasePath(
1573
1970
  dataName,
1574
- (0, import_utils8.isString)(newval) || (0, import_utils8.isNil)(newval) ? newval : void 0
1971
+ (0, import_utils10.isString)(newval) || (0, import_utils10.isNil)(newval) ? newval : void 0
1575
1972
  );
1576
1973
  }).build();
1577
1974
  return manager;
@@ -1596,10 +1993,15 @@ var AccessRuntime = class {
1596
1993
  const manager = this.getOrCreateDataOptions(dataName);
1597
1994
  return manager.fetch();
1598
1995
  }
1996
+ /**
1997
+ * Reusable configured data view: plain containers are frozen; native properties
1998
+ * return detached mutable copies on access. Native identity is not stable.
1999
+ * Replacement leaves previously captured views on their original data version.
2000
+ */
1599
2001
  getDataSnapshot(dataName) {
1600
2002
  const manager = this.getOrCreateDataOptions(dataName);
1601
2003
  const snapshot = manager.get("data");
1602
- return snapshot ?? [];
2004
+ return snapshot ?? emptyDataSnapshot;
1603
2005
  }
1604
2006
  getDataOption(dataName, key, defaultValue) {
1605
2007
  const manager = this.getOrCreateDataOptions(dataName);
@@ -1626,20 +2028,20 @@ var AccessRuntime = class {
1626
2028
  const schema = model.schema;
1627
2029
  this.modelRefs[modelName] = buildRefs(schema.tree);
1628
2030
  this.modelSubs[modelName] = buildSubPaths(schema.tree);
1629
- this.modelAtts[modelName] = (0, import_utils8.keys)(schema.obj);
2031
+ this.modelAtts[modelName] = (0, import_utils10.keys)(schema.obj);
1630
2032
  }
1631
2033
  getModelRef(modelName, refPath) {
1632
2034
  this.ensureModelMeta(modelName);
1633
- const value = (0, import_utils8.get)(this.modelRefs, `${modelName}.${refPath}`, null);
1634
- return (0, import_utils8.isString)(value) ? value : null;
2035
+ const value = (0, import_utils10.get)(this.modelRefs, `${modelName}.${refPath}`, null);
2036
+ return (0, import_utils10.isString)(value) ? value : null;
1635
2037
  }
1636
2038
  getModelSub(modelName) {
1637
2039
  this.ensureModelMeta(modelName);
1638
- return (0, import_utils8.get)(this.modelSubs, modelName, []);
2040
+ return (0, import_utils10.get)(this.modelSubs, modelName, []);
1639
2041
  }
1640
2042
  getModelAtt(modelName) {
1641
2043
  this.ensureModelMeta(modelName);
1642
- return (0, import_utils8.get)(this.modelAtts, modelName, []);
2044
+ return (0, import_utils10.get)(this.modelAtts, modelName, []);
1643
2045
  }
1644
2046
  };
1645
2047
  var defaultRuntime = new AccessRuntime({ allowGlobalModelLookup: true });
@@ -1659,10 +2061,29 @@ var getGlobalOption = (key, defaultValue) => {
1659
2061
 
1660
2062
  // src/validation/common.ts
1661
2063
  var import_zod2 = require("zod");
1662
- var import_utils10 = require("@web-ts-toolkit/utils");
2064
+ var import_utils12 = require("@web-ts-toolkit/utils");
2065
+
2066
+ // src/validation/public-admission-schema.ts
2067
+ var admissions = /* @__PURE__ */ new WeakMap();
2068
+ function publicBoundarySchema(schema, kind = "envelope") {
2069
+ const checked = schema.superRefine((value, ctx) => {
2070
+ try {
2071
+ assertPublicAdmission(value, kind);
2072
+ } catch (error) {
2073
+ if (!(error instanceof PublicAdmissionError)) throw error;
2074
+ ctx.addIssue({ code: "custom", message: error.result.errors[0].detail });
2075
+ }
2076
+ });
2077
+ admissions.set(checked, kind);
2078
+ return checked;
2079
+ }
2080
+ function assertTransformedPublicAdmission(schema, value) {
2081
+ const kind = admissions.get(schema);
2082
+ if (kind) assertPublicAdmission(value, kind);
2083
+ }
1663
2084
 
1664
2085
  // src/correlated-includes.ts
1665
- var import_utils9 = require("@web-ts-toolkit/utils");
2086
+ var import_utils11 = require("@web-ts-toolkit/utils");
1666
2087
  var PARENT_MARKER_KEY = "$parent";
1667
2088
  var ESCAPE_WRAPPER_KEY = "$escape";
1668
2089
  var SUBQUERY_PAYLOAD_KEYS = /* @__PURE__ */ new Set(["$$sq", "$$date"]);
@@ -1673,10 +2094,10 @@ var FIELD_SEGMENT_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
1673
2094
  var ARRAY_INDEX_SEGMENT_PATTERN = /^(0|[1-9]\d*)$/;
1674
2095
  var ownKeys = (value) => Object.keys(value);
1675
2096
  function isParentRefMarker(value) {
1676
- return (0, import_utils9.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === PARENT_MARKER_KEY;
2097
+ return (0, import_utils11.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === PARENT_MARKER_KEY;
1677
2098
  }
1678
2099
  function isEscapedParentRef(value) {
1679
- return (0, import_utils9.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === ESCAPE_WRAPPER_KEY;
2100
+ return (0, import_utils11.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === ESCAPE_WRAPPER_KEY;
1680
2101
  }
1681
2102
  function hasMarkerKey(value) {
1682
2103
  return ownKeys(value).includes(PARENT_MARKER_KEY) || ownKeys(value).includes(ESCAPE_WRAPPER_KEY);
@@ -1695,12 +2116,12 @@ function containsParentMarkerShape(value) {
1695
2116
  const seen = /* @__PURE__ */ new Set();
1696
2117
  const visit = (current) => {
1697
2118
  if (isParentRefMarker(current) || isEscapedParentRef(current)) return true;
1698
- if ((0, import_utils9.isArray)(current)) {
2119
+ if ((0, import_utils11.isArray)(current)) {
1699
2120
  if (seen.has(current)) return false;
1700
2121
  seen.add(current);
1701
2122
  return current.some(visit);
1702
2123
  }
1703
- if ((0, import_utils9.isPlainObject)(current)) {
2124
+ if ((0, import_utils11.isPlainObject)(current)) {
1704
2125
  if (seen.has(current)) return false;
1705
2126
  seen.add(current);
1706
2127
  if (hasMarkerKey(current)) return true;
@@ -1730,7 +2151,7 @@ function scanTemplateValueNode(value, path, issues) {
1730
2151
  }
1731
2152
  return;
1732
2153
  }
1733
- if ((0, import_utils9.isPlainObject)(value)) {
2154
+ if ((0, import_utils11.isPlainObject)(value)) {
1734
2155
  if (hasMarkerKey(value)) {
1735
2156
  issues.push({
1736
2157
  message: 'Malformed $parent reference: objects carrying $parent must be exactly { "$parent": "<field>" }',
@@ -1741,7 +2162,7 @@ function scanTemplateValueNode(value, path, issues) {
1741
2162
  scanTemplateObjectEntries(value, path, issues);
1742
2163
  return;
1743
2164
  }
1744
- if ((0, import_utils9.isArray)(value)) {
2165
+ if ((0, import_utils11.isArray)(value)) {
1745
2166
  value.forEach((item, index) => scanTemplateValueNode(item, [...path, index], issues));
1746
2167
  }
1747
2168
  }
@@ -1782,7 +2203,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
1782
2203
  continue;
1783
2204
  }
1784
2205
  if (LOGICAL_CLAUSE_KEYS.has(key)) {
1785
- if (!(0, import_utils9.isArray)(child)) {
2206
+ if (!(0, import_utils11.isArray)(child)) {
1786
2207
  scanTemplateValueNode(child, childPath, issues);
1787
2208
  continue;
1788
2209
  }
@@ -1795,7 +2216,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
1795
2216
  });
1796
2217
  return;
1797
2218
  }
1798
- if ((0, import_utils9.isPlainObject)(clause)) {
2219
+ if ((0, import_utils11.isPlainObject)(clause)) {
1799
2220
  scanTemplateObjectEntries(clause, clausePath, issues);
1800
2221
  }
1801
2222
  });
@@ -1806,7 +2227,7 @@ function scanTemplateObjectEntries(obj, basePath, issues) {
1806
2227
  }
1807
2228
  function validateCorrelatedFilterTemplate(filter) {
1808
2229
  const issues = [];
1809
- if (!(0, import_utils9.isPlainObject)(filter)) {
2230
+ if (!(0, import_utils11.isPlainObject)(filter)) {
1810
2231
  issues.push({ message: "Correlated include filter must be an object", path: [] });
1811
2232
  return issues;
1812
2233
  }
@@ -1853,42 +2274,48 @@ var sortSchema = import_zod2.z.union([
1853
2274
  import_zod2.z.null()
1854
2275
  ]);
1855
2276
  var populateAccessSchema = import_zod2.z.enum(["list", "read"]);
1856
- var populateSchema = import_zod2.z.union([
1857
- import_zod2.z.string(),
1858
- import_zod2.z.array(
1859
- import_zod2.z.union([
1860
- import_zod2.z.string(),
1861
- import_zod2.z.object({
1862
- path: import_zod2.z.string().min(1),
1863
- select: projectionSchema.optional(),
1864
- match: import_zod2.z.unknown().optional(),
1865
- access: populateAccessSchema.optional()
1866
- }).passthrough()
1867
- ])
1868
- ),
1869
- import_zod2.z.object({
1870
- path: import_zod2.z.string().min(1),
1871
- select: projectionSchema.optional(),
1872
- match: import_zod2.z.unknown().optional(),
1873
- access: populateAccessSchema.optional()
1874
- }).passthrough()
1875
- ]);
1876
- var subPopulateSchema = import_zod2.z.union([
1877
- import_zod2.z.string(),
1878
- import_zod2.z.array(
1879
- import_zod2.z.union([
1880
- import_zod2.z.string(),
1881
- import_zod2.z.object({
1882
- path: import_zod2.z.string().min(1),
1883
- select: projectionSchema.optional()
1884
- }).passthrough()
1885
- ])
1886
- ),
1887
- import_zod2.z.object({
1888
- path: import_zod2.z.string().min(1),
1889
- select: projectionSchema.optional()
1890
- }).passthrough()
1891
- ]);
2277
+ var populateSchema = publicBoundarySchema(
2278
+ import_zod2.z.union([
2279
+ import_zod2.z.string(),
2280
+ import_zod2.z.array(
2281
+ import_zod2.z.union([
2282
+ import_zod2.z.string(),
2283
+ import_zod2.z.object({
2284
+ path: import_zod2.z.string().min(1),
2285
+ select: projectionSchema.optional(),
2286
+ match: import_zod2.z.unknown().optional(),
2287
+ access: populateAccessSchema.optional()
2288
+ }).passthrough()
2289
+ ])
2290
+ ),
2291
+ import_zod2.z.object({
2292
+ path: import_zod2.z.string().min(1),
2293
+ select: projectionSchema.optional(),
2294
+ match: import_zod2.z.unknown().optional(),
2295
+ access: populateAccessSchema.optional()
2296
+ }).passthrough()
2297
+ ]),
2298
+ "populate"
2299
+ );
2300
+ var subPopulateSchema = publicBoundarySchema(
2301
+ import_zod2.z.union([
2302
+ import_zod2.z.string(),
2303
+ import_zod2.z.array(
2304
+ import_zod2.z.union([
2305
+ import_zod2.z.string(),
2306
+ import_zod2.z.object({
2307
+ path: import_zod2.z.string().min(1),
2308
+ select: projectionSchema.optional()
2309
+ }).passthrough()
2310
+ ])
2311
+ ),
2312
+ import_zod2.z.object({
2313
+ path: import_zod2.z.string().min(1),
2314
+ select: projectionSchema.optional()
2315
+ }).passthrough()
2316
+ ]),
2317
+ "populate"
2318
+ );
1892
2319
  var legacyIncludeItemSchema = import_zod2.z.object({
1893
2320
  mode: import_zod2.z.enum(["legacy"]).optional(),
1894
2321
  model: import_zod2.z.string().min(1),
@@ -1928,7 +2355,7 @@ var correlatedFilterSchema = import_zod2.z.record(import_zod2.z.string(), import
1928
2355
  }
1929
2356
  });
1930
2357
  var correlatedEmptyOptionsSchema = import_zod2.z.unknown().refine(
1931
- (value) => value === void 0 || (0, import_utils10.isPlainObject)(value) && Object.keys(value).length === 0,
2358
+ (value) => value === void 0 || (0, import_utils12.isPlainObject)(value) && Object.keys(value).length === 0,
1932
2359
  "Correlated include options must be absent or empty"
1933
2360
  ).optional();
1934
2361
  var correlatedPathSchema = import_zod2.z.string().min(1).superRefine((path, ctx) => {
@@ -1965,7 +2392,7 @@ var correlatedListArgsSchema = import_zod2.z.object({
1965
2392
  include: import_zod2.z.lazy(() => correlatedNestedIncludeSchema).optional()
1966
2393
  }).strict().superRefine((args, ctx) => checkArgsMarkers(args.select, args.sort, ctx));
1967
2394
  var correlatedCountArgsSchema = import_zod2.z.unknown().refine(
1968
- (value) => value === void 0 || (0, import_utils10.isPlainObject)(value) && Object.keys(value).length === 0,
2395
+ (value) => value === void 0 || (0, import_utils12.isPlainObject)(value) && Object.keys(value).length === 0,
1969
2396
  "Count includes accept no args"
1970
2397
  ).optional();
1971
2398
  var correlatedReadByIdSchema = import_zod2.z.object({
@@ -2004,18 +2431,21 @@ var correlatedCountSchema = import_zod2.z.object({
2004
2431
  args: correlatedCountArgsSchema,
2005
2432
  options: correlatedEmptyOptionsSchema
2006
2433
  }).strict();
2007
- var includeItemSchema = import_zod2.z.union([
2008
- legacyIncludeItemSchema,
2009
- correlatedReadByIdSchema,
2010
- correlatedReadByFilterSchema,
2011
- correlatedListSchema,
2012
- correlatedCountSchema
2013
- ]);
2434
+ var includeItemSchema = publicBoundarySchema(
2435
+ import_zod2.z.union([
2436
+ legacyIncludeItemSchema,
2437
+ correlatedReadByIdSchema,
2438
+ correlatedReadByFilterSchema,
2439
+ correlatedListSchema,
2440
+ correlatedCountSchema
2441
+ ]),
2442
+ "include"
2443
+ );
2014
2444
  var correlatedNestedIncludeSchema = import_zod2.z.union([includeItemSchema, import_zod2.z.array(includeItemSchema)]);
2015
2445
  var rejectDuplicateCorrelatedPaths = (items, ctx) => {
2016
2446
  const seen = /* @__PURE__ */ new Set();
2017
2447
  items.forEach((item, index) => {
2018
- if ((0, import_utils10.isPlainObject)(item) && item.mode === "correlated" && typeof item.path === "string") {
2448
+ if ((0, import_utils12.isPlainObject)(item) && item.mode === "correlated" && typeof item.path === "string") {
2019
2449
  if (seen.has(item.path)) {
2020
2450
  ctx.addIssue({
2021
2451
  code: import_zod2.z.ZodIssueCode.custom,
@@ -2053,7 +2483,7 @@ function rejectKeys(body, ctx, keys2) {
2053
2483
  }
2054
2484
 
2055
2485
  // src/validation/parsers.ts
2056
- var clientErrors = import_express_json_router.default.clientErrors;
2486
+ var clientErrors = import_express_json_router2.default.clientErrors;
2057
2487
  function parsePathParam(value, parameter) {
2058
2488
  const result = stringOrStringArray.safeParse(value);
2059
2489
  if (!result.success) {
@@ -2068,6 +2498,7 @@ function parsePathParam(value, parameter) {
2068
2498
  return param;
2069
2499
  }
2070
2500
  function parseQuery(schema, value) {
2501
+ assertTransformedPublicAdmission(schema, value);
2071
2502
  const complexityErrors = validateRequestComplexity(value, getGlobalOption("requestComplexity"), "request");
2072
2503
  if (complexityErrors.length > 0) {
2073
2504
  throw new clientErrors.BadRequestError("Bad Request", { errors: complexityErrors });
@@ -2079,6 +2510,7 @@ function parseQuery(schema, value) {
2079
2510
  return result.data;
2080
2511
  }
2081
2512
  function parseBody(schema, value) {
2513
+ assertTransformedPublicAdmission(schema, value);
2082
2514
  const complexityErrors = validateRequestComplexity(value ?? {}, getGlobalOption("requestComplexity"), "request");
2083
2515
  if (complexityErrors.length > 0) {
2084
2516
  throw new clientErrors.BadRequestError("Bad Request", { errors: complexityErrors });
@@ -2089,17 +2521,22 @@ function parseBody(schema, value) {
2089
2521
  }
2090
2522
  return result.data;
2091
2523
  }
2092
- function parseBodyWithSchema(schema, value, userSchema) {
2524
+ async function parseBodyWithSchema(schema, value, userSchema) {
2093
2525
  const body = parseBody(schema, value);
2094
- return isRequestSchema(userSchema) ? parseUserSchema(userSchema, body) : Promise.resolve(body);
2526
+ if (!isRequestSchema(userSchema)) return body;
2527
+ const transformed = await parseUserSchema(userSchema, body);
2528
+ assertTransformedPublicAdmission(schema, transformed);
2529
+ return transformed;
2095
2530
  }
2096
2531
  async function parseNestedBodyWithSchema(schema, value, nestedKey, userSchema) {
2097
2532
  const body = parseBody(schema, value);
2098
2533
  if (!isRequestSchema(userSchema)) return body;
2099
- return {
2534
+ const transformed = {
2100
2535
  ...body,
2101
2536
  [nestedKey]: await parseUserSchema(userSchema, body?.[nestedKey], [nestedKey])
2102
2537
  };
2538
+ assertTransformedPublicAdmission(schema, transformed);
2539
+ return transformed;
2103
2540
  }
2104
2541
  function throwValidationError(issues, key, location = "pointer") {
2105
2542
  const errors = issues.map((issue) => formatIssue(issue, key, location));
@@ -2527,147 +2964,177 @@ function buildPointer(path) {
2527
2964
 
2528
2965
  // src/validation/model-router.ts
2529
2966
  var import_zod3 = require("zod");
2530
- var listQuerySchema = import_zod3.z.object({
2531
- skip: nonNegativeIntegerString.optional(),
2532
- limit: positiveIntegerString.optional(),
2533
- page: nonNegativeIntegerString.optional(),
2534
- page_size: positiveIntegerString.optional(),
2535
- skim: queryBooleanString.optional(),
2536
- include_permissions: queryBooleanString.optional(),
2537
- include_field_permissions: queryBooleanString.optional(),
2538
- include_count: queryBooleanString.optional(),
2539
- include_extra_headers: queryBooleanString.optional(),
2540
- select: stringOrStringArray.optional(),
2541
- sort: import_zod3.z.string().optional().describe("Space-separated sort fields; prefix a field with - for descending order.")
2542
- }).passthrough();
2543
- var createQuerySchema = import_zod3.z.object({
2544
- include_permissions: queryBooleanString.optional(),
2545
- include_field_permissions: queryBooleanString.optional()
2546
- }).passthrough();
2547
- var readQuerySchema = import_zod3.z.object({
2548
- include_permissions: queryBooleanString.optional(),
2549
- include_field_permissions: queryBooleanString.optional(),
2550
- try_list: queryBooleanString.optional(),
2551
- select: stringOrStringArray.optional()
2552
- }).passthrough();
2553
- var updateQuerySchema = import_zod3.z.object({
2554
- returning_all: queryBooleanString.optional(),
2555
- include_permissions: queryBooleanString.optional(),
2556
- include_field_permissions: queryBooleanString.optional(),
2557
- select: stringOrStringArray.optional()
2558
- }).passthrough();
2559
- var upsertQuerySchema = import_zod3.z.object({
2560
- returning_all: queryBooleanString.optional(),
2561
- include_permissions: queryBooleanString.optional(),
2562
- include_field_permissions: queryBooleanString.optional()
2563
- }).passthrough();
2564
- var listBodySchema = import_zod3.z.object({
2565
- filter: objectOrArraySchema.optional(),
2566
- select: projectionSchema.optional(),
2567
- sort: sortSchema.optional(),
2568
- populate: populateSchema.optional(),
2569
- include: includeSchema.optional(),
2570
- tasks: tasksSchema.optional(),
2571
- skip: import_zod3.z.union([nonNegativeIntegerSchema, nonNegativeIntegerString]).optional(),
2572
- limit: import_zod3.z.union([positiveIntegerSchema, positiveIntegerString]).optional(),
2573
- page: import_zod3.z.union([nonNegativeIntegerSchema, nonNegativeIntegerString]).optional(),
2574
- pageSize: import_zod3.z.union([positiveIntegerSchema, positiveIntegerString]).optional(),
2575
- options: import_zod3.z.object({
2576
- skim: import_zod3.z.boolean().optional(),
2577
- includePermissions: import_zod3.z.boolean().optional(),
2578
- includeFieldPermissions: import_zod3.z.boolean().optional(),
2579
- includeCount: import_zod3.z.boolean().optional(),
2580
- includeExtraHeaders: import_zod3.z.boolean().optional(),
2581
- populateAccess: populateAccessSchema.optional()
2582
- }).passthrough().optional()
2583
- }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query"]));
2584
- var countBodySchema = import_zod3.z.object({
2585
- filter: objectOrArraySchema.optional()
2586
- }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query", "access", "options", "include"]));
2587
- var readFilterBodySchema = import_zod3.z.object({
2588
- filter: objectOrArraySchema.optional(),
2589
- select: projectionSchema.optional(),
2590
- sort: sortSchema.optional(),
2591
- populate: populateSchema.optional(),
2592
- include: includeSchema.optional(),
2593
- tasks: tasksSchema.optional(),
2594
- options: import_zod3.z.object({
2595
- skim: import_zod3.z.boolean().optional(),
2596
- includePermissions: import_zod3.z.boolean().optional(),
2597
- includeFieldPermissions: import_zod3.z.boolean().optional(),
2598
- tryList: import_zod3.z.boolean().optional(),
2599
- populateAccess: populateAccessSchema.optional()
2600
- }).passthrough().optional()
2601
- }).passthrough();
2602
- var readByIdBodySchema = import_zod3.z.object({
2603
- select: projectionSchema.optional(),
2604
- populate: populateSchema.optional(),
2605
- include: includeSchema.optional(),
2606
- tasks: tasksSchema.optional(),
2607
- options: import_zod3.z.object({
2608
- skim: import_zod3.z.boolean().optional(),
2609
- includePermissions: import_zod3.z.boolean().optional(),
2610
- includeFieldPermissions: import_zod3.z.boolean().optional(),
2611
- tryList: import_zod3.z.boolean().optional(),
2612
- populateAccess: populateAccessSchema.optional()
2613
- }).passthrough().optional()
2614
- }).passthrough();
2615
- var advancedCreateBodySchema = import_zod3.z.object({
2616
- data: import_zod3.z.unknown(),
2617
- select: projectionSchema.optional(),
2618
- populate: populateSchema.optional(),
2619
- tasks: tasksSchema.optional(),
2620
- options: import_zod3.z.object({
2621
- includePermissions: import_zod3.z.boolean().optional(),
2622
- includeFieldPermissions: import_zod3.z.boolean().optional(),
2623
- populateAccess: populateAccessSchema.optional()
2624
- }).passthrough().optional()
2625
- }).passthrough();
2626
- var createBodySchema = import_zod3.z.union([
2627
- import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()),
2628
- import_zod3.z.array(import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()))
2629
- ]);
2630
- var updateBodySchema = import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown());
2631
- var advancedUpdateBodySchema = import_zod3.z.object({
2632
- data: import_zod3.z.unknown(),
2633
- select: projectionSchema.optional(),
2634
- populate: populateSchema.optional(),
2635
- tasks: tasksSchema.optional(),
2636
- options: import_zod3.z.object({
2637
- returningAll: import_zod3.z.boolean().optional(),
2638
- includePermissions: import_zod3.z.boolean().optional(),
2639
- includeFieldPermissions: import_zod3.z.boolean().optional(),
2640
- populateAccess: populateAccessSchema.optional()
2641
- }).passthrough().optional()
2642
- }).passthrough();
2643
- var upsertBodySchema = import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown());
2644
- var advancedUpsertBodySchema = import_zod3.z.object({
2645
- data: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()),
2646
- select: projectionSchema.optional(),
2647
- populate: populateSchema.optional(),
2648
- tasks: tasksSchema.optional(),
2649
- options: import_zod3.z.object({
2650
- returningAll: import_zod3.z.boolean().optional(),
2651
- includePermissions: import_zod3.z.boolean().optional(),
2652
- includeFieldPermissions: import_zod3.z.boolean().optional(),
2653
- populateAccess: populateAccessSchema.optional()
2654
- }).passthrough().optional()
2655
- }).passthrough();
2656
- var distinctBodySchema = import_zod3.z.object({
2657
- filter: objectOrArraySchema.optional()
2658
- }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query"]));
2659
- var subListBodySchema = import_zod3.z.object({
2660
- filter: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional(),
2661
- select: fieldsSchema.optional()
2662
- }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["fields"]));
2663
- var subMutationBodySchema = import_zod3.z.union([
2664
- import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()),
2665
- import_zod3.z.array(import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()))
2666
- ]);
2667
- var subReadBodySchema = import_zod3.z.object({
2668
- select: fieldsSchema.optional(),
2669
- populate: subPopulateSchema.optional()
2670
- }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["fields"]));
2967
+ var listQuerySchema = publicBoundarySchema(
2968
+ import_zod3.z.object({
2969
+ skip: nonNegativeIntegerString.optional(),
2970
+ limit: positiveIntegerString.optional(),
2971
+ page: nonNegativeIntegerString.optional(),
2972
+ page_size: positiveIntegerString.optional(),
2973
+ skim: queryBooleanString.optional(),
2974
+ include_permissions: queryBooleanString.optional(),
2975
+ include_field_permissions: queryBooleanString.optional(),
2976
+ include_count: queryBooleanString.optional(),
2977
+ include_extra_headers: queryBooleanString.optional(),
2978
+ select: stringOrStringArray.optional(),
2979
+ sort: import_zod3.z.string().optional().describe("Space-separated sort fields; prefix a field with - for descending order.")
2980
+ }).passthrough()
2981
+ );
2982
+ var createQuerySchema = publicBoundarySchema(
2983
+ import_zod3.z.object({
2984
+ include_permissions: queryBooleanString.optional(),
2985
+ include_field_permissions: queryBooleanString.optional()
2986
+ }).passthrough()
2987
+ );
2988
+ var readQuerySchema = publicBoundarySchema(
2989
+ import_zod3.z.object({
2990
+ include_permissions: queryBooleanString.optional(),
2991
+ include_field_permissions: queryBooleanString.optional(),
2992
+ try_list: queryBooleanString.optional(),
2993
+ select: stringOrStringArray.optional()
2994
+ }).passthrough()
2995
+ );
2996
+ var updateQuerySchema = publicBoundarySchema(
2997
+ import_zod3.z.object({
2998
+ returning_all: queryBooleanString.optional(),
2999
+ include_permissions: queryBooleanString.optional(),
3000
+ include_field_permissions: queryBooleanString.optional(),
3001
+ select: stringOrStringArray.optional()
3002
+ }).passthrough()
3003
+ );
3004
+ var upsertQuerySchema = publicBoundarySchema(
3005
+ import_zod3.z.object({
3006
+ returning_all: queryBooleanString.optional(),
3007
+ include_permissions: queryBooleanString.optional(),
3008
+ include_field_permissions: queryBooleanString.optional()
3009
+ }).passthrough()
3010
+ );
3011
+ var listBodySchema = publicBoundarySchema(
3012
+ import_zod3.z.object({
3013
+ filter: objectOrArraySchema.optional(),
3014
+ select: projectionSchema.optional(),
3015
+ sort: sortSchema.optional(),
3016
+ populate: populateSchema.optional(),
3017
+ include: includeSchema.optional(),
3018
+ tasks: tasksSchema.optional(),
3019
+ skip: import_zod3.z.union([nonNegativeIntegerSchema, nonNegativeIntegerString]).optional(),
3020
+ limit: import_zod3.z.union([positiveIntegerSchema, positiveIntegerString]).optional(),
3021
+ page: import_zod3.z.union([nonNegativeIntegerSchema, nonNegativeIntegerString]).optional(),
3022
+ pageSize: import_zod3.z.union([positiveIntegerSchema, positiveIntegerString]).optional(),
3023
+ options: import_zod3.z.object({
3024
+ skim: import_zod3.z.boolean().optional(),
3025
+ includePermissions: import_zod3.z.boolean().optional(),
3026
+ includeFieldPermissions: import_zod3.z.boolean().optional(),
3027
+ includeCount: import_zod3.z.boolean().optional(),
3028
+ includeExtraHeaders: import_zod3.z.boolean().optional(),
3029
+ populateAccess: populateAccessSchema.optional()
3030
+ }).passthrough().optional()
3031
+ }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query"]))
3032
+ );
3033
+ var countBodySchema = publicBoundarySchema(
3034
+ import_zod3.z.object({
3035
+ filter: objectOrArraySchema.optional()
3036
+ }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query", "access", "options", "include"]))
3037
+ );
3038
+ var readFilterBodySchema = publicBoundarySchema(
3039
+ import_zod3.z.object({
3040
+ filter: objectOrArraySchema.optional(),
3041
+ select: projectionSchema.optional(),
3042
+ sort: sortSchema.optional(),
3043
+ populate: populateSchema.optional(),
3044
+ include: includeSchema.optional(),
3045
+ tasks: tasksSchema.optional(),
3046
+ options: import_zod3.z.object({
3047
+ skim: import_zod3.z.boolean().optional(),
3048
+ includePermissions: import_zod3.z.boolean().optional(),
3049
+ includeFieldPermissions: import_zod3.z.boolean().optional(),
3050
+ tryList: import_zod3.z.boolean().optional(),
3051
+ populateAccess: populateAccessSchema.optional()
3052
+ }).passthrough().optional()
3053
+ }).passthrough()
3054
+ );
3055
+ var readByIdBodySchema = publicBoundarySchema(
3056
+ import_zod3.z.object({
3057
+ select: projectionSchema.optional(),
3058
+ populate: populateSchema.optional(),
3059
+ include: includeSchema.optional(),
3060
+ tasks: tasksSchema.optional(),
3061
+ options: import_zod3.z.object({
3062
+ skim: import_zod3.z.boolean().optional(),
3063
+ includePermissions: import_zod3.z.boolean().optional(),
3064
+ includeFieldPermissions: import_zod3.z.boolean().optional(),
3065
+ tryList: import_zod3.z.boolean().optional(),
3066
+ populateAccess: populateAccessSchema.optional()
3067
+ }).passthrough().optional()
3068
+ }).passthrough()
3069
+ );
3070
+ var advancedCreateBodySchema = publicBoundarySchema(
3071
+ import_zod3.z.object({
3072
+ data: import_zod3.z.unknown(),
3073
+ select: projectionSchema.optional(),
3074
+ populate: populateSchema.optional(),
3075
+ tasks: tasksSchema.optional(),
3076
+ options: import_zod3.z.object({
3077
+ includePermissions: import_zod3.z.boolean().optional(),
3078
+ includeFieldPermissions: import_zod3.z.boolean().optional(),
3079
+ populateAccess: populateAccessSchema.optional()
3080
+ }).passthrough().optional()
3081
+ }).passthrough()
3082
+ );
3083
+ var createBodySchema = publicBoundarySchema(
3084
+ import_zod3.z.union([import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()), import_zod3.z.array(import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()))]),
3085
+ "data"
3086
+ );
3087
+ var updateBodySchema = publicBoundarySchema(import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()), "data");
3088
+ var advancedUpdateBodySchema = publicBoundarySchema(
3089
+ import_zod3.z.object({
3090
+ data: import_zod3.z.unknown(),
3091
+ select: projectionSchema.optional(),
3092
+ populate: populateSchema.optional(),
3093
+ tasks: tasksSchema.optional(),
3094
+ options: import_zod3.z.object({
3095
+ returningAll: import_zod3.z.boolean().optional(),
3096
+ includePermissions: import_zod3.z.boolean().optional(),
3097
+ includeFieldPermissions: import_zod3.z.boolean().optional(),
3098
+ populateAccess: populateAccessSchema.optional()
3099
+ }).passthrough().optional()
3100
+ }).passthrough()
3101
+ );
3102
+ var upsertBodySchema = publicBoundarySchema(import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()), "data");
3103
+ var advancedUpsertBodySchema = publicBoundarySchema(
3104
+ import_zod3.z.object({
3105
+ data: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()),
3106
+ select: projectionSchema.optional(),
3107
+ populate: populateSchema.optional(),
3108
+ tasks: tasksSchema.optional(),
3109
+ options: import_zod3.z.object({
3110
+ returningAll: import_zod3.z.boolean().optional(),
3111
+ includePermissions: import_zod3.z.boolean().optional(),
3112
+ includeFieldPermissions: import_zod3.z.boolean().optional(),
3113
+ populateAccess: populateAccessSchema.optional()
3114
+ }).passthrough().optional()
3115
+ }).passthrough()
3116
+ );
3117
+ var distinctBodySchema = publicBoundarySchema(
3118
+ import_zod3.z.object({
3119
+ filter: objectOrArraySchema.optional()
3120
+ }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query"]))
3121
+ );
3122
+ var subListBodySchema = publicBoundarySchema(
3123
+ import_zod3.z.object({
3124
+ filter: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional(),
3125
+ select: fieldsSchema.optional()
3126
+ }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["fields"]))
3127
+ );
3128
+ var subMutationBodySchema = publicBoundarySchema(
3129
+ import_zod3.z.union([import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()), import_zod3.z.array(import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()))]),
3130
+ "data"
3131
+ );
3132
+ var subReadBodySchema = publicBoundarySchema(
3133
+ import_zod3.z.object({
3134
+ select: fieldsSchema.optional(),
3135
+ populate: subPopulateSchema.optional()
3136
+ }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["fields"]))
3137
+ );
2671
3138
  var requestSchemas = {
2672
3139
  listQuery: listQuerySchema,
2673
3140
  createQuery: createQuerySchema,
@@ -2722,8 +3189,7 @@ var rootModelListOptionsSchema = import_zod5.z.object({
2722
3189
  includePermissions: import_zod5.z.boolean().optional(),
2723
3190
  includeFieldPermissions: import_zod5.z.boolean().optional(),
2724
3191
  includeCount: import_zod5.z.boolean().optional(),
2725
- populateAccess: populateAccessSchema.optional(),
2726
- lean: import_zod5.z.boolean().optional()
3192
+ populateAccess: populateAccessSchema.optional()
2727
3193
  }).passthrough();
2728
3194
  var rootModelReadArgsSchema = import_zod5.z.object({
2729
3195
  select: projectionSchema.optional(),
@@ -2739,8 +3205,7 @@ var rootModelReadOptionsSchema = import_zod5.z.object({
2739
3205
  includePermissions: import_zod5.z.boolean().optional(),
2740
3206
  includeFieldPermissions: import_zod5.z.boolean().optional(),
2741
3207
  tryList: import_zod5.z.boolean().optional(),
2742
- populateAccess: populateAccessSchema.optional(),
2743
- lean: import_zod5.z.boolean().optional()
3208
+ populateAccess: populateAccessSchema.optional()
2744
3209
  }).passthrough();
2745
3210
  var rootModelCreateArgsSchema = import_zod5.z.object({
2746
3211
  select: projectionSchema.optional(),
@@ -2945,7 +3410,9 @@ var rootDataQueryEntrySchema = import_zod5.z.union([
2945
3410
  args: rootDataReadArgsSchema.optional()
2946
3411
  }).passthrough()
2947
3412
  ]);
2948
- var rootQuerySchema = import_zod5.z.array(import_zod5.z.union([rootModelQueryEntrySchema, rootDataQueryEntrySchema]));
3413
+ var rootQuerySchema = publicBoundarySchema(
3414
+ import_zod5.z.array(import_zod5.z.union([rootModelQueryEntrySchema, rootDataQueryEntrySchema]))
3415
+ );
2949
3416
  // Annotate the CommonJS export names for ESM import in node:
2950
3417
  0 && (module.exports = {
2951
3418
  Codes,