@web-ts-toolkit/access-router 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -36,7 +36,19 @@ __export(index_exports, {
36
36
  acl: () => acl,
37
37
  combineRoutes: () => combineRoutes,
38
38
  createAccessRuntime: () => createAccessRuntime,
39
+ createOpenApiRouter: () => createOpenApiRouter,
39
40
  default: () => index_default,
41
+ defineRequestSchema: () => defineRequestSchema,
42
+ fromAjv: () => fromAjv,
43
+ fromArkType: () => fromArkType,
44
+ fromIoTs: () => fromIoTs,
45
+ fromJoi: () => fromJoi,
46
+ fromStandardSchema: () => fromStandardSchema,
47
+ fromSuperstruct: () => fromSuperstruct,
48
+ fromValibot: () => fromValibot,
49
+ fromVine: () => fromVine,
50
+ fromYup: () => fromYup,
51
+ fromZod: () => fromZod,
40
52
  getDefaultModelOption: () => getDefaultModelOption,
41
53
  getDefaultModelOptions: () => getDefaultModelOptions,
42
54
  getGlobalOption: () => getGlobalOption,
@@ -55,19 +67,19 @@ __export(index_exports, {
55
67
  setModelOptions: () => setModelOptions
56
68
  });
57
69
  module.exports = __toCommonJS(index_exports);
58
- var import_utils22 = require("@web-ts-toolkit/utils");
70
+ var import_utils27 = require("@web-ts-toolkit/utils");
59
71
 
60
72
  // src/middleware.ts
61
73
  var import_express_json_router2 = __toESM(require("@web-ts-toolkit/express-json-router"));
62
- var import_utils17 = require("@web-ts-toolkit/utils");
74
+ var import_utils20 = require("@web-ts-toolkit/utils");
63
75
 
64
76
  // src/core.ts
65
- var import_utils16 = require("@web-ts-toolkit/utils");
77
+ var import_utils19 = require("@web-ts-toolkit/utils");
66
78
 
67
79
  // src/runtime.ts
68
- var import_mongoose2 = __toESM(require("mongoose"));
80
+ var import_mongoose3 = __toESM(require("mongoose"));
69
81
  var import_mongoose_schema_jsonschema = __toESM(require("mongoose-schema-jsonschema"));
70
- var import_utils7 = require("@web-ts-toolkit/utils");
82
+ var import_utils10 = require("@web-ts-toolkit/utils");
71
83
 
72
84
  // src/helpers/collection.ts
73
85
  var import_sift = __toESM(require("sift"));
@@ -86,20 +98,11 @@ var findElementById = (collection, id) => {
86
98
  };
87
99
 
88
100
  // src/helpers/document.ts
89
- var import_utils4 = require("@web-ts-toolkit/utils");
90
-
91
- // src/lib.ts
92
101
  var import_mongoose = require("mongoose");
93
- var import_utils2 = require("@web-ts-toolkit/utils");
94
- var isSchema = (val) => val instanceof import_mongoose.Schema;
95
- var isObjectIdType = (val) => val === "ObjectId" || val === import_mongoose.Schema.Types.ObjectId;
96
- var isReference = (val) => (0, import_utils2.isPlainObject)(val) && !!val.ref && isObjectIdType(val.type);
97
- var isDocument = function isDocument2(doc) {
98
- return doc instanceof import_mongoose.Document;
99
- };
102
+ var import_utils3 = require("@web-ts-toolkit/utils");
100
103
 
101
104
  // src/helpers/query.ts
102
- var import_utils3 = require("@web-ts-toolkit/utils");
105
+ var import_utils2 = require("@web-ts-toolkit/utils");
103
106
  function genPagination({
104
107
  skip,
105
108
  limit,
@@ -108,10 +111,10 @@ function genPagination({
108
111
  }, hardLimit) {
109
112
  let _skip = 0;
110
113
  let _limit = Number(limit ?? pageSize);
111
- if ((0, import_utils3.isNaN)(_limit) || _limit > hardLimit) _limit = hardLimit;
112
- if (!(0, import_utils3.isNil)(skip)) {
114
+ if ((0, import_utils2.isNaN)(_limit) || _limit > hardLimit) _limit = hardLimit;
115
+ if (!(0, import_utils2.isNil)(skip)) {
113
116
  _skip = Number(skip);
114
- } else if (!(0, import_utils3.isNil)(page)) {
117
+ } else if (!(0, import_utils2.isNil)(page)) {
115
118
  const npage = Number(page);
116
119
  if (npage > 1) _skip = (npage - 1) * _limit;
117
120
  }
@@ -126,9 +129,9 @@ function parseSortString(sortString) {
126
129
  }
127
130
  }
128
131
  function normalizeSelect(select) {
129
- if (Array.isArray(select)) return (0, import_utils3.flattenDeep)(select.map(normalizeSelect));
130
- if ((0, import_utils3.isPlainObject)(select)) {
131
- return (0, import_utils3.reduce)(
132
+ if (Array.isArray(select)) return (0, import_utils2.flattenDeep)(select.map(normalizeSelect));
133
+ if ((0, import_utils2.isPlainObject)(select)) {
134
+ return (0, import_utils2.reduce)(
132
135
  select,
133
136
  (ret, val, key) => {
134
137
  if (val === 1) ret.push(key);
@@ -138,23 +141,27 @@ function normalizeSelect(select) {
138
141
  []
139
142
  );
140
143
  }
141
- if ((0, import_utils3.isString)(select)) return select.split(" ").map((v) => v.trim());
144
+ if ((0, import_utils2.isString)(select)) return select.split(" ").map((v) => v.trim());
142
145
  return [];
143
146
  }
144
147
 
145
148
  // src/helpers/document.ts
146
- function getDocValue(doc, path, defalutValue) {
149
+ var import_utils4 = require("@web-ts-toolkit/utils");
150
+ function isDocument(doc) {
151
+ return doc instanceof import_mongoose.Document;
152
+ }
153
+ function getDocValue(doc, path, defaultValue) {
147
154
  if (isDocument(doc)) {
148
- return (0, import_utils4.get)(doc._doc, path, defalutValue);
149
- } else if ((0, import_utils4.isPlainObject)(doc)) {
150
- return (0, import_utils4.get)(doc, path, defalutValue);
155
+ return (0, import_utils3.get)(doc._doc, path, defaultValue);
156
+ } else if ((0, import_utils3.isPlainObject)(doc)) {
157
+ return (0, import_utils3.get)(doc, path, defaultValue);
151
158
  }
152
159
  }
153
160
  function setDocValue(doc, path, value) {
154
161
  if (isDocument(doc)) {
155
- (0, import_utils4.set)(doc._doc, path, value);
156
- } else if ((0, import_utils4.isPlainObject)(doc)) {
157
- (0, import_utils4.set)(doc, path, value);
162
+ (0, import_utils3.set)(doc._doc, path, value);
163
+ } else if ((0, import_utils3.isPlainObject)(doc)) {
164
+ (0, import_utils3.set)(doc, path, value);
158
165
  }
159
166
  }
160
167
  function getDocPermissions(modelName, doc) {
@@ -166,10 +173,10 @@ function toObject(doc) {
166
173
  }
167
174
  function pickDocFields(doc, fields = []) {
168
175
  if (isDocument(doc)) {
169
- doc._doc = (0, import_utils4.pick)(doc._doc, fields);
176
+ doc._doc = (0, import_utils3.pick)(doc._doc, fields);
170
177
  return doc;
171
178
  } else {
172
- return (0, import_utils4.pick)(doc, fields);
179
+ return (0, import_utils3.pick)(doc, fields);
173
180
  }
174
181
  }
175
182
  async function populateDoc(doc, target) {
@@ -242,35 +249,47 @@ function handleResultError(result) {
242
249
  }
243
250
 
244
251
  // src/helpers/index.ts
252
+ var import_utils6 = require("@web-ts-toolkit/utils");
253
+
254
+ // src/lib.ts
255
+ var import_mongoose2 = require("mongoose");
245
256
  var import_utils5 = require("@web-ts-toolkit/utils");
257
+ var isSchema = (val) => val instanceof import_mongoose2.Schema;
258
+ var isObjectIdType = (val) => val === "ObjectId" || val === import_mongoose2.Schema.Types.ObjectId;
259
+ var isReference = (val) => (0, import_utils5.isPlainObject)(val) && !!val.ref && isObjectIdType(val.type);
260
+ var isDocument2 = function isDocument3(doc) {
261
+ return doc instanceof import_mongoose2.Document;
262
+ };
263
+
264
+ // src/helpers/index.ts
246
265
  function recurseObject(obj) {
247
266
  if (isSchema(obj)) {
248
267
  return buildRefs(obj.tree);
249
268
  }
250
- if (!(0, import_utils5.isObject)(obj)) return null;
269
+ if (!(0, import_utils6.isObject)(obj)) return null;
251
270
  if (isReference(obj)) {
252
271
  return obj.ref;
253
272
  }
254
273
  let ret = null;
255
- (0, import_utils5.forEach)(obj, (val) => {
274
+ (0, import_utils6.forEach)(obj, (val) => {
256
275
  ret = recurseObject(val);
257
- if (!(0, import_utils5.isEmpty)(ret)) {
276
+ if (!(0, import_utils6.isEmpty)(ret)) {
258
277
  return false;
259
278
  }
260
279
  });
261
280
  return ret;
262
281
  }
263
282
  function buildRefs(schema) {
264
- if (!(0, import_utils5.isObject)(schema)) return {};
283
+ if (!(0, import_utils6.isObject)(schema)) return {};
265
284
  const references = {};
266
- (0, import_utils5.forEach)(schema, (val, key) => {
285
+ (0, import_utils6.forEach)(schema, (val, key) => {
267
286
  const paths = recurseObject(val);
268
- if (!(0, import_utils5.isEmpty)(paths)) {
287
+ if (!(0, import_utils6.isEmpty)(paths)) {
269
288
  references[key] = paths;
270
289
  }
271
- const target = (0, import_utils5.isObject)(val) && "type" in val ? val.type ?? val : val;
272
- if ((0, import_utils5.isArray)(target) && target.length > 0) {
273
- if (isSchema(target[0]) || (0, import_utils5.isPlainObject)(target[0])) {
290
+ const target = (0, import_utils6.isObject)(val) && "type" in val ? val.type ?? val : val;
291
+ if ((0, import_utils6.isArray)(target) && target.length > 0) {
292
+ if (isSchema(target[0]) || (0, import_utils6.isPlainObject)(target[0])) {
274
293
  return;
275
294
  }
276
295
  }
@@ -278,12 +297,12 @@ function buildRefs(schema) {
278
297
  return references;
279
298
  }
280
299
  function buildSubPaths(schema) {
281
- if (!(0, import_utils5.isObject)(schema)) return [];
300
+ if (!(0, import_utils6.isObject)(schema)) return [];
282
301
  const subPaths = [];
283
- (0, import_utils5.forEach)(schema, (val, key) => {
284
- const target = (0, import_utils5.isObject)(val) && "type" in val ? val.type ?? val : val;
285
- if ((0, import_utils5.isArray)(target) && target.length > 0) {
286
- if (isSchema(target[0]) || (0, import_utils5.isPlainObject)(target[0]) && !isReference(target[0])) {
302
+ (0, import_utils6.forEach)(schema, (val, key) => {
303
+ const target = (0, import_utils6.isObject)(val) && "type" in val ? val.type ?? val : val;
304
+ if ((0, import_utils6.isArray)(target) && target.length > 0) {
305
+ if (isSchema(target[0]) || (0, import_utils6.isPlainObject)(target[0]) && !isReference(target[0])) {
287
306
  subPaths.push(key);
288
307
  }
289
308
  }
@@ -291,11 +310,11 @@ function buildSubPaths(schema) {
291
310
  return subPaths;
292
311
  }
293
312
  async function iterateQuery(query, handler) {
294
- if (!(0, import_utils5.isPlainObject)(query)) return query;
295
- if (!handler) return import_utils5.noop;
313
+ if (!(0, import_utils6.isPlainObject)(query)) return query;
314
+ if (!handler) return query;
296
315
  const queryObject = query;
297
- return (0, import_utils5.mapValuesAsync)(queryObject, async (val, key) => {
298
- if ((0, import_utils5.isPlainObject)(val)) {
316
+ return (0, import_utils6.mapValuesAsync)(queryObject, async (val, key) => {
317
+ if ((0, import_utils6.isPlainObject)(val)) {
299
318
  const plainValue = val;
300
319
  if (plainValue.$$sq) {
301
320
  return handler(0 /* SubQuery */, plainValue.$$sq, key);
@@ -305,7 +324,7 @@ async function iterateQuery(query, handler) {
305
324
  return iterateQuery(val, handler);
306
325
  }
307
326
  }
308
- if ((0, import_utils5.isArray)(val)) {
327
+ if ((0, import_utils6.isArray)(val)) {
309
328
  return Promise.all(val.map((v) => iterateQuery(v, handler)));
310
329
  }
311
330
  return val;
@@ -314,13 +333,259 @@ async function iterateQuery(query, handler) {
314
333
  var createValidator = (fn) => {
315
334
  const stringHandler = (key) => key.trim().split(" ").every((v) => fn(v));
316
335
  const arrayHandler = (arr) => arr.some((item) => {
317
- if ((0, import_utils5.isString)(item)) return stringHandler(item);
318
- else if ((0, import_utils5.isArray)(item)) return arrayHandler(item);
336
+ if ((0, import_utils6.isString)(item)) return stringHandler(item);
337
+ else if ((0, import_utils6.isArray)(item)) return arrayHandler(item);
319
338
  else return false;
320
339
  });
321
340
  return { stringHandler, arrayHandler };
322
341
  };
323
342
 
343
+ // src/openapi/build-spec.ts
344
+ var import_utils8 = require("@web-ts-toolkit/utils");
345
+
346
+ // src/openapi/responses.ts
347
+ var json = (schema) => ({
348
+ content: {
349
+ "application/json": {
350
+ schema
351
+ }
352
+ }
353
+ });
354
+ var problemJson = {
355
+ content: {
356
+ "application/problem+json": {
357
+ schema: {
358
+ type: "object",
359
+ properties: {
360
+ type: { type: "string" },
361
+ title: { type: "string" },
362
+ status: { type: "number" },
363
+ detail: { type: "string" },
364
+ errors: { type: "array", items: {} }
365
+ },
366
+ additionalProperties: true
367
+ }
368
+ }
369
+ }
370
+ };
371
+ var genericDataSchema = { type: "object", additionalProperties: true };
372
+ var genericListSchema = { type: "array", items: genericDataSchema };
373
+ var openApiResponses = {
374
+ single(description = "Success") {
375
+ return {
376
+ 200: { description, ...json(genericDataSchema) },
377
+ 400: { description: "Bad Request", ...problemJson },
378
+ 401: { description: "Unauthorized", ...problemJson },
379
+ 404: { description: "Not Found", ...problemJson }
380
+ };
381
+ },
382
+ list(description = "Success") {
383
+ return {
384
+ 200: { description, ...json(genericListSchema) },
385
+ 400: { description: "Bad Request", ...problemJson },
386
+ 401: { description: "Unauthorized", ...problemJson }
387
+ };
388
+ },
389
+ create(description = "Created") {
390
+ return {
391
+ 201: { description, ...json(genericDataSchema) },
392
+ 400: { description: "Bad Request", ...problemJson },
393
+ 401: { description: "Unauthorized", ...problemJson }
394
+ };
395
+ },
396
+ delete(description = "Deleted") {
397
+ return {
398
+ 200: { description, ...json(genericDataSchema) },
399
+ 400: { description: "Bad Request", ...problemJson },
400
+ 401: { description: "Unauthorized", ...problemJson },
401
+ 404: { description: "Not Found", ...problemJson }
402
+ };
403
+ },
404
+ batch(description = "Success") {
405
+ return {
406
+ 200: { description, ...json(genericListSchema) },
407
+ 400: { description: "Bad Request", ...problemJson },
408
+ 401: { description: "Unauthorized", ...problemJson }
409
+ };
410
+ }
411
+ };
412
+
413
+ // src/openapi/schemas.ts
414
+ var import_zod = require("zod");
415
+ var import_utils7 = require("@web-ts-toolkit/utils");
416
+ var fallbackObjectSchema = { type: "object", additionalProperties: true };
417
+ function patchOpenApiObjectSchema(source, properties) {
418
+ return {
419
+ kind: "objectProperties",
420
+ source,
421
+ properties
422
+ };
423
+ }
424
+ function defineOpenApiSchemaResolver(resolve) {
425
+ return {
426
+ kind: "schemaResolver",
427
+ resolve
428
+ };
429
+ }
430
+ function getNestedOpenApiSchemaDataSource(source) {
431
+ return (0, import_utils7.isPlainObject)(source) && "data" in source ? source.data : void 0;
432
+ }
433
+ function unwrapNestedOpenApiSchemaSource(source, fallback) {
434
+ if ((0, import_utils7.isPlainObject)(source) && ("default" in source || "data" in source)) {
435
+ return source.default ?? fallback;
436
+ }
437
+ return source ?? fallback;
438
+ }
439
+ function isOpenApiSchemaPatch(source) {
440
+ return (0, import_utils7.isPlainObject)(source) && source.kind === "objectProperties";
441
+ }
442
+ function isOpenApiSchemaResolver(source) {
443
+ return (0, import_utils7.isPlainObject)(source) && source.kind === "schemaResolver" && typeof source.resolve === "function";
444
+ }
445
+ function isJsonSchemaLike(source) {
446
+ return (0, import_utils7.isPlainObject)(source) && ("type" in source || "properties" in source || "$ref" in source || "anyOf" in source);
447
+ }
448
+ function hasOpenApiSchema(source) {
449
+ return (0, import_utils7.isPlainObject)(source) && isJsonSchemaLike(source.openapi);
450
+ }
451
+ function toOpenApiSchema(source) {
452
+ if (!source) return void 0;
453
+ const resolvedSource = isOpenApiSchemaResolver(source) ? source.resolve() : source;
454
+ if (!resolvedSource) return void 0;
455
+ if (isOpenApiSchemaPatch(resolvedSource)) {
456
+ const schema = toOpenApiSchema(resolvedSource.source) ?? { ...fallbackObjectSchema };
457
+ const properties = (0, import_utils7.isPlainObject)(schema.properties) ? { ...schema.properties } : {};
458
+ for (const [key, value] of Object.entries(resolvedSource.properties)) {
459
+ properties[key] = toOpenApiSchema(value) ?? fallbackObjectSchema;
460
+ }
461
+ return {
462
+ ...schema,
463
+ type: schema.type ?? "object",
464
+ properties
465
+ };
466
+ }
467
+ if (hasOpenApiSchema(resolvedSource)) {
468
+ return resolvedSource.openapi;
469
+ }
470
+ if (isJsonSchemaLike(resolvedSource)) {
471
+ return resolvedSource;
472
+ }
473
+ try {
474
+ return import_zod.z.toJSONSchema(resolvedSource);
475
+ } catch {
476
+ return fallbackObjectSchema;
477
+ }
478
+ }
479
+
480
+ // src/openapi/build-spec.ts
481
+ var openApiMediaType = "application/json";
482
+ var normalizePath = (path) => {
483
+ if (!path) return "/";
484
+ return path.startsWith("/") ? path : `/${path}`;
485
+ };
486
+ var toOpenApiPath = (path) => normalizePath(path).replace(/:([A-Za-z0-9_]+)/g, "{$1}");
487
+ var schemaToQueryParameters = (schema) => {
488
+ const jsonSchema = toOpenApiSchema(schema);
489
+ if (!jsonSchema || jsonSchema.type !== "object") return [];
490
+ const properties = (0, import_utils8.isPlainObject)(jsonSchema.properties) ? jsonSchema.properties : {};
491
+ const required = new Set(
492
+ (0, import_utils8.isArray)(jsonSchema.required) ? jsonSchema.required.filter((item) => typeof item === "string") : []
493
+ );
494
+ return Object.entries(properties).map(([name, value]) => ({
495
+ name,
496
+ in: "query",
497
+ required: required.has(name),
498
+ schema: value
499
+ }));
500
+ };
501
+ var schemaToPathParameters = (path, pathParams) => {
502
+ const names = [...toOpenApiPath(path).matchAll(/\{([^}]+)\}/g)].map((item) => item[1]);
503
+ return names.map((name) => ({
504
+ name,
505
+ in: "path",
506
+ required: true,
507
+ schema: (pathParams && name in pathParams ? toOpenApiSchema(pathParams[name]) : void 0) ?? { type: "string" }
508
+ }));
509
+ };
510
+ var getDefaultResponses = (route) => {
511
+ if (route.operationId === "root.query") return openApiResponses.batch();
512
+ if (route.method === "delete") return openApiResponses.delete();
513
+ if (route.operationId?.toLowerCase().includes("create")) return openApiResponses.create();
514
+ if (route.operationId?.toLowerCase().includes("list")) return openApiResponses.list();
515
+ if (route.operationId?.toLowerCase().includes("distinct")) return openApiResponses.list();
516
+ return openApiResponses.single();
517
+ };
518
+ var buildOperation = (route) => {
519
+ const queryParameters = schemaToQueryParameters(route.query);
520
+ const pathParameters = schemaToPathParameters(route.path, route.pathParams);
521
+ const bodySchema = toOpenApiSchema(route.body);
522
+ const responses = route.responses ?? getDefaultResponses(route);
523
+ const operation = {
524
+ operationId: route.operationId,
525
+ summary: route.summary,
526
+ description: route.description,
527
+ tags: route.tags,
528
+ deprecated: route.deprecated,
529
+ responses
530
+ };
531
+ const parameters = [...pathParameters, ...queryParameters];
532
+ if (parameters.length) {
533
+ operation.parameters = parameters;
534
+ }
535
+ if (bodySchema) {
536
+ operation.requestBody = {
537
+ required: true,
538
+ content: {
539
+ [openApiMediaType]: {
540
+ schema: bodySchema
541
+ }
542
+ }
543
+ };
544
+ }
545
+ if (route.acl) {
546
+ operation["x-access-router-acl"] = route.acl;
547
+ }
548
+ return operation;
549
+ };
550
+ function buildOpenApiSpec(routes, options) {
551
+ const paths = {};
552
+ const { servers, ...info } = options;
553
+ for (const route of routes) {
554
+ const path = toOpenApiPath(route.path);
555
+ if (!paths[path]) {
556
+ paths[path] = {};
557
+ }
558
+ paths[path][route.method] = buildOperation(route);
559
+ }
560
+ return {
561
+ openapi: "3.1.0",
562
+ info,
563
+ servers,
564
+ paths
565
+ };
566
+ }
567
+
568
+ // src/openapi/registry.ts
569
+ var OpenApiRegistry = class {
570
+ constructor() {
571
+ this.routes = [];
572
+ }
573
+ register(route) {
574
+ const existingIndex = this.routes.findIndex((item) => item.method === route.method && item.path === route.path);
575
+ if (existingIndex === -1) {
576
+ this.routes.push(route);
577
+ return;
578
+ }
579
+ this.routes[existingIndex] = route;
580
+ }
581
+ getRoutes() {
582
+ return [...this.routes];
583
+ }
584
+ getSpec(info) {
585
+ return buildOpenApiSpec(this.routes, info);
586
+ }
587
+ };
588
+
324
589
  // src/logger-default.ts
325
590
  var import_node_util = __toESM(require("util"));
326
591
  var import_winston = require("winston");
@@ -348,7 +613,7 @@ var defaultLogger = (0, import_winston.createLogger)({
348
613
  });
349
614
 
350
615
  // src/options/manager.ts
351
- var import_utils6 = require("@web-ts-toolkit/utils");
616
+ var import_utils9 = require("@web-ts-toolkit/utils");
352
617
  var getNestedOption = (manager, key, defaultValue) => {
353
618
  const keys2 = String(key).split(".");
354
619
  if (keys2.length === 1) {
@@ -385,26 +650,26 @@ var OptionsManager = class {
385
650
  return this;
386
651
  }
387
652
  get(key, defaultValue) {
388
- return (0, import_utils6.get)(this.currentOptions, key, defaultValue);
653
+ return (0, import_utils9.get)(this.currentOptions, key, defaultValue);
389
654
  }
390
655
  set(key, value) {
391
- (0, import_utils6.set)(this.currentOptions, key, value);
656
+ (0, import_utils9.set)(this.currentOptions, key, value);
392
657
  }
393
658
  fetch() {
394
659
  return { ...this.currentOptions };
395
660
  }
396
661
  assign(options) {
397
- (0, import_utils6.assign)(this.currentOptions, options);
662
+ (0, import_utils9.assign)(this.currentOptions, options);
398
663
  }
399
664
  onchange(key, func) {
400
- (0, import_utils6.set)(this.listeners, key, func);
665
+ (0, import_utils9.set)(this.listeners, key, func);
401
666
  return this;
402
667
  }
403
668
  };
404
669
 
405
670
  // src/runtime.ts
406
- (0, import_mongoose_schema_jsonschema.default)(import_mongoose2.default);
407
- var pluralize = import_mongoose2.default.pluralize();
671
+ (0, import_mongoose_schema_jsonschema.default)(import_mongoose3.default);
672
+ var pluralize = import_mongoose3.default.pluralize();
408
673
  var FIELD_ACCESS_KEYS = ["list", "create", "read", "update"];
409
674
  var defaultModelOptions = {
410
675
  basePath: null,
@@ -415,44 +680,44 @@ var defaultDataOptions = {
415
680
  queryRouteSegment: "__query"
416
681
  };
417
682
  var normalizeBasePath = (name, value) => {
418
- if ((0, import_utils7.isNil)(value)) {
683
+ if ((0, import_utils10.isNil)(value)) {
419
684
  return `/${pluralize(name)}`;
420
685
  }
421
- return (0, import_utils7.isString)(value) ? (0, import_utils7.addLeadingSlash)(value) : "";
686
+ return (0, import_utils10.isString)(value) ? (0, import_utils10.addLeadingSlash)(value) : "";
422
687
  };
423
688
  var hasModelPermission = (value, modelPermissionPrefix) => {
424
689
  if (!modelPermissionPrefix) {
425
690
  return true;
426
691
  }
427
- if ((0, import_utils7.isString)(value)) {
692
+ if ((0, import_utils10.isString)(value)) {
428
693
  return value.trim().split(" ").some((item) => item.startsWith(modelPermissionPrefix));
429
694
  }
430
- if ((0, import_utils7.isArray)(value)) {
695
+ if ((0, import_utils10.isArray)(value)) {
431
696
  return value.some((item) => {
432
- if ((0, import_utils7.isString)(item) || (0, import_utils7.isArray)(item)) {
697
+ if ((0, import_utils10.isString)(item) || (0, import_utils10.isArray)(item)) {
433
698
  return hasModelPermission(item, modelPermissionPrefix);
434
699
  }
435
700
  return true;
436
701
  });
437
702
  }
438
- return (0, import_utils7.isFunction)(value);
703
+ return (0, import_utils10.isFunction)(value);
439
704
  };
440
705
  var classifyPermissionSchema = (permissionSchema, modelPermissionPrefix) => {
441
706
  const schemaKeys = Object.keys(permissionSchema);
442
707
  const globalPermissionKeys = {};
443
708
  const modelPermissionKeys = {};
444
- (0, import_utils7.forEach)(schemaKeys, (schemaKey) => {
709
+ (0, import_utils10.forEach)(schemaKeys, (schemaKey) => {
445
710
  const schemaRule = permissionSchema[schemaKey];
446
- const ruleEntries = (0, import_utils7.isPlainObject)(schemaRule) ? Object.entries(schemaRule) : FIELD_ACCESS_KEYS.map((accessKey) => [accessKey, schemaRule]);
711
+ const ruleEntries = (0, import_utils10.isPlainObject)(schemaRule) ? Object.entries(schemaRule) : FIELD_ACCESS_KEYS.map((accessKey) => [accessKey, schemaRule]);
447
712
  for (let x = 0; x < ruleEntries.length; x++) {
448
713
  const [accessKey, value] = ruleEntries[x];
449
- if (!(0, import_utils7.isArray)(globalPermissionKeys[accessKey])) {
714
+ if (!(0, import_utils10.isArray)(globalPermissionKeys[accessKey])) {
450
715
  globalPermissionKeys[accessKey] = [];
451
716
  }
452
- if (!(0, import_utils7.isArray)(modelPermissionKeys[accessKey])) {
717
+ if (!(0, import_utils10.isArray)(modelPermissionKeys[accessKey])) {
453
718
  modelPermissionKeys[accessKey] = [];
454
719
  }
455
- if ((0, import_utils7.isBoolean)(value)) {
720
+ if ((0, import_utils10.isBoolean)(value)) {
456
721
  globalPermissionKeys[accessKey].push(schemaKey);
457
722
  return;
458
723
  }
@@ -493,6 +758,16 @@ var AccessRuntime = class {
493
758
  this.modelRefs = {};
494
759
  this.modelSubs = {};
495
760
  this.modelAtts = {};
761
+ this.openApiRegistry = new OpenApiRegistry();
762
+ }
763
+ registerOpenApiRoute(route) {
764
+ this.openApiRegistry.register(route);
765
+ }
766
+ getOpenApiRoutes() {
767
+ return this.openApiRegistry.getRoutes();
768
+ }
769
+ getOpenApiSpec(info) {
770
+ return this.openApiRegistry.getSpec(info);
496
771
  }
497
772
  setGlobalOptions(options) {
498
773
  this.globalOptions.assign(options);
@@ -519,7 +794,7 @@ var AccessRuntime = class {
519
794
  return this.defaultModelOptions.get(key, defaultValue);
520
795
  }
521
796
  createModelOptions(modelName) {
522
- const model = import_mongoose2.default.model(modelName);
797
+ const model = import_mongoose3.default.model(modelName);
523
798
  const manager = new OptionsManager({
524
799
  ...defaultModelOptions,
525
800
  modelName
@@ -536,7 +811,7 @@ var AccessRuntime = class {
536
811
  }).onchange("basePath", function(newval, key, target) {
537
812
  target[key] = normalizeBasePath(
538
813
  modelName,
539
- (0, import_utils7.isString)(newval) || (0, import_utils7.isNil)(newval) ? newval : void 0
814
+ (0, import_utils10.isString)(newval) || (0, import_utils10.isNil)(newval) ? newval : void 0
540
815
  );
541
816
  }).build();
542
817
  this.modelJsonSchemas[modelName] = model.jsonSchema();
@@ -594,7 +869,7 @@ var AccessRuntime = class {
594
869
  manager.onchange("basePath", function(newval, key, target) {
595
870
  target[key] = normalizeBasePath(
596
871
  dataName,
597
- (0, import_utils7.isString)(newval) || (0, import_utils7.isNil)(newval) ? newval : void 0
872
+ (0, import_utils10.isString)(newval) || (0, import_utils10.isNil)(newval) ? newval : void 0
598
873
  );
599
874
  }).build();
600
875
  return manager;
@@ -635,7 +910,7 @@ var AccessRuntime = class {
635
910
  if (modelName in this.modelRefs && modelName in this.modelSubs && modelName in this.modelAtts) {
636
911
  return;
637
912
  }
638
- const model = import_mongoose2.default.models[modelName];
913
+ const model = import_mongoose3.default.models[modelName];
639
914
  if (!model) {
640
915
  this.modelRefs[modelName] = this.modelRefs[modelName] ?? {};
641
916
  this.modelSubs[modelName] = this.modelSubs[modelName] ?? [];
@@ -645,26 +920,26 @@ var AccessRuntime = class {
645
920
  const schema = model.schema;
646
921
  this.modelRefs[modelName] = buildRefs(schema.tree);
647
922
  this.modelSubs[modelName] = buildSubPaths(schema.tree);
648
- this.modelAtts[modelName] = (0, import_utils7.keys)(schema.obj);
923
+ this.modelAtts[modelName] = (0, import_utils10.keys)(schema.obj);
649
924
  }
650
925
  getModelRef(modelName, refPath) {
651
926
  this.ensureModelMeta(modelName);
652
- return (0, import_utils7.get)(this.modelRefs, `${modelName}.${refPath}`, null);
927
+ return (0, import_utils10.get)(this.modelRefs, `${modelName}.${refPath}`, null);
653
928
  }
654
929
  getModelSub(modelName) {
655
930
  this.ensureModelMeta(modelName);
656
- return (0, import_utils7.get)(this.modelSubs, modelName, []);
931
+ return (0, import_utils10.get)(this.modelSubs, modelName, []);
657
932
  }
658
933
  getModelAtt(modelName) {
659
934
  this.ensureModelMeta(modelName);
660
- return (0, import_utils7.get)(this.modelAtts, modelName, []);
935
+ return (0, import_utils10.get)(this.modelAtts, modelName, []);
661
936
  }
662
937
  };
663
938
  var defaultRuntime = new AccessRuntime();
664
939
 
665
940
  // src/runtime-context.ts
666
941
  var import_node_async_hooks = require("async_hooks");
667
- var import_mongoose3 = __toESM(require("mongoose"));
942
+ var import_mongoose4 = __toESM(require("mongoose"));
668
943
  var ACCESS_RUNTIME = /* @__PURE__ */ Symbol("access-runtime");
669
944
  var runtimeStorage = new import_node_async_hooks.AsyncLocalStorage();
670
945
  function runWithRuntime(runtime, callback) {
@@ -674,13 +949,13 @@ function getActiveRuntime() {
674
949
  return runtimeStorage.getStore() ?? null;
675
950
  }
676
951
  function attachRuntimeToModel(modelName, runtime) {
677
- const model = import_mongoose3.default.models[modelName];
952
+ const model = import_mongoose4.default.models[modelName];
678
953
  if (model) {
679
954
  model[ACCESS_RUNTIME] = runtime;
680
955
  }
681
956
  }
682
957
  function getRuntimeForModelName(modelName) {
683
- const model = import_mongoose3.default.models[modelName];
958
+ const model = import_mongoose4.default.models[modelName];
684
959
  return model?.[ACCESS_RUNTIME] ?? null;
685
960
  }
686
961
 
@@ -757,16 +1032,16 @@ var getModelSub = (modelName) => {
757
1032
  };
758
1033
 
759
1034
  // src/services/base.ts
760
- var import_utils8 = require("@web-ts-toolkit/utils");
1035
+ var import_utils11 = require("@web-ts-toolkit/utils");
761
1036
  function validateClientFilter(filter2) {
762
1037
  const errors = [];
763
1038
  const blockedOperators = /* @__PURE__ */ new Set(["$where", "$expr", "$function", "$accumulator"]);
764
1039
  const visit = (value, path) => {
765
- if ((0, import_utils8.isArray)(value)) {
1040
+ if ((0, import_utils11.isArray)(value)) {
766
1041
  value.forEach((item, index) => visit(item, `${path}[${index}]`));
767
1042
  return;
768
1043
  }
769
- if (!(0, import_utils8.isPlainObject)(value)) return;
1044
+ if (!(0, import_utils11.isPlainObject)(value)) return;
770
1045
  Object.entries(value).forEach(([key, child]) => {
771
1046
  const nextPath = path ? `${path}.${key}` : key;
772
1047
  if (blockedOperators.has(key)) {
@@ -861,17 +1136,17 @@ var Base = class {
861
1136
  return validateClientFilter(filter2);
862
1137
  }
863
1138
  processInclude(include) {
864
- const includes = (0, import_utils8.compact)((0, import_utils8.castArray)(include)).filter(({ model, op, path, localField, foreignField }) => {
1139
+ const includes = (0, import_utils11.compact)((0, import_utils11.castArray)(include)).filter(({ model, op, path, localField, foreignField }) => {
865
1140
  return model && op && path && localField && foreignField;
866
1141
  });
867
1142
  let includeLocalFields = [];
868
1143
  let includePaths = [];
869
- (0, import_utils8.forEach)(includes, (inc) => {
1144
+ (0, import_utils11.forEach)(includes, (inc) => {
870
1145
  includeLocalFields.push(inc.localField);
871
1146
  includePaths.push(inc.path);
872
1147
  });
873
- includeLocalFields = (0, import_utils8.uniq)((0, import_utils8.compact)(includeLocalFields));
874
- includePaths = (0, import_utils8.uniq)((0, import_utils8.compact)(includePaths));
1148
+ includeLocalFields = (0, import_utils11.uniq)((0, import_utils11.compact)(includeLocalFields));
1149
+ includePaths = (0, import_utils11.uniq)((0, import_utils11.compact)(includePaths));
875
1150
  return {
876
1151
  includes,
877
1152
  includeLocalFields,
@@ -880,9 +1155,9 @@ var Base = class {
880
1155
  }
881
1156
  async includeDocs(docs, include) {
882
1157
  if (!include) return docs;
883
- const includes = (0, import_utils8.compact)((0, import_utils8.castArray)(include));
1158
+ const includes = (0, import_utils11.compact)((0, import_utils11.castArray)(include));
884
1159
  if (includes.length === 0) return docs;
885
- const isSingle = !(0, import_utils8.isArray)(docs);
1160
+ const isSingle = !(0, import_utils11.isArray)(docs);
886
1161
  if (isSingle) docs = [docs];
887
1162
  for (let x = 0; x < includes.length; x++) {
888
1163
  const include2 = includes[x];
@@ -899,10 +1174,10 @@ var Base = class {
899
1174
  const svc = this.req.macl.getPublicService(model);
900
1175
  if (!svc) return docs;
901
1176
  const includeLocalValues = [];
902
- (0, import_utils8.forEach)(docs, (doc, i) => {
903
- includeLocalValues.push((0, import_utils8.get)(doc, localField));
1177
+ (0, import_utils11.forEach)(docs, (doc, i) => {
1178
+ includeLocalValues.push((0, import_utils11.get)(doc, localField));
904
1179
  });
905
- const filter2 = { ..._filters ?? {}, [foreignField]: { $in: (0, import_utils8.flatten)(includeLocalValues) } };
1180
+ const filter2 = { ..._filters ?? {}, [foreignField]: { $in: (0, import_utils11.flatten)(includeLocalValues) } };
906
1181
  const result = await svc.find(filter2, args, {
907
1182
  ...options,
908
1183
  lean: true,
@@ -912,8 +1187,8 @@ var Base = class {
912
1187
  if (!result.success) return docs;
913
1188
  for (let y = 0; y < docs.length; y++) {
914
1189
  const doc = docs[y];
915
- const localValue = (0, import_utils8.get)(doc, localField);
916
- const filterFn = (row) => (0, import_utils8.intersectionBy)((0, import_utils8.castArray)(localValue), (0, import_utils8.castArray)((0, import_utils8.get)(row, foreignField)), String).length > 0;
1190
+ const localValue = (0, import_utils11.get)(doc, localField);
1191
+ const filterFn = (row) => (0, import_utils11.intersectionBy)((0, import_utils11.castArray)(localValue), (0, import_utils11.castArray)((0, import_utils11.get)(row, foreignField)), String).length > 0;
917
1192
  const matches = result.data.filter(filterFn);
918
1193
  setDocValue(doc, path, op === "list" ? matches : matches[0]);
919
1194
  }
@@ -925,7 +1200,7 @@ var Base = class {
925
1200
  if (!svc) return docs;
926
1201
  for (let y = 0; y < docs.length; y++) {
927
1202
  const doc = docs[y];
928
- const localValue = (0, import_utils8.get)(doc, localField);
1203
+ const localValue = (0, import_utils11.get)(doc, localField);
929
1204
  const filter2 = { ..._filters ?? {}, [foreignField]: localValue };
930
1205
  const result = await svc.count(filter2);
931
1206
  if (!result.success) continue;
@@ -967,28 +1242,45 @@ var Base = class {
967
1242
  if (!result.success) return null;
968
1243
  let ret = result.data;
969
1244
  if (sqOptions.path) {
970
- ret = (0, import_utils8.isArray)(ret) ? (0, import_utils8.flatten)(ret.map((v) => (0, import_utils8.get)(v, sqOptions.path))) : (0, import_utils8.get)(ret, sqOptions.path);
1245
+ ret = (0, import_utils11.isArray)(ret) ? (0, import_utils11.flatten)(ret.map((v) => (0, import_utils11.get)(v, sqOptions.path))) : (0, import_utils11.get)(ret, sqOptions.path);
971
1246
  }
972
1247
  if (sqOptions.compact) {
973
- ret = (0, import_utils8.compact)((0, import_utils8.castArray)(ret));
1248
+ ret = (0, import_utils11.compact)((0, import_utils11.castArray)(ret));
974
1249
  }
975
1250
  return ret;
976
1251
  }
977
- async handleDate(val, key) {
1252
+ handleDate(val, key) {
1253
+ if (val instanceof Date) return val;
1254
+ if (typeof val === "string" || typeof val === "number") return new Date(val);
978
1255
  return /* @__PURE__ */ new Date();
979
1256
  }
980
1257
  };
981
1258
 
982
1259
  // src/services/service.ts
983
- var import_utils10 = require("@web-ts-toolkit/utils");
1260
+ var import_utils13 = require("@web-ts-toolkit/utils");
984
1261
  var import_deep_diff = __toESM(require("deep-diff"));
985
1262
 
986
1263
  // src/model.ts
987
- var import_mongoose4 = __toESM(require("mongoose"));
1264
+ var import_mongoose5 = __toESM(require("mongoose"));
1265
+
1266
+ // src/logger.ts
1267
+ var passthrough = (level) => (...args) => {
1268
+ const globalLogger = getGlobalOption("logger");
1269
+ const target = globalLogger?.[level] ?? defaultLogger[level];
1270
+ return target.apply(globalLogger ?? defaultLogger, args);
1271
+ };
1272
+ var logger = {
1273
+ debug: passthrough("debug"),
1274
+ info: passthrough("info"),
1275
+ warn: passthrough("warn"),
1276
+ error: passthrough("error")
1277
+ };
1278
+
1279
+ // src/model.ts
988
1280
  var Model = class {
989
1281
  constructor(modelName) {
990
1282
  this.modelName = modelName;
991
- this.model = import_mongoose4.default.model(modelName);
1283
+ this.model = import_mongoose5.default.model(modelName);
992
1284
  if (!this.model) return;
993
1285
  this.model.schema.set("optimisticConcurrency", true);
994
1286
  const currVersionKey = this.model.schema.get("versionKey");
@@ -1014,12 +1306,15 @@ var Model = class {
1014
1306
  if (lean) builder.lean();
1015
1307
  return builder;
1016
1308
  }
1017
- // See https://github.com/Automattic/mongoose/blob/65b2d12a8f85f86136cfaf32947f338ba0c5f451/lib/query.js#L3011
1018
- validateSort(sort, logError = console.error) {
1309
+ validateSort(sort, logError = logger.error) {
1019
1310
  const validSortOrders = [1, -1, "asc", "ascending", "desc", "descending"];
1311
+ const fieldPathPattern = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*)*$/;
1312
+ const isValidFieldPath = (field) => fieldPathPattern.test(field);
1020
1313
  if (sort === null || sort === void 0) return true;
1021
1314
  if (typeof sort === "string") {
1022
- if (!/^[a-zA-Z0-9\s-]+/.test(sort)) {
1315
+ const fields = sort.trim().split(/\s+/).filter(Boolean);
1316
+ const isValid = fields.every((field) => isValidFieldPath(field.startsWith("-") ? field.slice(1) : field));
1317
+ if (!isValid) {
1023
1318
  logError("Invalid sort string:", sort);
1024
1319
  return false;
1025
1320
  }
@@ -1032,8 +1327,8 @@ var Model = class {
1032
1327
  return false;
1033
1328
  }
1034
1329
  const [key, order] = pair;
1035
- if (typeof key !== "string") {
1036
- logError("Invalid sort array key: must be string", key);
1330
+ if (typeof key !== "string" || !isValidFieldPath(key)) {
1331
+ logError("Invalid sort array key: must be a field path string", key);
1037
1332
  return false;
1038
1333
  }
1039
1334
  if (!validSortOrders.includes(order)) {
@@ -1045,7 +1340,11 @@ var Model = class {
1045
1340
  return isValid;
1046
1341
  }
1047
1342
  if (typeof sort === "object" && !(sort instanceof Map)) {
1048
- const isValid = Object.values(sort).every((order) => {
1343
+ const isValid = Object.entries(sort).every(([key, order]) => {
1344
+ if (!isValidFieldPath(key)) {
1345
+ logError("Invalid sort object key: must be a field path string", key);
1346
+ return false;
1347
+ }
1049
1348
  if (!validSortOrders.includes(order)) {
1050
1349
  logError('Invalid sort object value: must be 1, -1, "asc", or "desc"', order);
1051
1350
  return false;
@@ -1055,7 +1354,11 @@ var Model = class {
1055
1354
  return isValid;
1056
1355
  }
1057
1356
  if (sort instanceof Map) {
1058
- const isValid = Array.from(sort.values()).every((order) => {
1357
+ const isValid = Array.from(sort.entries()).every(([key, order]) => {
1358
+ if (!isValidFieldPath(key)) {
1359
+ logError("Invalid sort Map key: must be a field path string", key);
1360
+ return false;
1361
+ }
1059
1362
  if (!validSortOrders.includes(order)) {
1060
1363
  logError('Invalid sort Map value: must be 1, -1, "asc", or "desc"', order);
1061
1364
  return false;
@@ -1078,9 +1381,6 @@ var Model = class {
1078
1381
  if (lean) builder.lean();
1079
1382
  return builder;
1080
1383
  }
1081
- findOneAndDelete(filter2) {
1082
- return this.model.findOneAndDelete(filter2);
1083
- }
1084
1384
  exists(filter2) {
1085
1385
  if (!filter2) return null;
1086
1386
  return this.findOne(filter2).select("_id").lean();
@@ -1089,10 +1389,6 @@ var Model = class {
1089
1389
  countDocuments(filter2 = {}) {
1090
1390
  return this.model.countDocuments(filter2);
1091
1391
  }
1092
- // see https://mongoosejs.com/docs/api.html#model_Model.estimatedDocumentCount
1093
- estimatedDocumentCount() {
1094
- return this.model.estimatedDocumentCount();
1095
- }
1096
1392
  // see https://mongoosejs.com/docs/api.html#model_Model.distinct
1097
1393
  distinct(field, conditions = {}) {
1098
1394
  return this.model.distinct(field, conditions);
@@ -1100,40 +1396,27 @@ var Model = class {
1100
1396
  };
1101
1397
  var model_default = Model;
1102
1398
 
1103
- // src/logger.ts
1104
- var passthrough = (level) => (...args) => {
1105
- const globalLogger = getGlobalOption("logger");
1106
- const target = globalLogger?.[level] ?? defaultLogger[level];
1107
- return target.apply(globalLogger ?? defaultLogger, args);
1108
- };
1109
- var logger = {
1110
- debug: passthrough("debug"),
1111
- info: passthrough("info"),
1112
- warn: passthrough("warn"),
1113
- error: passthrough("error")
1114
- };
1115
-
1116
1399
  // src/services/model-subdocument-service.ts
1117
- var import_utils9 = require("@web-ts-toolkit/utils");
1400
+ var import_utils12 = require("@web-ts-toolkit/utils");
1118
1401
  async function listSub(service, id, sub, options) {
1119
1402
  const { filter: ft, select } = options ?? {};
1120
1403
  const parentDoc = await getParentDoc(service, id, sub, null, { access: "read" });
1121
1404
  if (!parentDoc) return { success: false, code: "not_found" /* NotFound */ };
1122
- let result = (0, import_utils9.get)(parentDoc, sub);
1405
+ let result = (0, import_utils12.get)(parentDoc, sub);
1123
1406
  const [subFilter, subSelect] = await Promise.all([
1124
1407
  service.genFilter(`subs.${sub}.list`, ft),
1125
1408
  service.genQuerySelect("list", select, false, [sub, "sub"])
1126
1409
  ]);
1127
1410
  if (subFilter === false) return { success: false, code: "forbidden" /* Forbidden */ };
1128
1411
  result = filterCollection(result, subFilter);
1129
- if (subSelect) result = result.map((v) => (0, import_utils9.pick)(toObject(v), subSelect.concat("_id")));
1412
+ if (subSelect) result = result.map((v) => (0, import_utils12.pick)(toObject(v), subSelect.concat("_id")));
1130
1413
  return { success: true, kind: "list", code: "success" /* Success */, data: result, count: result.length };
1131
1414
  }
1132
1415
  async function readSub(service, id, sub, subId, options) {
1133
1416
  const { select, populate } = options ?? {};
1134
1417
  const parentDoc = await getParentDoc(service, id, sub, { populate }, { access: "read" });
1135
1418
  if (!parentDoc) return { success: false, code: "not_found" /* NotFound */ };
1136
- const result = (0, import_utils9.get)(parentDoc, sub);
1419
+ const result = (0, import_utils12.get)(parentDoc, sub);
1137
1420
  const [subFilter, subSelect] = await Promise.all([
1138
1421
  service.genFilter(`subs.${sub}.read`, { _id: subId }),
1139
1422
  service.genQuerySelect("read", select, false, [sub, "sub"])
@@ -1141,13 +1424,13 @@ async function readSub(service, id, sub, subId, options) {
1141
1424
  if (subFilter === false) return { success: false, code: "forbidden" /* Forbidden */ };
1142
1425
  let subdoc = findElement(result, subFilter);
1143
1426
  if (!subdoc) return { success: false, code: "not_found" /* NotFound */ };
1144
- if (subSelect) subdoc = (0, import_utils9.pick)(toObject(subdoc), subSelect.concat(["_id"]));
1427
+ if (subSelect) subdoc = (0, import_utils12.pick)(toObject(subdoc), subSelect.concat(["_id"]));
1145
1428
  return { success: true, kind: "single", code: "success" /* Success */, data: subdoc };
1146
1429
  }
1147
1430
  async function updateSub(service, id, sub, subId, data) {
1148
1431
  const parentDoc = await getParentDoc(service, id, sub, null, { access: "update" });
1149
1432
  if (!parentDoc) return { success: false, code: "not_found" /* NotFound */ };
1150
- const result = (0, import_utils9.get)(parentDoc, sub);
1433
+ const result = (0, import_utils12.get)(parentDoc, sub);
1151
1434
  const [subFilter, subReadSelect, subUpdateSelect] = await Promise.all([
1152
1435
  service.genFilter(`subs.${sub}.update`, { _id: subId }),
1153
1436
  service.genQuerySelect("read", null, false, [sub, "sub"]),
@@ -1156,16 +1439,16 @@ async function updateSub(service, id, sub, subId, data) {
1156
1439
  if (subFilter === false) return { success: false, code: "forbidden" /* Forbidden */ };
1157
1440
  let subdoc = findElement(result, subFilter);
1158
1441
  if (!subdoc) return { success: false, code: "not_found" /* NotFound */ };
1159
- const allowedData = (0, import_utils9.pick)(data, subUpdateSelect);
1442
+ const allowedData = (0, import_utils12.pick)(data, subUpdateSelect);
1160
1443
  Object.assign(subdoc, allowedData);
1161
1444
  await parentDoc.save();
1162
- if (subReadSelect) subdoc = (0, import_utils9.pick)(toObject(subdoc), subReadSelect.concat(["_id"]));
1445
+ if (subReadSelect) subdoc = (0, import_utils12.pick)(toObject(subdoc), subReadSelect.concat(["_id"]));
1163
1446
  return { success: true, kind: "single", code: "success" /* Success */, data: subdoc };
1164
1447
  }
1165
1448
  async function bulkUpdateSub(service, id, sub, data) {
1166
1449
  const parentDoc = await getParentDoc(service, id, sub, null, { access: "update" });
1167
1450
  if (!parentDoc) return { success: false, code: "not_found" /* NotFound */ };
1168
- let result = (0, import_utils9.get)(parentDoc, sub);
1451
+ let result = (0, import_utils12.get)(parentDoc, sub);
1169
1452
  const [subFilter, subReadSelect, subUpdateSelect] = await Promise.all([
1170
1453
  service.genFilter(`subs.${sub}.update`, { _id: { $in: data.map((v) => v._id) } }),
1171
1454
  service.genQuerySelect("read", null, false, [sub, "sub"]),
@@ -1173,35 +1456,35 @@ async function bulkUpdateSub(service, id, sub, data) {
1173
1456
  ]);
1174
1457
  if (subFilter === false) return { success: false, code: "forbidden" /* Forbidden */ };
1175
1458
  result = filterCollection(result, subFilter);
1176
- (0, import_utils9.forEach)(result, (subdoc) => {
1459
+ (0, import_utils12.forEach)(result, (subdoc) => {
1177
1460
  const tdata = findElementById(data, subdoc._id);
1178
1461
  if (!tdata) return;
1179
- const allowedData = (0, import_utils9.pick)(tdata, subUpdateSelect);
1462
+ const allowedData = (0, import_utils12.pick)(tdata, subUpdateSelect);
1180
1463
  Object.assign(subdoc, allowedData);
1181
1464
  });
1182
1465
  await parentDoc.save();
1183
- if (subReadSelect) result = result.map((v) => (0, import_utils9.pick)(toObject(v), subReadSelect.concat(["_id"])));
1466
+ if (subReadSelect) result = result.map((v) => (0, import_utils12.pick)(toObject(v), subReadSelect.concat(["_id"])));
1184
1467
  return { success: true, kind: "list", code: "success" /* Success */, data: result, count: result.length };
1185
1468
  }
1186
1469
  async function createSub(service, id, sub, data, options) {
1187
1470
  const { addFirst } = options ?? {};
1188
1471
  const parentDoc = await getParentDoc(service, id, sub, null, { access: "update" });
1189
1472
  if (!parentDoc) return { success: false, code: "not_found" /* NotFound */ };
1190
- let result = (0, import_utils9.get)(parentDoc, sub);
1473
+ let result = (0, import_utils12.get)(parentDoc, sub);
1191
1474
  const [subCreateSelect, subReadSelect] = await Promise.all([
1192
1475
  service.genQuerySelect("create", null, false, [sub, "sub"]),
1193
1476
  service.genQuerySelect("read", null, false, [sub, "sub"])
1194
1477
  ]);
1195
- const allowedData = (0, import_utils9.pick)(data, subCreateSelect);
1478
+ const allowedData = (0, import_utils12.pick)(data, subCreateSelect);
1196
1479
  addFirst === true ? result.unshift(allowedData) : result.push(allowedData);
1197
1480
  await parentDoc.save();
1198
- if (subReadSelect) result = result.map((v) => (0, import_utils9.pick)(toObject(v), subReadSelect.concat(["_id"])));
1481
+ if (subReadSelect) result = result.map((v) => (0, import_utils12.pick)(toObject(v), subReadSelect.concat(["_id"])));
1199
1482
  return { success: true, kind: "list", code: "created" /* Created */, data: result, count: result.length };
1200
1483
  }
1201
1484
  async function deleteSub(service, id, sub, subId) {
1202
1485
  const parentDoc = await getParentDoc(service, id, sub, null, { access: "update" });
1203
1486
  if (!parentDoc) return { success: false, code: "not_found" /* NotFound */ };
1204
- const result = (0, import_utils9.get)(parentDoc, sub);
1487
+ const result = (0, import_utils12.get)(parentDoc, sub);
1205
1488
  const subFilter = await service.genFilter(`subs.${sub}.delete`, { _id: subId });
1206
1489
  if (subFilter === false) return { success: false, code: "forbidden" /* Forbidden */ };
1207
1490
  const subdoc = findElement(result, subFilter);
@@ -1336,7 +1619,7 @@ function resolveExistsOptions(service, options = {}) {
1336
1619
 
1337
1620
  // src/services/service.ts
1338
1621
  var assertModelDocument = (value, modelName, hookName) => {
1339
- if (isDocument(value)) {
1622
+ if (isDocument2(value)) {
1340
1623
  return value;
1341
1624
  }
1342
1625
  throw new Error(`${hookName} hook for model=${modelName} must return a Mongoose document instance`);
@@ -1430,7 +1713,7 @@ var Service = class extends Base {
1430
1713
  genPagination({ skip, limit, page, pageSize }, this.options.listHardLimit)
1431
1714
  ]);
1432
1715
  const finalSelect = normalizeSelect(_select);
1433
- const filteredPopulate = (0, import_utils10.isArray)(finalSelect) && (0, import_utils10.isArray)(_populate) ? _populate.filter((p) => finalSelect.includes(p.path.split(".")[0])) : _populate;
1716
+ const filteredPopulate = (0, import_utils13.isArray)(finalSelect) && (0, import_utils13.isArray)(_populate) ? _populate.filter((p) => finalSelect.includes(p.path.split(".")[0])) : _populate;
1434
1717
  const { includes, includeLocalFields, includePaths } = this.processInclude(include);
1435
1718
  const query = {
1436
1719
  filter: _filter,
@@ -1452,7 +1735,7 @@ var Service = class extends Base {
1452
1735
  originalDocumentSnapshot: toObject(doc),
1453
1736
  resolvedQuery: query
1454
1737
  }));
1455
- const _decorate = (0, import_utils10.isFunction)(decorate) ? decorate : (v) => v;
1738
+ const _decorate = (0, import_utils13.isFunction)(decorate) ? decorate : (v) => v;
1456
1739
  docs = await this.includeDocs(docs, includes);
1457
1740
  const fieldPermissionAccess = includePermissions ? await this.getFieldPermissionAccess(docs.map((doc) => doc._id)) : void 0;
1458
1741
  docs = await Promise.all(
@@ -1504,16 +1787,16 @@ var Service = class extends Base {
1504
1787
  resolvedQuery: resolvedPopulate.length > 0 ? { populate: resolvedPopulate } : {}
1505
1788
  };
1506
1789
  const allowedFields = await this.genAllowedFields(item, "create");
1507
- const allowedData = (0, import_utils10.pick)(item, allowedFields);
1790
+ const allowedData = (0, import_utils13.pick)(item, allowedFields);
1508
1791
  context.allowedFields = allowedFields;
1509
1792
  context.allowedData = allowedData;
1510
1793
  const validated = await this.validate(allowedData, "create", context);
1511
- if ((0, import_utils10.isBoolean)(validated)) {
1794
+ if ((0, import_utils13.isBoolean)(validated)) {
1512
1795
  if (!validated) {
1513
1796
  validationError = { success: false, code: "bad_request" /* BadRequest */ };
1514
1797
  return;
1515
1798
  }
1516
- } else if ((0, import_utils10.isArray)(validated)) {
1799
+ } else if ((0, import_utils13.isArray)(validated)) {
1517
1800
  if (validated.length > 0) {
1518
1801
  validationError = { success: false, code: "bad_request" /* BadRequest */, errors: validated };
1519
1802
  return;
@@ -1526,7 +1809,7 @@ var Service = class extends Base {
1526
1809
  })
1527
1810
  );
1528
1811
  if (validationError) return validationError;
1529
- const _decorate = (0, import_utils10.isFunction)(decorate) ? decorate : (v) => v;
1812
+ const _decorate = (0, import_utils13.isFunction)(decorate) ? decorate : (v) => v;
1530
1813
  const createdDocs = await this.model.create(items);
1531
1814
  const docs = await Promise.all(
1532
1815
  createdDocs.map(async (doc, index) => {
@@ -1597,13 +1880,13 @@ var Service = class extends Base {
1597
1880
  context.docPermissions = this.getDocPermissions(doc);
1598
1881
  context.currentDocument = doc;
1599
1882
  const allowedFields = await this.genAllowedFields(doc, "update");
1600
- const allowedData = (0, import_utils10.pick)(data, allowedFields);
1883
+ const allowedData = (0, import_utils13.pick)(data, allowedFields);
1601
1884
  context.allowedFields = allowedFields;
1602
1885
  context.allowedData = allowedData;
1603
1886
  const validated = await this.validate(allowedData, "update", context);
1604
- if ((0, import_utils10.isBoolean)(validated)) {
1887
+ if ((0, import_utils13.isBoolean)(validated)) {
1605
1888
  if (!validated) return { success: false, code: "bad_request" /* BadRequest */ };
1606
- } else if ((0, import_utils10.isArray)(validated)) {
1889
+ } else if ((0, import_utils13.isArray)(validated)) {
1607
1890
  if (validated.length > 0) return { success: false, code: "bad_request" /* BadRequest */, errors: validated };
1608
1891
  }
1609
1892
  const prepared = await this.prepare(allowedData, "update", context);
@@ -1616,10 +1899,10 @@ var Service = class extends Base {
1616
1899
  const diffExcludeFields = [this.options.documentPermissionField, "__v"];
1617
1900
  this.asServiceHookContext(context).diff = (d) => {
1618
1901
  context.changes = (0, import_deep_diff.default)(
1619
- (0, import_utils10.omit)(context.originalDocumentSnapshot, diffExcludeFields),
1620
- (0, import_utils10.omit)(d.toObject({ virtuals: false }), diffExcludeFields)
1902
+ (0, import_utils13.omit)(context.originalDocumentSnapshot, diffExcludeFields),
1903
+ (0, import_utils13.omit)(d.toObject({ virtuals: false }), diffExcludeFields)
1621
1904
  ) || [];
1622
- context.modifiedPaths = (0, import_utils10.uniq)(context.changes.map((di) => di.path.length > 0 ? di.path[0] : ""));
1905
+ context.modifiedPaths = (0, import_utils13.uniq)(context.changes.map((di) => di.path.length > 0 ? di.path[0] : ""));
1623
1906
  };
1624
1907
  doc = assertModelDocument(await this.afterPersist(doc, "update", context), this.modelName, "afterPersist");
1625
1908
  context.currentDocument = doc;
@@ -1635,7 +1918,7 @@ var Service = class extends Base {
1635
1918
  if (_populate) await populateDoc(doc, _populate);
1636
1919
  doc = await this.trimOutputFields(doc, "read", this.baseFieldsExt);
1637
1920
  let outputDoc = doc;
1638
- if ((0, import_utils10.isFunction)(decorate)) outputDoc = await decorate(outputDoc, context);
1921
+ if ((0, import_utils13.isFunction)(decorate)) outputDoc = await decorate(outputDoc, context);
1639
1922
  if (!includePermissions) outputDoc = this.addEmptyPermissions(outputDoc);
1640
1923
  return { success: true, kind: "single", code: "success" /* Success */, data: outputDoc, input: prepared };
1641
1924
  }
@@ -1799,7 +2082,7 @@ var Service = class extends Base {
1799
2082
  return resolveExistsOptions(this, options);
1800
2083
  }
1801
2084
  async getFieldPermissionAccess(ids) {
1802
- const uniqueIds = (0, import_utils10.uniq)(ids.map((id) => String(id)).filter(Boolean));
2085
+ const uniqueIds = (0, import_utils13.uniq)(ids.map((id) => String(id)).filter(Boolean));
1803
2086
  if (uniqueIds.length === 0) {
1804
2087
  return {
1805
2088
  readIds: /* @__PURE__ */ new Set(),
@@ -1829,7 +2112,7 @@ var Service = class extends Base {
1829
2112
  return updateSub(this, id, sub, subId, data);
1830
2113
  }
1831
2114
  async bulkUpdateSub(id, sub, data) {
1832
- return bulkUpdateSub(this, id, sub, (0, import_utils10.castArray)(data));
2115
+ return bulkUpdateSub(this, id, sub, (0, import_utils13.castArray)(data));
1833
2116
  }
1834
2117
  async createSub(id, sub, data, options) {
1835
2118
  return createSub(this, id, sub, data, options);
@@ -1843,7 +2126,7 @@ var Service = class extends Base {
1843
2126
  };
1844
2127
 
1845
2128
  // src/services/public-service.ts
1846
- var import_utils11 = require("@web-ts-toolkit/utils");
2129
+ var import_utils14 = require("@web-ts-toolkit/utils");
1847
2130
  var PublicService = class extends Service {
1848
2131
  async _list(filter2, args, options) {
1849
2132
  const { select, populate, include, sort, skip, limit, page, pageSize, tasks } = this.resolvePublicListArgs(args);
@@ -1882,7 +2165,7 @@ var PublicService = class extends Service {
1882
2165
  doc = toObject(doc);
1883
2166
  doc = await this.decorate(doc, "create", context);
1884
2167
  doc = this.runTasks(doc, tasks);
1885
- if (select) doc = (0, import_utils11.pick)(doc, [...normalizeSelect(select), ...this.baseFieldsExt]);
2168
+ if (select) doc = (0, import_utils14.pick)(doc, [...normalizeSelect(select), ...this.baseFieldsExt]);
1886
2169
  return doc;
1887
2170
  }
1888
2171
  );
@@ -1977,8 +2260,8 @@ var PublicService = class extends Service {
1977
2260
  doc = toObject(doc);
1978
2261
  doc = await this.decorate(doc, "update", context);
1979
2262
  doc = this.runTasks(doc, tasks);
1980
- if (select) doc = (0, import_utils11.pick)(doc, [...normalizeSelect(select), ...this.baseFieldsExt]);
1981
- else if (!returningAll) doc = (0, import_utils11.pick)(doc, [...Object.keys(data), "_id"]);
2263
+ if (select) doc = (0, import_utils14.pick)(doc, [...normalizeSelect(select), ...this.baseFieldsExt]);
2264
+ else if (!returningAll) doc = (0, import_utils14.pick)(doc, [...Object.keys(data), "_id"]);
1982
2265
  return doc;
1983
2266
  }
1984
2267
  );
@@ -2100,7 +2383,7 @@ var PublicService = class extends Service {
2100
2383
  };
2101
2384
 
2102
2385
  // src/services/data-service.ts
2103
- var import_utils12 = require("@web-ts-toolkit/utils");
2386
+ var import_utils15 = require("@web-ts-toolkit/utils");
2104
2387
  var DataService = class {
2105
2388
  constructor(req, dataName) {
2106
2389
  this.req = req;
@@ -2122,7 +2405,7 @@ var DataService = class {
2122
2405
  let doc = await findElement(this.data, _filter);
2123
2406
  if (!doc) return { success: false, code: "not_found" /* NotFound */, query };
2124
2407
  doc = await this.trimOutputFields(doc, access);
2125
- if (_select.length > 0) doc = (0, import_utils12.pick)(doc, _select);
2408
+ if (_select.length > 0) doc = (0, import_utils15.pick)(doc, _select);
2126
2409
  return { success: true, kind: "single", code: "success" /* Success */, data: doc, query };
2127
2410
  }
2128
2411
  async findById(id, args, options) {
@@ -2158,13 +2441,13 @@ var DataService = class {
2158
2441
  docs = await Promise.all(
2159
2442
  docs.map(async (doc) => {
2160
2443
  doc = await this.trimOutputFields(doc, "list");
2161
- if (_select.length > 0) doc = (0, import_utils12.pick)(doc, _select);
2444
+ if (_select.length > 0) doc = (0, import_utils15.pick)(doc, _select);
2162
2445
  return doc;
2163
2446
  })
2164
2447
  );
2165
2448
  if (sort) {
2166
2449
  const { sortKey, sortOrder } = parseSortString(sort);
2167
- docs = (0, import_utils12.orderBy)(docs, [sortKey], [sortOrder]);
2450
+ docs = (0, import_utils15.orderBy)(docs, [sortKey], [sortOrder]);
2168
2451
  }
2169
2452
  docs = docs.slice(query.skip, query.limit && query.skip + query.limit);
2170
2453
  return {
@@ -2207,29 +2490,29 @@ var DataService = class {
2207
2490
  };
2208
2491
 
2209
2492
  // src/processors.ts
2210
- var import_utils13 = require("@web-ts-toolkit/utils");
2493
+ var import_utils16 = require("@web-ts-toolkit/utils");
2211
2494
  var copyAndDepopulate = (docObject, operations, options = { mutable: true, idField: "_id" }) => {
2212
- const obj = (0, import_utils13.get)(options, "mutable", true) ? docObject : (0, import_utils13.cloneDeep)(docObject);
2213
- const idField = (0, import_utils13.get)(options, "idField", "_id");
2214
- (0, import_utils13.forEach)((0, import_utils13.castArray)(operations), (op) => {
2495
+ const obj = (0, import_utils16.get)(options, "mutable", true) ? docObject : (0, import_utils16.cloneDeep)(docObject);
2496
+ const idField = (0, import_utils16.get)(options, "idField", "_id");
2497
+ (0, import_utils16.forEach)((0, import_utils16.castArray)(operations), (op) => {
2215
2498
  if (!op.src || !op.dest) return;
2216
2499
  let targets = [obj];
2217
2500
  const segs = op.src.split(".");
2218
- (0, import_utils13.forEach)(segs, (seg, ind) => {
2501
+ (0, import_utils16.forEach)(segs, (seg, ind) => {
2219
2502
  if (segs.length === ind + 1) {
2220
- (0, import_utils13.forEach)(targets, (target) => {
2503
+ (0, import_utils16.forEach)(targets, (target) => {
2221
2504
  const targetObject = target;
2222
- (0, import_utils13.set)(targetObject, op.dest, (0, import_utils13.get)(targetObject, seg));
2223
- (0, import_utils13.set)(
2505
+ (0, import_utils16.set)(targetObject, op.dest, (0, import_utils16.get)(targetObject, seg));
2506
+ (0, import_utils16.set)(
2224
2507
  targetObject,
2225
2508
  seg,
2226
- (0, import_utils13.isArray)(targetObject[seg]) ? (0, import_utils13.map)(targetObject[seg], idField) : (0, import_utils13.get)(targetObject, `${seg}.${idField}`)
2509
+ (0, import_utils16.isArray)(targetObject[seg]) ? (0, import_utils16.map)(targetObject[seg], idField) : (0, import_utils16.get)(targetObject, `${seg}.${idField}`)
2227
2510
  );
2228
2511
  });
2229
2512
  } else {
2230
2513
  targets = targets.reduce((ret, target) => {
2231
2514
  const targetObject = target;
2232
- if ((0, import_utils13.isArray)(targetObject[seg])) ret.push(...targetObject[seg]);
2515
+ if ((0, import_utils16.isArray)(targetObject[seg])) ret.push(...targetObject[seg]);
2233
2516
  else ret.push(targetObject[seg]);
2234
2517
  return ret;
2235
2518
  }, []);
@@ -2277,7 +2560,7 @@ var Cache = class {
2277
2560
  };
2278
2561
 
2279
2562
  // src/core-shared.ts
2280
- var import_utils14 = require("@web-ts-toolkit/utils");
2563
+ var import_utils17 = require("@web-ts-toolkit/utils");
2281
2564
 
2282
2565
  // src/permission.ts
2283
2566
  var Permission = class {
@@ -2315,10 +2598,10 @@ var permission_default = Permission;
2315
2598
 
2316
2599
  // src/core-shared.ts
2317
2600
  function isAndFilter(filter2) {
2318
- return !!filter2 && (0, import_utils14.isPlainObject)(filter2) && Object.keys(filter2).length === 1 && (0, import_utils14.isArray)(filter2.$and);
2601
+ return !!filter2 && (0, import_utils17.isPlainObject)(filter2) && Object.keys(filter2).length === 1 && (0, import_utils17.isArray)(filter2.$and);
2319
2602
  }
2320
2603
  function isMergeableClause(filter2) {
2321
- return !!filter2 && (0, import_utils14.isPlainObject)(filter2) && Object.keys(filter2).every((key) => !key.startsWith("$"));
2604
+ return !!filter2 && (0, import_utils17.isPlainObject)(filter2) && Object.keys(filter2).every((key) => !key.startsWith("$"));
2322
2605
  }
2323
2606
  function optimizeAndFilter(clausesInput) {
2324
2607
  const clauses = [];
@@ -2333,7 +2616,7 @@ function optimizeAndFilter(clausesInput) {
2333
2616
  }
2334
2617
  }
2335
2618
  const dedupedClauses = clauses.filter(
2336
- (clause, index) => clauses.findIndex((item) => (0, import_utils14.isEqual)(item, clause)) === index
2619
+ (clause, index) => clauses.findIndex((item) => (0, import_utils17.isEqual)(item, clause)) === index
2337
2620
  );
2338
2621
  const mergedClause = {};
2339
2622
  const remainingClauses = [];
@@ -2345,7 +2628,7 @@ function optimizeAndFilter(clausesInput) {
2345
2628
  }
2346
2629
  let canMerge = true;
2347
2630
  for (const [key, value] of Object.entries(clause)) {
2348
- if (Object.prototype.hasOwnProperty.call(mergedClause, key) && !(0, import_utils14.isEqual)(mergedClause[key], value)) {
2631
+ if (Object.prototype.hasOwnProperty.call(mergedClause, key) && !(0, import_utils17.isEqual)(mergedClause[key], value)) {
2349
2632
  canMerge = false;
2350
2633
  break;
2351
2634
  }
@@ -2356,24 +2639,24 @@ function optimizeAndFilter(clausesInput) {
2356
2639
  }
2357
2640
  Object.assign(mergedClause, clause);
2358
2641
  }
2359
- const finalClauses = (0, import_utils14.isEmpty)(mergedClause) ? remainingClauses : [mergedClause, ...remainingClauses];
2642
+ const finalClauses = (0, import_utils17.isEmpty)(mergedClause) ? remainingClauses : [mergedClause, ...remainingClauses];
2360
2643
  if (finalClauses.length === 0) return null;
2361
2644
  if (finalClauses.length === 1) return finalClauses[0];
2362
2645
  return { $and: finalClauses };
2363
2646
  }
2364
2647
  function normalizeFilter(filter2) {
2365
2648
  if (filter2 === false) return false;
2366
- if (!filter2 || !(0, import_utils14.isPlainObject)(filter2) || (0, import_utils14.isEmpty)(filter2)) return null;
2649
+ if (!filter2 || !(0, import_utils17.isPlainObject)(filter2) || (0, import_utils17.isEmpty)(filter2)) return null;
2367
2650
  if (!isAndFilter(filter2)) {
2368
2651
  return filter2;
2369
2652
  }
2370
2653
  return optimizeAndFilter(filter2.$and);
2371
2654
  }
2372
2655
  async function resolveIdentifierFilter(req, idField, resolveIdFilter, id) {
2373
- if ((0, import_utils14.isFunction)(resolveIdFilter)) {
2656
+ if ((0, import_utils17.isFunction)(resolveIdFilter)) {
2374
2657
  return await resolveIdFilter.call(req, id);
2375
2658
  }
2376
- if ((0, import_utils14.isString)(idField)) {
2659
+ if ((0, import_utils17.isString)(idField)) {
2377
2660
  return { [idField]: id };
2378
2661
  }
2379
2662
  return { _id: id };
@@ -2389,11 +2672,11 @@ async function resolveAccessFilter({
2389
2672
  }) {
2390
2673
  let nextFilter = normalizeFilter(filter2);
2391
2674
  const overrideFilterFn = getOption(`overrideFilter.${access}`, null);
2392
- if ((0, import_utils14.isFunction)(overrideFilterFn)) {
2675
+ if ((0, import_utils17.isFunction)(overrideFilterFn)) {
2393
2676
  nextFilter = normalizeFilter(await overrideFilterFn.call(req, nextFilter, permissions));
2394
2677
  }
2395
2678
  const baseFilterFn = getOption(`baseFilter.${access}`, null);
2396
- if (!(0, import_utils14.isFunction)(baseFilterFn)) return nextFilter || {};
2679
+ if (!(0, import_utils17.isFunction)(baseFilterFn)) return nextFilter || {};
2397
2680
  const baseFilter = normalizeFilter(
2398
2681
  cache.has(cacheKey) ? cache.get(cacheKey) : await baseFilterFn.call(req, permissions)
2399
2682
  );
@@ -2413,33 +2696,33 @@ async function setRequestPermissions(req) {
2413
2696
  const requestPermissionField = getGlobalOption("requestPermissionField");
2414
2697
  if (req[requestPermissionField]) return;
2415
2698
  const globalPermissions = getGlobalOption("globalPermissions");
2416
- if (!(0, import_utils14.isFunction)(globalPermissions)) return;
2699
+ if (!(0, import_utils17.isFunction)(globalPermissions)) return;
2417
2700
  const permissions = await globalPermissions.call(req, req);
2418
- if ((0, import_utils14.isPlainObject)(permissions)) req[requestPermissionField] = permissions;
2419
- else if ((0, import_utils14.isArray)(permissions)) req[requestPermissionField] = (0, import_utils14.arrayToRecord)(permissions);
2420
- else if ((0, import_utils14.isString)(permissions)) req[requestPermissionField] = { [permissions]: true };
2701
+ if ((0, import_utils17.isPlainObject)(permissions)) req[requestPermissionField] = permissions;
2702
+ else if ((0, import_utils17.isArray)(permissions)) req[requestPermissionField] = (0, import_utils17.arrayToRecord)(permissions);
2703
+ else if ((0, import_utils17.isString)(permissions)) req[requestPermissionField] = { [permissions]: true };
2421
2704
  }
2422
2705
  async function evaluateRouteGuard(req, permissions, routeGuard) {
2423
2706
  const phas = (key) => permissions.has(key);
2424
2707
  const { stringHandler, arrayHandler } = createValidator(phas);
2425
- if ((0, import_utils14.isBoolean)(routeGuard)) {
2708
+ if ((0, import_utils17.isBoolean)(routeGuard)) {
2426
2709
  return routeGuard === true;
2427
2710
  }
2428
- if ((0, import_utils14.isString)(routeGuard)) {
2711
+ if ((0, import_utils17.isString)(routeGuard)) {
2429
2712
  return stringHandler(routeGuard);
2430
2713
  }
2431
- if ((0, import_utils14.isArray)(routeGuard)) {
2714
+ if ((0, import_utils17.isArray)(routeGuard)) {
2432
2715
  return arrayHandler(routeGuard);
2433
2716
  }
2434
- if ((0, import_utils14.isFunction)(routeGuard)) {
2717
+ if ((0, import_utils17.isFunction)(routeGuard)) {
2435
2718
  return routeGuard.call(req, permissions);
2436
2719
  }
2437
2720
  return false;
2438
2721
  }
2439
2722
  async function callHookChain(req, hook, doc, permissions, context) {
2440
- const hooks = (0, import_utils14.castArray)(hook);
2723
+ const hooks = (0, import_utils17.castArray)(hook);
2441
2724
  for (let x = 0; x < hooks.length; x++) {
2442
- if ((0, import_utils14.isFunction)(hooks[x])) {
2725
+ if ((0, import_utils17.isFunction)(hooks[x])) {
2443
2726
  doc = await hooks[x].call(req, doc, permissions, context);
2444
2727
  }
2445
2728
  }
@@ -2462,13 +2745,13 @@ async function collectSchemaFields({
2462
2745
  if (baseFields.includes(key)) continue;
2463
2746
  const val = permissionSchema[key];
2464
2747
  const value = val && val[access] || val;
2465
- if ((0, import_utils14.isBoolean)(value)) {
2748
+ if ((0, import_utils17.isBoolean)(value)) {
2466
2749
  if (value) fields.push(key);
2467
- } else if ((0, import_utils14.isString)(value)) {
2750
+ } else if ((0, import_utils17.isString)(value)) {
2468
2751
  if (stringHandler(value)) fields.push(key);
2469
- } else if ((0, import_utils14.isArray)(value)) {
2752
+ } else if ((0, import_utils17.isArray)(value)) {
2470
2753
  if (arrayHandler(value)) fields.push(key);
2471
- } else if ((0, import_utils14.isFunction)(value)) {
2754
+ } else if ((0, import_utils17.isFunction)(value)) {
2472
2755
  if (await value.call(req, ...functionArgs)) fields.push(key);
2473
2756
  }
2474
2757
  }
@@ -2557,7 +2840,7 @@ async function runDecorateAllHook({
2557
2840
  }
2558
2841
 
2559
2842
  // src/acl/select-resolution.ts
2560
- var import_utils15 = require("@web-ts-toolkit/utils");
2843
+ var import_utils18 = require("@web-ts-toolkit/utils");
2561
2844
  async function collectAllowedFieldsForRequest({
2562
2845
  req,
2563
2846
  permissionSchema,
@@ -2625,15 +2908,15 @@ async function resolveSelectForRequest({
2625
2908
  const excludeall = normalizedSelect.every((v) => v.startsWith("-"));
2626
2909
  if (excludeall) {
2627
2910
  normalizedSelect = normalizedSelect.map((v) => v.substring(1));
2628
- fields = (0, import_utils15.difference)(fields, normalizedSelect);
2911
+ fields = (0, import_utils18.difference)(fields, normalizedSelect);
2629
2912
  if (excludeid) fields.push("-_id");
2630
2913
  } else {
2631
- fields = (0, import_utils15.intersection)(normalizedSelect, fields.concat(excludeid ? "-_id" : "_id"));
2914
+ fields = (0, import_utils18.intersection)(normalizedSelect, fields.concat(excludeid ? "-_id" : "_id"));
2632
2915
  }
2633
2916
  }
2634
2917
  return fields.concat(alwaysSelectFields);
2635
2918
  }
2636
- return (0, import_utils15.intersection)(normalizedSelect, fields);
2919
+ return (0, import_utils18.intersection)(normalizedSelect, fields);
2637
2920
  }
2638
2921
 
2639
2922
  // src/core.ts
@@ -2647,10 +2930,10 @@ var Core = class {
2647
2930
  getIdentifier(modelName) {
2648
2931
  const resolveIdFilter = getModelOption(modelName, "resolveIdFilter");
2649
2932
  const idField = getModelOption(modelName, "idField");
2650
- if ((0, import_utils16.isFunction)(resolveIdFilter)) {
2933
+ if ((0, import_utils19.isFunction)(resolveIdFilter)) {
2651
2934
  return null;
2652
2935
  }
2653
- if ((0, import_utils16.isString)(idField)) {
2936
+ if ((0, import_utils19.isString)(idField)) {
2654
2937
  return idField;
2655
2938
  }
2656
2939
  return "_id";
@@ -2728,11 +3011,11 @@ var Core = class {
2728
3011
  async genPopulate(modelName, access = "read", _populate = null) {
2729
3012
  if (!_populate) return [];
2730
3013
  let populate = Array.isArray(_populate) ? _populate : [_populate];
2731
- populate = (0, import_utils16.compact)(
3014
+ populate = (0, import_utils19.compact)(
2732
3015
  await Promise.all(
2733
3016
  populate.map(async (p) => {
2734
- const populateAccess = !(0, import_utils16.isString)(p) && p.access ? p.access : access;
2735
- const ret = (0, import_utils16.isString)(p) ? { path: p } : {
3017
+ const populateAccess = !(0, import_utils19.isString)(p) && p.access ? p.access : access;
3018
+ const ret = (0, import_utils19.isString)(p) ? { path: p } : {
2736
3019
  path: p.path,
2737
3020
  select: normalizeSelect(p.select)
2738
3021
  };
@@ -2752,10 +3035,10 @@ var Core = class {
2752
3035
  }
2753
3036
  async validate(modelName, allowedData, access, context) {
2754
3037
  const validate = getModelOption(modelName, `validate.${access}`, null);
2755
- if ((0, import_utils16.isFunction)(validate)) {
3038
+ if ((0, import_utils19.isFunction)(validate)) {
2756
3039
  const permissions = this.getGlobalPermissions();
2757
3040
  return validate.call(this.req, allowedData, permissions, context);
2758
- } else if ((0, import_utils16.isBoolean)(validate) || (0, import_utils16.isArray)(validate)) {
3041
+ } else if ((0, import_utils19.isBoolean)(validate) || (0, import_utils19.isArray)(validate)) {
2759
3042
  return validate;
2760
3043
  } else {
2761
3044
  return true;
@@ -2780,7 +3063,7 @@ var Core = class {
2780
3063
  const changeOptions = getModelOption(modelName, `onChange`, {});
2781
3064
  for (let x = 0; x < context.modifiedPaths.length; x++) {
2782
3065
  const mpath = context.modifiedPaths[x];
2783
- if ((0, import_utils16.isFunction)(changeOptions[mpath])) {
3066
+ if ((0, import_utils19.isFunction)(changeOptions[mpath])) {
2784
3067
  await changeOptions[mpath].call(
2785
3068
  this.req,
2786
3069
  context.originalDocumentSnapshot[mpath],
@@ -2804,7 +3087,7 @@ var Core = class {
2804
3087
  async genDocPermissions(modelName, doc, access, context) {
2805
3088
  const docPermissionsFn = getModelOption(modelName, `docPermissions.${access}`, null);
2806
3089
  let docPermissions = {};
2807
- if ((0, import_utils16.isFunction)(docPermissionsFn)) {
3090
+ if ((0, import_utils19.isFunction)(docPermissionsFn)) {
2808
3091
  const permissions = this.getGlobalPermissions();
2809
3092
  try {
2810
3093
  docPermissions = await docPermissionsFn.call(this.req, doc, permissions, context);
@@ -2852,7 +3135,7 @@ var Core = class {
2852
3135
  readExists ? this.genAllowedFields(modelName, doc, "read") : [],
2853
3136
  updateExists ? this.genAllowedFields(modelName, doc, "update") : []
2854
3137
  ]);
2855
- const viewObj = (0, import_utils16.reduce)(
3138
+ const viewObj = (0, import_utils19.reduce)(
2856
3139
  views,
2857
3140
  (ret, view) => {
2858
3141
  ret[view] = true;
@@ -2860,7 +3143,7 @@ var Core = class {
2860
3143
  },
2861
3144
  {}
2862
3145
  );
2863
- const editObj = (0, import_utils16.reduce)(
3146
+ const editObj = (0, import_utils19.reduce)(
2864
3147
  edits,
2865
3148
  (ret, view) => {
2866
3149
  ret[view] = true;
@@ -2884,9 +3167,9 @@ var Core = class {
2884
3167
  return runDecorateAllHook({ req: this.req, hook: decorateAll, docs, permissions, context });
2885
3168
  }
2886
3169
  runTasks(modelName, docObject, task) {
2887
- const tasks = (0, import_utils16.compact)((0, import_utils16.castArray)(task));
3170
+ const tasks = (0, import_utils19.compact)((0, import_utils19.castArray)(task));
2888
3171
  if (tasks.length === 0) return docObject;
2889
- (0, import_utils16.forEach)(tasks, (task2) => {
3172
+ (0, import_utils19.forEach)(tasks, (task2) => {
2890
3173
  const { type, args, options } = task2;
2891
3174
  switch (type) {
2892
3175
  case "COPY_AND_DEPOPULATE":
@@ -2917,9 +3200,9 @@ var Core = class {
2917
3200
  }
2918
3201
  const [, field, op] = keys2;
2919
3202
  const subOption = getExactModelOption(modelName, `operationAccess.${access}`);
2920
- if ((0, import_utils16.isUndefined)(subOption)) {
3203
+ if ((0, import_utils19.isUndefined)(subOption)) {
2921
3204
  const subFieldOption = getExactModelOption(modelName, `operationAccess.subs.${field}`);
2922
- if ((0, import_utils16.isUndefined)(subFieldOption)) {
3205
+ if ((0, import_utils19.isUndefined)(subFieldOption)) {
2923
3206
  const opOption = getModelOption(modelName, `operationAccess.${op}`);
2924
3207
  return this.canActivate(opOption);
2925
3208
  }
@@ -2969,25 +3252,25 @@ function guard(condition) {
2969
3252
  const permissions = req[PERMISSIONS];
2970
3253
  let cond = condition;
2971
3254
  let phas = (key) => permissions.has(key);
2972
- if ((0, import_utils17.isPlainObject)(condition)) {
3255
+ if ((0, import_utils20.isPlainObject)(condition)) {
2973
3256
  const { modelName, id, condition: _cond } = condition;
2974
3257
  const svc = req.macl.getPublicService(modelName);
2975
3258
  const select = getModelOption(modelName, `alwaysSelectFields.read`, void 0);
2976
- let _id = (0, import_utils17.isString)(id) ? id : null;
2977
- if ((0, import_utils17.isPlainObject)(id)) {
3259
+ let _id = (0, import_utils20.isString)(id) ? id : null;
3260
+ if ((0, import_utils20.isPlainObject)(id)) {
2978
3261
  const { type = "param", key } = id;
2979
3262
  if (type === "param") {
2980
3263
  const paramValue = req.params[key];
2981
- _id = (0, import_utils17.isArray)(paramValue) ? paramValue[0] ?? null : paramValue ?? null;
3264
+ _id = (0, import_utils20.isArray)(paramValue) ? paramValue[0] ?? null : paramValue ?? null;
2982
3265
  } else if (type === "query") {
2983
3266
  const _qval = req.query[key];
2984
- if ((0, import_utils17.isArray)(_qval)) _id = _qval.length > 0 ? _qval[0] : null;
3267
+ if ((0, import_utils20.isArray)(_qval)) _id = _qval.length > 0 ? _qval[0] : null;
2985
3268
  else _id = _qval;
2986
3269
  } else {
2987
3270
  _id = null;
2988
3271
  }
2989
3272
  }
2990
- if (!(0, import_utils17.isString)(_id) || !_id) {
3273
+ if (!(0, import_utils20.isString)(_id) || !_id) {
2991
3274
  return next(new import_express_json_router2.default.clientErrors.BadRequestError());
2992
3275
  }
2993
3276
  const result = await svc._read(_id, { select });
@@ -2999,11 +3282,11 @@ function guard(condition) {
2999
3282
  cond = _cond;
3000
3283
  }
3001
3284
  const { stringHandler, arrayHandler } = createValidator(phas);
3002
- if ((0, import_utils17.isString)(cond)) {
3285
+ if ((0, import_utils20.isString)(cond)) {
3003
3286
  if (stringHandler(cond)) return next();
3004
- } else if ((0, import_utils17.isArray)(cond)) {
3287
+ } else if ((0, import_utils20.isArray)(cond)) {
3005
3288
  if (arrayHandler(cond)) return next();
3006
- } else if ((0, import_utils17.isFunction)(cond)) {
3289
+ } else if ((0, import_utils20.isFunction)(cond)) {
3007
3290
  const result = await cond.call(req, permissions);
3008
3291
  if (!!result) return next();
3009
3292
  }
@@ -3012,11 +3295,11 @@ function guard(condition) {
3012
3295
  }
3013
3296
 
3014
3297
  // src/routers/index.ts
3015
- var import_express = __toESM(require("express"));
3298
+ var import_express2 = __toESM(require("express"));
3016
3299
 
3017
3300
  // src/routers/model-router.ts
3018
3301
  var import_express_json_router5 = __toESM(require("@web-ts-toolkit/express-json-router"));
3019
- var import_utils19 = require("@web-ts-toolkit/utils");
3302
+ var import_utils24 = require("@web-ts-toolkit/utils");
3020
3303
 
3021
3304
  // src/routers/router-mutation.ts
3022
3305
  var MODEL_BUILD_TIME_OPTION_KEYS = /* @__PURE__ */ new Set([
@@ -3108,88 +3391,88 @@ function formatModelUpsertResponse(result) {
3108
3391
  var import_express_json_router4 = __toESM(require("@web-ts-toolkit/express-json-router"));
3109
3392
 
3110
3393
  // src/validation/common.ts
3111
- var import_zod = require("zod");
3112
- var stringOrStringArray = import_zod.z.union([import_zod.z.string(), import_zod.z.array(import_zod.z.string())]);
3113
- var queryBooleanString = import_zod.z.enum(["true", "false"]);
3114
- var positiveIntegerString = import_zod.z.string().regex(/^\d+$/, "Expected a non-negative integer");
3115
- var nonNegativeIntegerSchema = import_zod.z.number().int().min(0);
3116
- var unknownRecord = import_zod.z.record(import_zod.z.string(), import_zod.z.unknown());
3117
- var projectionObjectSchema = import_zod.z.record(import_zod.z.string(), import_zod.z.union([import_zod.z.literal(1), import_zod.z.literal(-1)]));
3118
- var projectionSchema = import_zod.z.union([import_zod.z.string(), import_zod.z.array(import_zod.z.string()), projectionObjectSchema]);
3119
- var sortOrderSchema = import_zod.z.union([
3120
- import_zod.z.literal(-1),
3121
- import_zod.z.literal(1),
3122
- import_zod.z.literal("asc"),
3123
- import_zod.z.literal("ascending"),
3124
- import_zod.z.literal("desc"),
3125
- import_zod.z.literal("descending")
3394
+ var import_zod2 = require("zod");
3395
+ var stringOrStringArray = import_zod2.z.union([import_zod2.z.string(), import_zod2.z.array(import_zod2.z.string())]);
3396
+ var queryBooleanString = import_zod2.z.enum(["true", "false"]);
3397
+ var positiveIntegerString = import_zod2.z.string().regex(/^\d+$/, "Expected a non-negative integer");
3398
+ var nonNegativeIntegerSchema = import_zod2.z.number().int().min(0);
3399
+ var unknownRecord = import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown());
3400
+ var projectionObjectSchema = import_zod2.z.record(import_zod2.z.string(), import_zod2.z.union([import_zod2.z.literal(1), import_zod2.z.literal(-1)]));
3401
+ var projectionSchema = import_zod2.z.union([import_zod2.z.string(), import_zod2.z.array(import_zod2.z.string()), projectionObjectSchema]);
3402
+ var sortOrderSchema = import_zod2.z.union([
3403
+ import_zod2.z.literal(-1),
3404
+ import_zod2.z.literal(1),
3405
+ import_zod2.z.literal("asc"),
3406
+ import_zod2.z.literal("ascending"),
3407
+ import_zod2.z.literal("desc"),
3408
+ import_zod2.z.literal("descending")
3126
3409
  ]);
3127
- var sortSchema = import_zod.z.union([
3128
- import_zod.z.string(),
3129
- import_zod.z.record(import_zod.z.string(), sortOrderSchema),
3130
- import_zod.z.array(import_zod.z.tuple([import_zod.z.string(), sortOrderSchema])),
3131
- import_zod.z.null()
3410
+ var sortSchema = import_zod2.z.union([
3411
+ import_zod2.z.string(),
3412
+ import_zod2.z.record(import_zod2.z.string(), sortOrderSchema),
3413
+ import_zod2.z.array(import_zod2.z.tuple([import_zod2.z.string(), sortOrderSchema])),
3414
+ import_zod2.z.null()
3132
3415
  ]);
3133
- var populateSchema = import_zod.z.union([
3134
- import_zod.z.string(),
3135
- import_zod.z.array(
3136
- import_zod.z.union([
3137
- import_zod.z.string(),
3138
- import_zod.z.object({
3139
- path: import_zod.z.string().min(1),
3416
+ var populateSchema = import_zod2.z.union([
3417
+ import_zod2.z.string(),
3418
+ import_zod2.z.array(
3419
+ import_zod2.z.union([
3420
+ import_zod2.z.string(),
3421
+ import_zod2.z.object({
3422
+ path: import_zod2.z.string().min(1),
3140
3423
  select: projectionSchema.optional(),
3141
- match: import_zod.z.unknown().optional(),
3142
- access: import_zod.z.enum(["list", "read"]).optional()
3424
+ match: import_zod2.z.unknown().optional(),
3425
+ access: import_zod2.z.enum(["list", "read"]).optional()
3143
3426
  }).passthrough()
3144
3427
  ])
3145
3428
  ),
3146
- import_zod.z.object({
3147
- path: import_zod.z.string().min(1),
3429
+ import_zod2.z.object({
3430
+ path: import_zod2.z.string().min(1),
3148
3431
  select: projectionSchema.optional(),
3149
- match: import_zod.z.unknown().optional(),
3150
- access: import_zod.z.enum(["list", "read"]).optional()
3432
+ match: import_zod2.z.unknown().optional(),
3433
+ access: import_zod2.z.enum(["list", "read"]).optional()
3151
3434
  }).passthrough()
3152
3435
  ]);
3153
- var subPopulateSchema = import_zod.z.union([
3154
- import_zod.z.string(),
3155
- import_zod.z.array(
3156
- import_zod.z.union([
3157
- import_zod.z.string(),
3158
- import_zod.z.object({
3159
- path: import_zod.z.string().min(1),
3436
+ var subPopulateSchema = import_zod2.z.union([
3437
+ import_zod2.z.string(),
3438
+ import_zod2.z.array(
3439
+ import_zod2.z.union([
3440
+ import_zod2.z.string(),
3441
+ import_zod2.z.object({
3442
+ path: import_zod2.z.string().min(1),
3160
3443
  select: projectionSchema.optional()
3161
3444
  }).passthrough()
3162
3445
  ])
3163
3446
  ),
3164
- import_zod.z.object({
3165
- path: import_zod.z.string().min(1),
3447
+ import_zod2.z.object({
3448
+ path: import_zod2.z.string().min(1),
3166
3449
  select: projectionSchema.optional()
3167
3450
  }).passthrough()
3168
3451
  ]);
3169
- var includeItemSchema = import_zod.z.object({
3170
- model: import_zod.z.string().min(1),
3171
- op: import_zod.z.enum(["list", "read", "count"]),
3172
- path: import_zod.z.string().min(1),
3173
- filter: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional(),
3174
- localField: import_zod.z.string().min(1),
3175
- foreignField: import_zod.z.string().min(1),
3176
- args: import_zod.z.unknown().optional(),
3177
- options: import_zod.z.unknown().optional()
3452
+ var includeItemSchema = import_zod2.z.object({
3453
+ model: import_zod2.z.string().min(1),
3454
+ op: import_zod2.z.enum(["list", "read", "count"]),
3455
+ path: import_zod2.z.string().min(1),
3456
+ filter: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()).optional(),
3457
+ localField: import_zod2.z.string().min(1),
3458
+ foreignField: import_zod2.z.string().min(1),
3459
+ args: import_zod2.z.unknown().optional(),
3460
+ options: import_zod2.z.unknown().optional()
3178
3461
  }).passthrough();
3179
- var includeSchema = import_zod.z.union([includeItemSchema, import_zod.z.array(includeItemSchema)]);
3180
- var fieldsSchema = import_zod.z.array(import_zod.z.string().min(1));
3181
- var taskSchema = import_zod.z.object({
3182
- type: import_zod.z.string().min(1),
3183
- args: import_zod.z.unknown(),
3462
+ var includeSchema = import_zod2.z.union([includeItemSchema, import_zod2.z.array(includeItemSchema)]);
3463
+ var fieldsSchema = import_zod2.z.array(import_zod2.z.string().min(1));
3464
+ var taskSchema = import_zod2.z.object({
3465
+ type: import_zod2.z.string().min(1),
3466
+ args: import_zod2.z.unknown(),
3184
3467
  options: unknownRecord.optional()
3185
3468
  });
3186
- var tasksSchema = import_zod.z.union([taskSchema, import_zod.z.array(taskSchema)]);
3187
- var objectOrArraySchema = import_zod.z.union([import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()), import_zod.z.array(import_zod.z.unknown())]);
3469
+ var tasksSchema = import_zod2.z.union([taskSchema, import_zod2.z.array(taskSchema)]);
3470
+ var objectOrArraySchema = import_zod2.z.union([import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()), import_zod2.z.array(import_zod2.z.unknown())]);
3188
3471
  function rejectKeys(body, ctx, keys2) {
3189
3472
  for (const key of keys2) {
3190
3473
  if (key in body) {
3191
3474
  ctx.addIssue({
3192
- code: import_zod.z.ZodIssueCode.custom,
3475
+ code: import_zod2.z.ZodIssueCode.custom,
3193
3476
  message: `Unsupported field: ${key}`,
3194
3477
  path: [key]
3195
3478
  });
@@ -3202,7 +3485,7 @@ var clientErrors = import_express_json_router4.default.clientErrors;
3202
3485
  function parsePathParam(value, parameter) {
3203
3486
  const result = stringOrStringArray.safeParse(value);
3204
3487
  if (!result.success) {
3205
- throwValidationError(result.error.issues, parameter, "parameter");
3488
+ throwValidationError(normalizeIssues(result.error.issues), parameter, "parameter");
3206
3489
  }
3207
3490
  const param = Array.isArray(result.data) ? result.data[0] : result.data;
3208
3491
  if (!param) {
@@ -3215,49 +3498,336 @@ function parsePathParam(value, parameter) {
3215
3498
  function parseQuery(schema, value) {
3216
3499
  const result = schema.safeParse(value);
3217
3500
  if (!result.success) {
3218
- throwValidationError(result.error.issues, void 0, "parameter");
3501
+ throwValidationError(normalizeIssues(result.error.issues), void 0, "parameter");
3219
3502
  }
3220
3503
  return result.data;
3221
3504
  }
3222
3505
  function parseBody(schema, value) {
3223
3506
  const result = schema.safeParse(value ?? {});
3224
3507
  if (!result.success) {
3225
- throwValidationError(result.error.issues, void 0, "pointer");
3508
+ throwValidationError(normalizeIssues(result.error.issues), void 0, "pointer");
3226
3509
  }
3227
3510
  return result.data;
3228
3511
  }
3229
3512
  function parseBodyWithSchema(schema, value, userSchema) {
3230
3513
  const body = parseBody(schema, value);
3231
- return isZodSchema(userSchema) ? parseUserSchema(userSchema, body) : body;
3514
+ return isRequestSchema(userSchema) ? parseUserSchema(userSchema, body) : Promise.resolve(body);
3232
3515
  }
3233
- function parseNestedBodyWithSchema(schema, value, nestedKey, userSchema) {
3516
+ async function parseNestedBodyWithSchema(schema, value, nestedKey, userSchema) {
3234
3517
  const body = parseBody(schema, value);
3235
- if (!isZodSchema(userSchema)) return body;
3518
+ if (!isRequestSchema(userSchema)) return body;
3236
3519
  return {
3237
3520
  ...body,
3238
- [nestedKey]: parseUserSchema(userSchema, body?.[nestedKey], [nestedKey])
3521
+ [nestedKey]: await parseUserSchema(userSchema, body?.[nestedKey], [nestedKey])
3239
3522
  };
3240
3523
  }
3241
3524
  function throwValidationError(issues, key, location = "pointer") {
3242
3525
  const errors = issues.map((issue) => formatIssue(issue, key, location));
3243
3526
  throw new clientErrors.BadRequestError("Bad Request", { errors });
3244
3527
  }
3245
- function parseUserSchema(schema, value, prefix = []) {
3246
- const result = schema.safeParse(value);
3247
- if (!result.success) {
3248
- const issues = result.error.issues.map((issue) => ({
3249
- ...issue,
3250
- path: prefix.concat(issue.path.map(String))
3251
- }));
3252
- throwValidationError(issues, void 0, "pointer");
3253
- }
3254
- return result.data;
3528
+ async function parseUserSchema(schema, value, prefix = []) {
3529
+ const validator = toRequestSchemaValidator(schema);
3530
+ const result = await validator(value);
3531
+ if (!isRequestSchemaFailure(result)) {
3532
+ return result.data;
3533
+ }
3534
+ const issues = result.issues.map((issue) => ({
3535
+ ...issue,
3536
+ path: prefix.concat((issue.path ?? []).map(String))
3537
+ }));
3538
+ throwValidationError(issues, void 0, "pointer");
3255
3539
  }
3256
3540
  function isZodSchema(schema) {
3257
3541
  return typeof schema === "object" && schema !== null && "safeParse" in schema && typeof schema.safeParse === "function";
3258
3542
  }
3543
+ function isRequestSchema(schema) {
3544
+ return isZodSchema(schema) || isStandardSchema(schema) || isRequestSchemaValidator(schema) || isRequestSchemaAdapter(schema);
3545
+ }
3546
+ function isRequestSchemaValidator(schema) {
3547
+ return typeof schema === "function";
3548
+ }
3549
+ function isRequestSchemaAdapter(schema) {
3550
+ return typeof schema === "object" && schema !== null && "validate" in schema && typeof schema.validate === "function";
3551
+ }
3552
+ function isStandardSchema(schema) {
3553
+ return typeof schema === "object" && schema !== null && "~standard" in schema && typeof schema["~standard"] === "object" && schema["~standard"] !== null && "validate" in schema["~standard"] && typeof schema["~standard"].validate === "function";
3554
+ }
3555
+ function isRequestSchemaFailure(result) {
3556
+ return result.success === false;
3557
+ }
3558
+ function toRequestSchemaValidator(schema) {
3559
+ if (isZodSchema(schema)) return fromZod(schema);
3560
+ if (isStandardSchema(schema)) return fromStandardSchema(schema);
3561
+ if (isRequestSchemaValidator(schema)) return schema;
3562
+ return schema.validate;
3563
+ }
3564
+ function defineRequestSchema(validator, options = {}) {
3565
+ return {
3566
+ validate: validator,
3567
+ openapi: options.openapi
3568
+ };
3569
+ }
3570
+ function fromZod(schema) {
3571
+ return (value) => {
3572
+ const result = schema.safeParse(value);
3573
+ if (result.success) {
3574
+ return {
3575
+ success: true,
3576
+ data: result.data
3577
+ };
3578
+ }
3579
+ return {
3580
+ success: false,
3581
+ issues: normalizeIssues(result.error.issues)
3582
+ };
3583
+ };
3584
+ }
3585
+ function fromStandardSchema(schema) {
3586
+ return async (value) => {
3587
+ const result = await schema["~standard"].validate(value);
3588
+ if (!isStandardSchemaFailure(result)) {
3589
+ return {
3590
+ success: true,
3591
+ data: result.value
3592
+ };
3593
+ }
3594
+ return {
3595
+ success: false,
3596
+ issues: normalizeIssues(result.issues)
3597
+ };
3598
+ };
3599
+ }
3600
+ function fromYup(schema) {
3601
+ return async (value) => {
3602
+ try {
3603
+ const data = await schema.validate(value, { abortEarly: false });
3604
+ return {
3605
+ success: true,
3606
+ data
3607
+ };
3608
+ } catch (error) {
3609
+ return {
3610
+ success: false,
3611
+ issues: normalizeYupIssues(error)
3612
+ };
3613
+ }
3614
+ };
3615
+ }
3616
+ function fromJoi(schema) {
3617
+ return async (value) => {
3618
+ const result = await schema.validate(value, { abortEarly: false });
3619
+ if (!result.error?.details?.length) {
3620
+ return {
3621
+ success: true,
3622
+ data: result.value
3623
+ };
3624
+ }
3625
+ return {
3626
+ success: false,
3627
+ issues: normalizeJoiIssues(result.error.details)
3628
+ };
3629
+ };
3630
+ }
3631
+ function fromAjv(validator) {
3632
+ return async (value) => {
3633
+ const valid = await validator(value);
3634
+ if (valid) {
3635
+ return {
3636
+ success: true,
3637
+ data: value
3638
+ };
3639
+ }
3640
+ return {
3641
+ success: false,
3642
+ issues: normalizeAjvIssues(validator.errors ?? [])
3643
+ };
3644
+ };
3645
+ }
3646
+ function fromValibot(schema, safeParse) {
3647
+ return async (value) => {
3648
+ const result = await safeParse(schema, value, { abortEarly: false });
3649
+ if (result.success) {
3650
+ return {
3651
+ success: true,
3652
+ data: result.output
3653
+ };
3654
+ }
3655
+ return {
3656
+ success: false,
3657
+ issues: normalizeValibotIssues(result.issues)
3658
+ };
3659
+ };
3660
+ }
3661
+ function fromArkType(type) {
3662
+ return async (value) => {
3663
+ const result = await type(value);
3664
+ if (!isArkTypeErrors(result)) {
3665
+ return {
3666
+ success: true,
3667
+ data: result
3668
+ };
3669
+ }
3670
+ return {
3671
+ success: false,
3672
+ issues: normalizeArkTypeIssues(result)
3673
+ };
3674
+ };
3675
+ }
3676
+ function fromIoTs(decoder) {
3677
+ return async (value) => {
3678
+ const result = decoder.decode(value);
3679
+ if (result._tag === "Right") {
3680
+ return {
3681
+ success: true,
3682
+ data: result.right
3683
+ };
3684
+ }
3685
+ return {
3686
+ success: false,
3687
+ issues: normalizeIoTsIssues(result.left)
3688
+ };
3689
+ };
3690
+ }
3691
+ function fromSuperstruct(struct, validate) {
3692
+ return async (value) => {
3693
+ const [failure, output] = await validate(value, struct);
3694
+ if (!failure) {
3695
+ return {
3696
+ success: true,
3697
+ data: output
3698
+ };
3699
+ }
3700
+ return {
3701
+ success: false,
3702
+ issues: normalizeSuperstructFailure(failure)
3703
+ };
3704
+ };
3705
+ }
3706
+ function fromVine(validator) {
3707
+ return async (value) => {
3708
+ try {
3709
+ const output = await validator.validate(value);
3710
+ return {
3711
+ success: true,
3712
+ data: output
3713
+ };
3714
+ } catch (error) {
3715
+ return {
3716
+ success: false,
3717
+ issues: normalizeVineError(error)
3718
+ };
3719
+ }
3720
+ };
3721
+ }
3722
+ function isStandardSchemaFailure(result) {
3723
+ return Array.isArray(result.issues);
3724
+ }
3725
+ function normalizeIssues(issues) {
3726
+ return issues.map((issue) => ({
3727
+ message: issue.message,
3728
+ path: issue.path?.flatMap((segment) => normalizePathSegment(segment))
3729
+ }));
3730
+ }
3731
+ function normalizePathSegment(segment) {
3732
+ const key = isStandardSchemaPathSegment(segment) ? segment.key : segment;
3733
+ return typeof key === "string" || typeof key === "number" ? [key] : [];
3734
+ }
3735
+ function isStandardSchemaPathSegment(segment) {
3736
+ return typeof segment === "object" && segment !== null && "key" in segment;
3737
+ }
3738
+ function normalizeYupIssues(error) {
3739
+ if (!isYupValidationError(error)) {
3740
+ return [{ message: "Validation failed" }];
3741
+ }
3742
+ const issues = error.inner?.length ? error.inner : [error];
3743
+ return issues.map((issue) => ({
3744
+ message: issue.message,
3745
+ path: parsePathString(issue.path)
3746
+ }));
3747
+ }
3748
+ function normalizeJoiIssues(issues) {
3749
+ return issues.map((issue) => ({
3750
+ message: issue.message,
3751
+ path: issue.path ? [...issue.path] : void 0
3752
+ }));
3753
+ }
3754
+ function normalizeAjvIssues(issues) {
3755
+ return issues.map((issue) => ({
3756
+ message: issue.message ?? "Validation failed",
3757
+ path: parseAjvPath(issue)
3758
+ }));
3759
+ }
3760
+ function normalizeValibotIssues(issues) {
3761
+ return issues.map((issue) => ({
3762
+ message: issue.message,
3763
+ path: issue.path?.flatMap(
3764
+ (item) => typeof item.key === "string" || typeof item.key === "number" ? [item.key] : []
3765
+ )
3766
+ }));
3767
+ }
3768
+ function normalizeArkTypeIssues(issues) {
3769
+ const normalized = issues.map((issue) => ({
3770
+ message: issue.message ?? issue.problem ?? issues.summary ?? "Validation failed",
3771
+ path: issue.path ? [...issue.path] : void 0
3772
+ }));
3773
+ return normalized.length ? normalized : [{ message: issues.summary ?? "Validation failed" }];
3774
+ }
3775
+ function normalizeIoTsIssues(issues) {
3776
+ return issues.map((issue) => ({
3777
+ message: issue.message ?? "Validation failed",
3778
+ path: issue.context.map((entry) => entry.key).filter(Boolean)
3779
+ }));
3780
+ }
3781
+ function normalizeSuperstructFailure(failure) {
3782
+ const failures = failure.failures?.() ?? [failure];
3783
+ return failures.map((entry) => ({
3784
+ message: entry.message ?? "Validation failed",
3785
+ path: normalizeSuperstructPath(entry)
3786
+ }));
3787
+ }
3788
+ function normalizeSuperstructPath(failure) {
3789
+ if (failure.path?.length) return [...failure.path];
3790
+ if (typeof failure.key === "string" || typeof failure.key === "number") return [failure.key];
3791
+ return void 0;
3792
+ }
3793
+ function normalizeVineError(error) {
3794
+ if (!isVineValidationError(error)) {
3795
+ return [{ message: "Validation failed" }];
3796
+ }
3797
+ return error.messages.map((message) => ({
3798
+ message: message.message,
3799
+ path: normalizeVineField(message)
3800
+ }));
3801
+ }
3802
+ function normalizeVineField(message) {
3803
+ const path = message.field.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
3804
+ if (typeof message.index === "number" && path.length === 0) {
3805
+ return [message.index];
3806
+ }
3807
+ return path.length ? path : void 0;
3808
+ }
3809
+ function parseAjvPath(issue) {
3810
+ const path = issue.instancePath?.split("/").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
3811
+ if (issue.params?.missingProperty) {
3812
+ return (path ?? []).concat(issue.params.missingProperty);
3813
+ }
3814
+ return path;
3815
+ }
3816
+ function parsePathString(path) {
3817
+ if (!path) return void 0;
3818
+ return path.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
3819
+ }
3820
+ function isYupValidationError(error) {
3821
+ return typeof error === "object" && error !== null && "message" in error;
3822
+ }
3823
+ function isArkTypeErrors(value) {
3824
+ return Array.isArray(value);
3825
+ }
3826
+ function isVineValidationError(error) {
3827
+ return typeof error === "object" && error !== null && "messages" in error && Array.isArray(error.messages);
3828
+ }
3259
3829
  function formatIssue(issue, key, location = "pointer") {
3260
- const path = issue.path.map(String);
3830
+ const path = (issue.path ?? []).map(String);
3261
3831
  const joinedPath = path.join(".");
3262
3832
  if (location === "parameter") {
3263
3833
  return {
@@ -3275,8 +3845,8 @@ function buildPointer(path) {
3275
3845
  }
3276
3846
 
3277
3847
  // src/validation/model-router.ts
3278
- var import_zod2 = require("zod");
3279
- var listQuerySchema = import_zod2.z.object({
3848
+ var import_zod3 = require("zod");
3849
+ var listQuerySchema = import_zod3.z.object({
3280
3850
  skip: positiveIntegerString.optional(),
3281
3851
  limit: positiveIntegerString.optional(),
3282
3852
  page: positiveIntegerString.optional(),
@@ -3286,122 +3856,122 @@ var listQuerySchema = import_zod2.z.object({
3286
3856
  include_count: queryBooleanString.optional(),
3287
3857
  include_extra_headers: queryBooleanString.optional()
3288
3858
  }).passthrough();
3289
- var createQuerySchema = import_zod2.z.object({
3859
+ var createQuerySchema = import_zod3.z.object({
3290
3860
  include_permissions: queryBooleanString.optional()
3291
3861
  }).passthrough();
3292
- var readQuerySchema = import_zod2.z.object({
3862
+ var readQuerySchema = import_zod3.z.object({
3293
3863
  include_permissions: queryBooleanString.optional(),
3294
3864
  try_list: queryBooleanString.optional()
3295
3865
  }).passthrough();
3296
- var updateQuerySchema = import_zod2.z.object({
3866
+ var updateQuerySchema = import_zod3.z.object({
3297
3867
  returning_all: queryBooleanString.optional(),
3298
3868
  include_permissions: queryBooleanString.optional()
3299
3869
  }).passthrough();
3300
- var upsertQuerySchema = import_zod2.z.object({
3870
+ var upsertQuerySchema = import_zod3.z.object({
3301
3871
  returning_all: queryBooleanString.optional(),
3302
3872
  include_permissions: queryBooleanString.optional()
3303
3873
  }).passthrough();
3304
- var listBodySchema = import_zod2.z.object({
3874
+ var listBodySchema = import_zod3.z.object({
3305
3875
  filter: objectOrArraySchema.optional(),
3306
3876
  select: projectionSchema.optional(),
3307
3877
  sort: sortSchema.optional(),
3308
3878
  populate: populateSchema.optional(),
3309
3879
  include: includeSchema.optional(),
3310
3880
  tasks: tasksSchema.optional(),
3311
- skip: import_zod2.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3312
- limit: import_zod2.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3313
- page: import_zod2.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3314
- pageSize: import_zod2.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3315
- options: import_zod2.z.object({
3316
- skim: import_zod2.z.boolean().optional(),
3317
- includePermissions: import_zod2.z.boolean().optional(),
3318
- includeCount: import_zod2.z.boolean().optional(),
3319
- includeExtraHeaders: import_zod2.z.boolean().optional(),
3320
- populateAccess: import_zod2.z.unknown().optional()
3881
+ skip: import_zod3.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3882
+ limit: import_zod3.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3883
+ page: import_zod3.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3884
+ pageSize: import_zod3.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3885
+ options: import_zod3.z.object({
3886
+ skim: import_zod3.z.boolean().optional(),
3887
+ includePermissions: import_zod3.z.boolean().optional(),
3888
+ includeCount: import_zod3.z.boolean().optional(),
3889
+ includeExtraHeaders: import_zod3.z.boolean().optional(),
3890
+ populateAccess: import_zod3.z.unknown().optional()
3321
3891
  }).passthrough().optional()
3322
3892
  }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query"]));
3323
- var countBodySchema = import_zod2.z.object({
3893
+ var countBodySchema = import_zod3.z.object({
3324
3894
  filter: objectOrArraySchema.optional(),
3325
- options: import_zod2.z.object({
3326
- access: import_zod2.z.unknown().optional()
3895
+ options: import_zod3.z.object({
3896
+ access: import_zod3.z.unknown().optional()
3327
3897
  }).passthrough().optional()
3328
3898
  }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query", "access"]));
3329
- var readFilterBodySchema = import_zod2.z.object({
3899
+ var readFilterBodySchema = import_zod3.z.object({
3330
3900
  filter: objectOrArraySchema.optional(),
3331
3901
  select: projectionSchema.optional(),
3332
3902
  sort: sortSchema.optional(),
3333
3903
  populate: populateSchema.optional(),
3334
3904
  include: includeSchema.optional(),
3335
3905
  tasks: tasksSchema.optional(),
3336
- options: import_zod2.z.object({
3337
- skim: import_zod2.z.boolean().optional(),
3338
- includePermissions: import_zod2.z.boolean().optional(),
3339
- tryList: import_zod2.z.boolean().optional(),
3340
- populateAccess: import_zod2.z.unknown().optional()
3906
+ options: import_zod3.z.object({
3907
+ skim: import_zod3.z.boolean().optional(),
3908
+ includePermissions: import_zod3.z.boolean().optional(),
3909
+ tryList: import_zod3.z.boolean().optional(),
3910
+ populateAccess: import_zod3.z.unknown().optional()
3341
3911
  }).passthrough().optional()
3342
3912
  }).passthrough();
3343
- var readByIdBodySchema = import_zod2.z.object({
3913
+ var readByIdBodySchema = import_zod3.z.object({
3344
3914
  select: projectionSchema.optional(),
3345
3915
  populate: populateSchema.optional(),
3346
3916
  include: includeSchema.optional(),
3347
3917
  tasks: tasksSchema.optional(),
3348
- options: import_zod2.z.object({
3349
- skim: import_zod2.z.boolean().optional(),
3350
- includePermissions: import_zod2.z.boolean().optional(),
3351
- tryList: import_zod2.z.boolean().optional(),
3352
- populateAccess: import_zod2.z.unknown().optional()
3918
+ options: import_zod3.z.object({
3919
+ skim: import_zod3.z.boolean().optional(),
3920
+ includePermissions: import_zod3.z.boolean().optional(),
3921
+ tryList: import_zod3.z.boolean().optional(),
3922
+ populateAccess: import_zod3.z.unknown().optional()
3353
3923
  }).passthrough().optional()
3354
3924
  }).passthrough();
3355
- var advancedCreateBodySchema = import_zod2.z.object({
3356
- data: import_zod2.z.unknown(),
3925
+ var advancedCreateBodySchema = import_zod3.z.object({
3926
+ data: import_zod3.z.unknown(),
3357
3927
  select: projectionSchema.optional(),
3358
3928
  populate: populateSchema.optional(),
3359
3929
  tasks: tasksSchema.optional(),
3360
- options: import_zod2.z.object({
3361
- includePermissions: import_zod2.z.boolean().optional(),
3362
- populateAccess: import_zod2.z.unknown().optional()
3930
+ options: import_zod3.z.object({
3931
+ includePermissions: import_zod3.z.boolean().optional(),
3932
+ populateAccess: import_zod3.z.unknown().optional()
3363
3933
  }).passthrough().optional()
3364
3934
  }).passthrough();
3365
- var createBodySchema = import_zod2.z.union([
3366
- import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()),
3367
- import_zod2.z.array(import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()))
3935
+ var createBodySchema = import_zod3.z.union([
3936
+ import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()),
3937
+ import_zod3.z.array(import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()))
3368
3938
  ]);
3369
- var updateBodySchema = import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown());
3370
- var advancedUpdateBodySchema = import_zod2.z.object({
3371
- data: import_zod2.z.unknown(),
3939
+ var updateBodySchema = import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown());
3940
+ var advancedUpdateBodySchema = import_zod3.z.object({
3941
+ data: import_zod3.z.unknown(),
3372
3942
  select: projectionSchema.optional(),
3373
3943
  populate: populateSchema.optional(),
3374
3944
  tasks: tasksSchema.optional(),
3375
- options: import_zod2.z.object({
3376
- returningAll: import_zod2.z.boolean().optional(),
3377
- includePermissions: import_zod2.z.boolean().optional(),
3378
- populateAccess: import_zod2.z.unknown().optional()
3945
+ options: import_zod3.z.object({
3946
+ returningAll: import_zod3.z.boolean().optional(),
3947
+ includePermissions: import_zod3.z.boolean().optional(),
3948
+ populateAccess: import_zod3.z.unknown().optional()
3379
3949
  }).passthrough().optional()
3380
3950
  }).passthrough();
3381
- var upsertBodySchema = import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown());
3382
- var advancedUpsertBodySchema = import_zod2.z.object({
3383
- data: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()),
3951
+ var upsertBodySchema = import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown());
3952
+ var advancedUpsertBodySchema = import_zod3.z.object({
3953
+ data: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()),
3384
3954
  select: projectionSchema.optional(),
3385
3955
  populate: populateSchema.optional(),
3386
3956
  tasks: tasksSchema.optional(),
3387
- options: import_zod2.z.object({
3388
- returningAll: import_zod2.z.boolean().optional(),
3389
- includePermissions: import_zod2.z.boolean().optional(),
3390
- populateAccess: import_zod2.z.unknown().optional()
3957
+ options: import_zod3.z.object({
3958
+ returningAll: import_zod3.z.boolean().optional(),
3959
+ includePermissions: import_zod3.z.boolean().optional(),
3960
+ populateAccess: import_zod3.z.unknown().optional()
3391
3961
  }).passthrough().optional()
3392
3962
  }).passthrough();
3393
- var distinctBodySchema = import_zod2.z.object({
3963
+ var distinctBodySchema = import_zod3.z.object({
3394
3964
  filter: objectOrArraySchema.optional()
3395
3965
  }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query"]));
3396
- var subListBodySchema = import_zod2.z.object({
3397
- filter: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()).optional(),
3966
+ var subListBodySchema = import_zod3.z.object({
3967
+ filter: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()).optional(),
3398
3968
  select: fieldsSchema.optional()
3399
3969
  }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["fields"]));
3400
- var subMutationBodySchema = import_zod2.z.union([
3401
- import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()),
3402
- import_zod2.z.array(import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()))
3970
+ var subMutationBodySchema = import_zod3.z.union([
3971
+ import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()),
3972
+ import_zod3.z.array(import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()))
3403
3973
  ]);
3404
- var subReadBodySchema = import_zod2.z.object({
3974
+ var subReadBodySchema = import_zod3.z.object({
3405
3975
  select: fieldsSchema.optional(),
3406
3976
  populate: subPopulateSchema.optional()
3407
3977
  }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["fields"]));
@@ -3414,54 +3984,54 @@ var requestSchemas = {
3414
3984
  };
3415
3985
 
3416
3986
  // src/validation/data-router.ts
3417
- var import_zod3 = require("zod");
3418
- var dataListBodySchema = import_zod3.z.object({
3987
+ var import_zod4 = require("zod");
3988
+ var dataListBodySchema = import_zod4.z.object({
3419
3989
  filter: objectOrArraySchema.optional(),
3420
3990
  select: projectionSchema.optional(),
3421
- sort: import_zod3.z.string().optional(),
3422
- skip: import_zod3.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3423
- limit: import_zod3.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3424
- page: import_zod3.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3425
- pageSize: import_zod3.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3426
- options: import_zod3.z.object({
3427
- includeCount: import_zod3.z.boolean().optional(),
3428
- includeExtraHeaders: import_zod3.z.boolean().optional()
3991
+ sort: import_zod4.z.string().optional(),
3992
+ skip: import_zod4.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3993
+ limit: import_zod4.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3994
+ page: import_zod4.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3995
+ pageSize: import_zod4.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3996
+ options: import_zod4.z.object({
3997
+ includeCount: import_zod4.z.boolean().optional(),
3998
+ includeExtraHeaders: import_zod4.z.boolean().optional()
3429
3999
  }).passthrough().optional()
3430
4000
  }).passthrough();
3431
- var dataReadFilterBodySchema = import_zod3.z.object({
4001
+ var dataReadFilterBodySchema = import_zod4.z.object({
3432
4002
  filter: objectOrArraySchema.optional(),
3433
4003
  select: projectionSchema.optional()
3434
4004
  }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["options"]));
3435
- var dataReadByIdBodySchema = import_zod3.z.object({
4005
+ var dataReadByIdBodySchema = import_zod4.z.object({
3436
4006
  select: projectionSchema.optional()
3437
4007
  }).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["options"]));
3438
4008
 
3439
4009
  // src/validation/root-router.ts
3440
- var import_zod4 = require("zod");
4010
+ var import_zod5 = require("zod");
3441
4011
  var rootEntryBaseSchema = {
3442
- target: import_zod4.z.enum(["model", "data"]),
3443
- name: import_zod4.z.string().min(1),
3444
- order: import_zod4.z.number().int().optional()
4012
+ target: import_zod5.z.enum(["model", "data"]),
4013
+ name: import_zod5.z.string().min(1),
4014
+ order: import_zod5.z.number().int().optional()
3445
4015
  };
3446
- var rootModelListArgsSchema = import_zod4.z.object({
4016
+ var rootModelListArgsSchema = import_zod5.z.object({
3447
4017
  select: projectionSchema.optional(),
3448
4018
  populate: populateSchema.optional(),
3449
4019
  include: includeSchema.optional(),
3450
4020
  sort: sortSchema.optional(),
3451
- skip: import_zod4.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3452
- limit: import_zod4.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3453
- page: import_zod4.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3454
- pageSize: import_zod4.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
4021
+ skip: import_zod5.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
4022
+ limit: import_zod5.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
4023
+ page: import_zod5.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
4024
+ pageSize: import_zod5.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3455
4025
  tasks: tasksSchema.optional()
3456
4026
  }).passthrough();
3457
- var rootModelListOptionsSchema = import_zod4.z.object({
3458
- skim: import_zod4.z.boolean().optional(),
3459
- includePermissions: import_zod4.z.boolean().optional(),
3460
- includeCount: import_zod4.z.boolean().optional(),
3461
- populateAccess: import_zod4.z.unknown().optional(),
3462
- lean: import_zod4.z.boolean().optional()
4027
+ var rootModelListOptionsSchema = import_zod5.z.object({
4028
+ skim: import_zod5.z.boolean().optional(),
4029
+ includePermissions: import_zod5.z.boolean().optional(),
4030
+ includeCount: import_zod5.z.boolean().optional(),
4031
+ populateAccess: import_zod5.z.unknown().optional(),
4032
+ lean: import_zod5.z.boolean().optional()
3463
4033
  }).passthrough();
3464
- var rootModelReadArgsSchema = import_zod4.z.object({
4034
+ var rootModelReadArgsSchema = import_zod5.z.object({
3465
4035
  select: projectionSchema.optional(),
3466
4036
  populate: populateSchema.optional(),
3467
4037
  include: includeSchema.optional(),
@@ -3470,231 +4040,247 @@ var rootModelReadArgsSchema = import_zod4.z.object({
3470
4040
  var rootModelReadFilterArgsSchema = rootModelReadArgsSchema.extend({
3471
4041
  sort: sortSchema.optional()
3472
4042
  });
3473
- var rootModelReadOptionsSchema = import_zod4.z.object({
3474
- skim: import_zod4.z.boolean().optional(),
3475
- includePermissions: import_zod4.z.boolean().optional(),
3476
- tryList: import_zod4.z.boolean().optional(),
3477
- populateAccess: import_zod4.z.unknown().optional(),
3478
- lean: import_zod4.z.boolean().optional()
4043
+ var rootModelReadOptionsSchema = import_zod5.z.object({
4044
+ skim: import_zod5.z.boolean().optional(),
4045
+ includePermissions: import_zod5.z.boolean().optional(),
4046
+ tryList: import_zod5.z.boolean().optional(),
4047
+ populateAccess: import_zod5.z.unknown().optional(),
4048
+ lean: import_zod5.z.boolean().optional()
3479
4049
  }).passthrough();
3480
- var rootModelCreateArgsSchema = import_zod4.z.object({
4050
+ var rootModelCreateArgsSchema = import_zod5.z.object({
3481
4051
  select: projectionSchema.optional(),
3482
4052
  populate: populateSchema.optional(),
3483
4053
  tasks: tasksSchema.optional()
3484
4054
  }).passthrough();
3485
- var rootModelCreateOptionsSchema = import_zod4.z.object({
3486
- skim: import_zod4.z.boolean().optional(),
3487
- includePermissions: import_zod4.z.boolean().optional(),
3488
- populateAccess: import_zod4.z.unknown().optional()
4055
+ var rootModelCreateOptionsSchema = import_zod5.z.object({
4056
+ skim: import_zod5.z.boolean().optional(),
4057
+ includePermissions: import_zod5.z.boolean().optional(),
4058
+ populateAccess: import_zod5.z.unknown().optional()
3489
4059
  }).passthrough();
3490
- var rootModelUpdateArgsSchema = import_zod4.z.object({
4060
+ var rootModelUpdateArgsSchema = import_zod5.z.object({
3491
4061
  select: projectionSchema.optional(),
3492
4062
  populate: populateSchema.optional(),
3493
4063
  tasks: tasksSchema.optional()
3494
4064
  }).passthrough();
3495
- var rootModelUpdateOptionsSchema = import_zod4.z.object({
3496
- skim: import_zod4.z.boolean().optional(),
3497
- returningAll: import_zod4.z.boolean().optional(),
3498
- includePermissions: import_zod4.z.boolean().optional(),
3499
- populateAccess: import_zod4.z.unknown().optional()
4065
+ var rootModelUpdateOptionsSchema = import_zod5.z.object({
4066
+ skim: import_zod5.z.boolean().optional(),
4067
+ returningAll: import_zod5.z.boolean().optional(),
4068
+ includePermissions: import_zod5.z.boolean().optional(),
4069
+ populateAccess: import_zod5.z.unknown().optional()
3500
4070
  }).passthrough();
3501
4071
  var rootModelUpsertArgsSchema = rootModelUpdateArgsSchema;
3502
4072
  var rootModelUpsertOptionsSchema = rootModelUpdateOptionsSchema;
3503
- var rootModelSubListArgsSchema = import_zod4.z.object({
4073
+ var rootModelSubListArgsSchema = import_zod5.z.object({
3504
4074
  select: fieldsSchema.optional()
3505
4075
  }).passthrough();
3506
- var rootModelSubReadArgsSchema = import_zod4.z.object({
4076
+ var rootModelSubReadArgsSchema = import_zod5.z.object({
3507
4077
  select: fieldsSchema.optional(),
3508
4078
  populate: subPopulateSchema.optional()
3509
4079
  }).passthrough();
3510
- var rootModelCountOptionsSchema = import_zod4.z.object({
3511
- access: import_zod4.z.unknown().optional()
4080
+ var rootModelCountOptionsSchema = import_zod5.z.object({
4081
+ access: import_zod5.z.unknown().optional()
3512
4082
  }).passthrough();
3513
- var rootDataListArgsSchema = import_zod4.z.object({
4083
+ var rootDataListArgsSchema = import_zod5.z.object({
3514
4084
  select: projectionSchema.optional(),
3515
- sort: import_zod4.z.string().optional(),
3516
- skip: import_zod4.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3517
- limit: import_zod4.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3518
- page: import_zod4.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
3519
- pageSize: import_zod4.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional()
4085
+ sort: import_zod5.z.string().optional(),
4086
+ skip: import_zod5.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
4087
+ limit: import_zod5.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
4088
+ page: import_zod5.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
4089
+ pageSize: import_zod5.z.union([nonNegativeIntegerSchema, positiveIntegerString]).optional()
3520
4090
  }).passthrough();
3521
- var rootDataListOptionsSchema = import_zod4.z.object({
3522
- includeCount: import_zod4.z.boolean().optional()
4091
+ var rootDataListOptionsSchema = import_zod5.z.object({
4092
+ includeCount: import_zod5.z.boolean().optional()
3523
4093
  }).passthrough();
3524
- var rootDataReadArgsSchema = import_zod4.z.object({
4094
+ var rootDataReadArgsSchema = import_zod5.z.object({
3525
4095
  select: projectionSchema.optional()
3526
4096
  }).passthrough();
3527
- var rootModelQueryEntrySchema = import_zod4.z.union([
3528
- import_zod4.z.object({ ...rootEntryBaseSchema, target: import_zod4.z.literal("model"), op: import_zod4.z.literal("new") }).passthrough(),
3529
- import_zod4.z.object({
4097
+ var rootModelQueryEntrySchema = import_zod5.z.union([
4098
+ import_zod5.z.object({ ...rootEntryBaseSchema, target: import_zod5.z.literal("model"), op: import_zod5.z.literal("new") }).passthrough(),
4099
+ import_zod5.z.object({
3530
4100
  ...rootEntryBaseSchema,
3531
- target: import_zod4.z.literal("model"),
3532
- op: import_zod4.z.literal("list"),
4101
+ target: import_zod5.z.literal("model"),
4102
+ op: import_zod5.z.literal("list"),
3533
4103
  filter: objectOrArraySchema.optional(),
3534
4104
  args: rootModelListArgsSchema.optional(),
3535
4105
  options: rootModelListOptionsSchema.optional()
3536
4106
  }).passthrough(),
3537
- import_zod4.z.object({
4107
+ import_zod5.z.object({
3538
4108
  ...rootEntryBaseSchema,
3539
- target: import_zod4.z.literal("model"),
3540
- op: import_zod4.z.literal("read"),
3541
- id: import_zod4.z.string().min(1),
4109
+ target: import_zod5.z.literal("model"),
4110
+ op: import_zod5.z.literal("read"),
4111
+ id: import_zod5.z.string().min(1),
3542
4112
  args: rootModelReadArgsSchema.optional(),
3543
4113
  options: rootModelReadOptionsSchema.optional()
3544
4114
  }).passthrough(),
3545
- import_zod4.z.object({
4115
+ import_zod5.z.object({
3546
4116
  ...rootEntryBaseSchema,
3547
- target: import_zod4.z.literal("model"),
3548
- op: import_zod4.z.literal("read"),
4117
+ target: import_zod5.z.literal("model"),
4118
+ op: import_zod5.z.literal("read"),
3549
4119
  filter: objectOrArraySchema,
3550
4120
  args: rootModelReadFilterArgsSchema.optional(),
3551
4121
  options: rootModelReadOptionsSchema.optional()
3552
4122
  }).passthrough(),
3553
- import_zod4.z.object({
4123
+ import_zod5.z.object({
3554
4124
  ...rootEntryBaseSchema,
3555
- target: import_zod4.z.literal("model"),
3556
- op: import_zod4.z.literal("create"),
3557
- data: import_zod4.z.unknown(),
4125
+ target: import_zod5.z.literal("model"),
4126
+ op: import_zod5.z.literal("create"),
4127
+ data: import_zod5.z.unknown(),
3558
4128
  args: rootModelCreateArgsSchema.optional(),
3559
4129
  options: rootModelCreateOptionsSchema.optional()
3560
4130
  }).passthrough(),
3561
- import_zod4.z.object({
4131
+ import_zod5.z.object({
3562
4132
  ...rootEntryBaseSchema,
3563
- target: import_zod4.z.literal("model"),
3564
- op: import_zod4.z.literal("update"),
3565
- id: import_zod4.z.string().min(1),
3566
- data: import_zod4.z.unknown(),
4133
+ target: import_zod5.z.literal("model"),
4134
+ op: import_zod5.z.literal("update"),
4135
+ id: import_zod5.z.string().min(1),
4136
+ data: import_zod5.z.unknown(),
3567
4137
  args: rootModelUpdateArgsSchema.optional(),
3568
4138
  options: rootModelUpdateOptionsSchema.optional()
3569
4139
  }).passthrough(),
3570
- import_zod4.z.object({
4140
+ import_zod5.z.object({
3571
4141
  ...rootEntryBaseSchema,
3572
- target: import_zod4.z.literal("model"),
3573
- op: import_zod4.z.literal("upsert"),
3574
- data: import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()),
4142
+ target: import_zod5.z.literal("model"),
4143
+ op: import_zod5.z.literal("upsert"),
4144
+ data: import_zod5.z.record(import_zod5.z.string(), import_zod5.z.unknown()),
3575
4145
  args: rootModelUpsertArgsSchema.optional(),
3576
4146
  options: rootModelUpsertOptionsSchema.optional()
3577
4147
  }).passthrough(),
3578
- import_zod4.z.object({ ...rootEntryBaseSchema, target: import_zod4.z.literal("model"), op: import_zod4.z.literal("delete"), id: import_zod4.z.string().min(1) }).passthrough(),
3579
- import_zod4.z.object({
4148
+ import_zod5.z.object({ ...rootEntryBaseSchema, target: import_zod5.z.literal("model"), op: import_zod5.z.literal("delete"), id: import_zod5.z.string().min(1) }).passthrough(),
4149
+ import_zod5.z.object({
3580
4150
  ...rootEntryBaseSchema,
3581
- target: import_zod4.z.literal("model"),
3582
- op: import_zod4.z.literal("subList"),
3583
- id: import_zod4.z.string().min(1),
3584
- sub: import_zod4.z.string().min(1),
3585
- filter: import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()).optional(),
4151
+ target: import_zod5.z.literal("model"),
4152
+ op: import_zod5.z.literal("subList"),
4153
+ id: import_zod5.z.string().min(1),
4154
+ sub: import_zod5.z.string().min(1),
4155
+ filter: import_zod5.z.record(import_zod5.z.string(), import_zod5.z.unknown()).optional(),
3586
4156
  args: rootModelSubListArgsSchema.optional()
3587
4157
  }).passthrough(),
3588
- import_zod4.z.object({
4158
+ import_zod5.z.object({
3589
4159
  ...rootEntryBaseSchema,
3590
- target: import_zod4.z.literal("model"),
3591
- op: import_zod4.z.literal("subRead"),
3592
- id: import_zod4.z.string().min(1),
3593
- sub: import_zod4.z.string().min(1),
3594
- subId: import_zod4.z.string().min(1),
4160
+ target: import_zod5.z.literal("model"),
4161
+ op: import_zod5.z.literal("subRead"),
4162
+ id: import_zod5.z.string().min(1),
4163
+ sub: import_zod5.z.string().min(1),
4164
+ subId: import_zod5.z.string().min(1),
3595
4165
  args: rootModelSubReadArgsSchema.optional()
3596
4166
  }).passthrough(),
3597
- import_zod4.z.object({
4167
+ import_zod5.z.object({
3598
4168
  ...rootEntryBaseSchema,
3599
- target: import_zod4.z.literal("model"),
3600
- op: import_zod4.z.literal("subCreate"),
3601
- id: import_zod4.z.string().min(1),
3602
- sub: import_zod4.z.string().min(1),
3603
- data: import_zod4.z.union([import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()), import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))])
4169
+ target: import_zod5.z.literal("model"),
4170
+ op: import_zod5.z.literal("subCreate"),
4171
+ id: import_zod5.z.string().min(1),
4172
+ sub: import_zod5.z.string().min(1),
4173
+ data: import_zod5.z.union([import_zod5.z.record(import_zod5.z.string(), import_zod5.z.unknown()), import_zod5.z.array(import_zod5.z.record(import_zod5.z.string(), import_zod5.z.unknown()))])
3604
4174
  }).passthrough(),
3605
- import_zod4.z.object({
4175
+ import_zod5.z.object({
3606
4176
  ...rootEntryBaseSchema,
3607
- target: import_zod4.z.literal("model"),
3608
- op: import_zod4.z.literal("subUpdate"),
3609
- id: import_zod4.z.string().min(1),
3610
- sub: import_zod4.z.string().min(1),
3611
- subId: import_zod4.z.string().min(1),
3612
- data: import_zod4.z.union([import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()), import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))])
4177
+ target: import_zod5.z.literal("model"),
4178
+ op: import_zod5.z.literal("subUpdate"),
4179
+ id: import_zod5.z.string().min(1),
4180
+ sub: import_zod5.z.string().min(1),
4181
+ subId: import_zod5.z.string().min(1),
4182
+ data: import_zod5.z.union([import_zod5.z.record(import_zod5.z.string(), import_zod5.z.unknown()), import_zod5.z.array(import_zod5.z.record(import_zod5.z.string(), import_zod5.z.unknown()))])
3613
4183
  }).passthrough(),
3614
- import_zod4.z.object({
4184
+ import_zod5.z.object({
3615
4185
  ...rootEntryBaseSchema,
3616
- target: import_zod4.z.literal("model"),
3617
- op: import_zod4.z.literal("subBulkUpdate"),
3618
- id: import_zod4.z.string().min(1),
3619
- sub: import_zod4.z.string().min(1),
3620
- data: import_zod4.z.union([import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()), import_zod4.z.array(import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()))])
4186
+ target: import_zod5.z.literal("model"),
4187
+ op: import_zod5.z.literal("subBulkUpdate"),
4188
+ id: import_zod5.z.string().min(1),
4189
+ sub: import_zod5.z.string().min(1),
4190
+ data: import_zod5.z.union([import_zod5.z.record(import_zod5.z.string(), import_zod5.z.unknown()), import_zod5.z.array(import_zod5.z.record(import_zod5.z.string(), import_zod5.z.unknown()))])
3621
4191
  }).passthrough(),
3622
- import_zod4.z.object({
4192
+ import_zod5.z.object({
3623
4193
  ...rootEntryBaseSchema,
3624
- target: import_zod4.z.literal("model"),
3625
- op: import_zod4.z.literal("subDelete"),
3626
- id: import_zod4.z.string().min(1),
3627
- sub: import_zod4.z.string().min(1),
3628
- subId: import_zod4.z.string().min(1)
4194
+ target: import_zod5.z.literal("model"),
4195
+ op: import_zod5.z.literal("subDelete"),
4196
+ id: import_zod5.z.string().min(1),
4197
+ sub: import_zod5.z.string().min(1),
4198
+ subId: import_zod5.z.string().min(1)
3629
4199
  }).passthrough(),
3630
- import_zod4.z.object({
4200
+ import_zod5.z.object({
3631
4201
  ...rootEntryBaseSchema,
3632
- target: import_zod4.z.literal("model"),
3633
- op: import_zod4.z.literal("distinct"),
3634
- field: import_zod4.z.string().min(1),
4202
+ target: import_zod5.z.literal("model"),
4203
+ op: import_zod5.z.literal("distinct"),
4204
+ field: import_zod5.z.string().min(1),
3635
4205
  filter: objectOrArraySchema.optional()
3636
4206
  }).passthrough(),
3637
- import_zod4.z.object({
4207
+ import_zod5.z.object({
3638
4208
  ...rootEntryBaseSchema,
3639
- target: import_zod4.z.literal("model"),
3640
- op: import_zod4.z.literal("count"),
4209
+ target: import_zod5.z.literal("model"),
4210
+ op: import_zod5.z.literal("count"),
3641
4211
  filter: objectOrArraySchema.optional(),
3642
4212
  options: rootModelCountOptionsSchema.optional()
3643
4213
  }).passthrough()
3644
4214
  ]);
3645
- var rootDataQueryEntrySchema = import_zod4.z.union([
3646
- import_zod4.z.object({
4215
+ var rootDataQueryEntrySchema = import_zod5.z.union([
4216
+ import_zod5.z.object({
3647
4217
  ...rootEntryBaseSchema,
3648
- target: import_zod4.z.literal("data"),
3649
- op: import_zod4.z.literal("list"),
4218
+ target: import_zod5.z.literal("data"),
4219
+ op: import_zod5.z.literal("list"),
3650
4220
  filter: objectOrArraySchema.optional(),
3651
4221
  args: rootDataListArgsSchema.optional(),
3652
4222
  options: rootDataListOptionsSchema.optional()
3653
4223
  }).passthrough(),
3654
- import_zod4.z.object({
4224
+ import_zod5.z.object({
3655
4225
  ...rootEntryBaseSchema,
3656
- target: import_zod4.z.literal("data"),
3657
- op: import_zod4.z.literal("read"),
3658
- id: import_zod4.z.string().min(1),
4226
+ target: import_zod5.z.literal("data"),
4227
+ op: import_zod5.z.literal("read"),
4228
+ id: import_zod5.z.string().min(1),
3659
4229
  args: rootDataReadArgsSchema.optional()
3660
4230
  }).passthrough(),
3661
- import_zod4.z.object({
4231
+ import_zod5.z.object({
3662
4232
  ...rootEntryBaseSchema,
3663
- target: import_zod4.z.literal("data"),
3664
- op: import_zod4.z.literal("read"),
4233
+ target: import_zod5.z.literal("data"),
4234
+ op: import_zod5.z.literal("read"),
3665
4235
  filter: objectOrArraySchema,
3666
4236
  args: rootDataReadArgsSchema.optional()
3667
4237
  }).passthrough()
3668
4238
  ]);
3669
- var rootQuerySchema = import_zod4.z.array(import_zod4.z.union([rootModelQueryEntrySchema, rootDataQueryEntrySchema]));
4239
+ var rootQuerySchema = import_zod5.z.array(import_zod5.z.union([rootModelQueryEntrySchema, rootDataQueryEntrySchema]));
3670
4240
 
3671
4241
  // src/routers/shared.ts
3672
- var parseBooleanString = (str, defaultValue) => str ? str === "true" : defaultValue;
4242
+ var import_utils21 = require("@web-ts-toolkit/utils");
3673
4243
 
3674
4244
  // src/routers/model-router-collection-routes.ts
3675
4245
  function setModelCollectionRoutes(context) {
3676
4246
  const { router, options } = context;
4247
+ const getAdvancedCreateOpenApiBody = () => {
4248
+ const advancedCreateSchema = context.getRequestSchema("requestSchemas.advancedCreate");
4249
+ const dataSchema = context.getRequestSchema("requestSchemas.advancedCreate.data") ?? getNestedOpenApiSchemaDataSource(advancedCreateSchema);
4250
+ const bodySchema = unwrapNestedOpenApiSchemaSource(
4251
+ context.getRequestSchema("requestSchemas.advancedCreate.default") ?? advancedCreateSchema,
4252
+ advancedCreateBodySchema
4253
+ );
4254
+ return dataSchema ? patchOpenApiObjectSchema(bodySchema, { data: dataSchema }) : bodySchema;
4255
+ };
3677
4256
  router.get("", async (req) => {
3678
4257
  await context.assertAllowed(req, "list");
3679
4258
  const { skip, limit, page, page_size, skim, include_permissions, include_count, include_extra_headers } = parseQuery(requestSchemas.listQuery, req.query);
3680
4259
  const svc = context.getPublicService(req);
3681
- const includeCount = parseBooleanString(include_count);
3682
- const includeExtraHeaders = parseBooleanString(include_extra_headers);
4260
+ const includeCount = (0, import_utils21.parseBooleanString)(include_count);
4261
+ const includeExtraHeaders = (0, import_utils21.parseBooleanString)(include_extra_headers);
3683
4262
  const result = await svc._list(
3684
4263
  {},
3685
4264
  { skip, limit, page, pageSize: page_size },
3686
4265
  {
3687
- skim: parseBooleanString(skim),
3688
- includePermissions: parseBooleanString(include_permissions),
4266
+ skim: (0, import_utils21.parseBooleanString)(skim),
4267
+ includePermissions: (0, import_utils21.parseBooleanString)(include_permissions),
3689
4268
  includeCount
3690
4269
  }
3691
4270
  );
3692
4271
  handleResultError(result);
3693
4272
  return formatModelListResponse(req, result, includeCount, includeExtraHeaders);
3694
4273
  });
4274
+ context.registerOpenApiRoute({
4275
+ method: "get",
4276
+ path: "",
4277
+ operationId: `${context.modelName}.list`,
4278
+ summary: `List ${context.modelName} documents`,
4279
+ query: requestSchemas.listQuery
4280
+ });
3695
4281
  router.post(`/${options.queryRouteSegment}`, async (req) => {
3696
4282
  await context.assertAllowed(req, "list");
3697
- const body = parseBodyWithSchema(
4283
+ const body = await parseBodyWithSchema(
3698
4284
  listBodySchema,
3699
4285
  req.body,
3700
4286
  context.getRequestSchema("requestSchemas.advancedList")
@@ -3717,19 +4303,38 @@ function setModelCollectionRoutes(context) {
3717
4303
  handleResultError(result);
3718
4304
  return formatModelListResponse(req, result, includeCount, includeExtraHeaders);
3719
4305
  });
4306
+ context.registerOpenApiRoute({
4307
+ method: "post",
4308
+ path: `/${options.queryRouteSegment}`,
4309
+ operationId: `${context.modelName}.listAdvanced`,
4310
+ summary: `Advanced list ${context.modelName} documents`,
4311
+ body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.advancedList") ?? listBodySchema)
4312
+ });
3720
4313
  router.post("", async (req) => {
3721
4314
  await context.assertAllowed(req, "create");
3722
4315
  const { include_permissions } = parseQuery(requestSchemas.createQuery, req.query);
3723
- const data = parseBodyWithSchema(createBodySchema, req.body, context.getRequestSchema("requestSchemas.create"));
4316
+ const data = await parseBodyWithSchema(
4317
+ createBodySchema,
4318
+ req.body,
4319
+ context.getRequestSchema("requestSchemas.create")
4320
+ );
3724
4321
  const svc = context.getPublicService(req);
3725
- const result = await svc._create(data, {}, { includePermissions: parseBooleanString(include_permissions) });
4322
+ const result = await svc._create(data, {}, { includePermissions: (0, import_utils21.parseBooleanString)(include_permissions) });
3726
4323
  handleResultError(result);
3727
4324
  return formatModelCreatedResponse(result);
3728
4325
  });
4326
+ context.registerOpenApiRoute({
4327
+ method: "post",
4328
+ path: "",
4329
+ operationId: `${context.modelName}.create`,
4330
+ summary: `Create a ${context.modelName} document`,
4331
+ query: requestSchemas.createQuery,
4332
+ body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.create") ?? createBodySchema)
4333
+ });
3729
4334
  router.post(`/${options.mutationRouteSegment}`, async (req) => {
3730
4335
  await context.assertAllowed(req, "create");
3731
4336
  const { include_permissions } = parseQuery(requestSchemas.createQuery, req.query);
3732
- const body = parseNestedBodyWithSchema(
4337
+ const body = await parseNestedBodyWithSchema(
3733
4338
  advancedCreateBodySchema,
3734
4339
  req.body,
3735
4340
  "data",
@@ -3737,7 +4342,7 @@ function setModelCollectionRoutes(context) {
3737
4342
  );
3738
4343
  const { data, select, populate, tasks } = body;
3739
4344
  const advancedOptions = body.options ?? {};
3740
- parseBodyWithSchema(
4345
+ await parseBodyWithSchema(
3741
4346
  advancedCreateBodySchema,
3742
4347
  { data, select, populate, tasks, options: advancedOptions },
3743
4348
  context.getRequestSchema("requestSchemas.advancedCreate.default") ?? context.getRequestSchema("requestSchemas.advancedCreate")
@@ -3748,24 +4353,56 @@ function setModelCollectionRoutes(context) {
3748
4353
  data,
3749
4354
  { select, populate, tasks },
3750
4355
  {
3751
- includePermissions: includePermissions ?? parseBooleanString(include_permissions),
4356
+ includePermissions: includePermissions ?? (0, import_utils21.parseBooleanString)(include_permissions),
3752
4357
  populateAccess
3753
4358
  }
3754
4359
  );
3755
4360
  handleResultError(result);
3756
4361
  return formatModelCreatedResponse(result);
3757
4362
  });
4363
+ context.registerOpenApiRoute({
4364
+ method: "post",
4365
+ path: `/${options.mutationRouteSegment}`,
4366
+ operationId: `${context.modelName}.createAdvanced`,
4367
+ summary: `Advanced create a ${context.modelName} document`,
4368
+ query: requestSchemas.createQuery,
4369
+ body: defineOpenApiSchemaResolver(getAdvancedCreateOpenApiBody)
4370
+ });
3758
4371
  router.get("/new", async (req) => {
3759
4372
  const svc = context.getPublicService(req);
3760
4373
  const result = await svc._new();
3761
4374
  handleResultError(result);
3762
4375
  return unwrapServiceData(result);
3763
4376
  });
4377
+ context.registerOpenApiRoute({
4378
+ method: "get",
4379
+ path: "/new",
4380
+ operationId: `${context.modelName}.new`,
4381
+ summary: `Get a new ${context.modelName} document template`
4382
+ });
3764
4383
  }
3765
4384
 
3766
4385
  // src/routers/model-router-document-routes.ts
3767
4386
  function setModelDocumentRoutes(context) {
3768
4387
  const { router, options, modelName } = context;
4388
+ const getAdvancedUpdateOpenApiBody = () => {
4389
+ const advancedUpdateSchema = context.getRequestSchema("requestSchemas.advancedUpdate");
4390
+ const dataSchema = context.getRequestSchema("requestSchemas.advancedUpdate.data") ?? getNestedOpenApiSchemaDataSource(advancedUpdateSchema);
4391
+ const bodySchema = unwrapNestedOpenApiSchemaSource(
4392
+ context.getRequestSchema("requestSchemas.advancedUpdate.default") ?? advancedUpdateSchema,
4393
+ advancedUpdateBodySchema
4394
+ );
4395
+ return dataSchema ? patchOpenApiObjectSchema(bodySchema, { data: dataSchema }) : bodySchema;
4396
+ };
4397
+ const getAdvancedUpsertOpenApiBody = () => {
4398
+ const advancedUpsertSchema = context.getRequestSchema("requestSchemas.advancedUpsert");
4399
+ const dataSchema = context.getRequestSchema("requestSchemas.advancedUpsert.data") ?? getNestedOpenApiSchemaDataSource(advancedUpsertSchema);
4400
+ const bodySchema = unwrapNestedOpenApiSchemaSource(
4401
+ context.getRequestSchema("requestSchemas.advancedUpsert.default") ?? advancedUpsertSchema,
4402
+ advancedUpsertBodySchema
4403
+ );
4404
+ return dataSchema ? patchOpenApiObjectSchema(bodySchema, { data: dataSchema }) : bodySchema;
4405
+ };
3769
4406
  router.get("/count", async (req) => {
3770
4407
  await context.assertAllowed(req, "count");
3771
4408
  const svc = context.getPublicService(req);
@@ -3773,9 +4410,15 @@ function setModelDocumentRoutes(context) {
3773
4410
  handleResultError(result);
3774
4411
  return unwrapServiceData(result);
3775
4412
  });
4413
+ context.registerOpenApiRoute({
4414
+ method: "get",
4415
+ path: "/count",
4416
+ operationId: `${modelName}.count`,
4417
+ summary: `Count ${modelName} documents`
4418
+ });
3776
4419
  router.post("/count", async (req) => {
3777
4420
  await context.assertAllowed(req, "count");
3778
- const { filter: filter2, options: countOptions = {} } = parseBodyWithSchema(
4421
+ const { filter: filter2, options: countOptions = {} } = await parseBodyWithSchema(
3779
4422
  countBodySchema,
3780
4423
  req.body,
3781
4424
  context.getRequestSchema("requestSchemas.count")
@@ -3788,6 +4431,13 @@ function setModelDocumentRoutes(context) {
3788
4431
  handleResultError(result);
3789
4432
  return unwrapServiceData(result);
3790
4433
  });
4434
+ context.registerOpenApiRoute({
4435
+ method: "post",
4436
+ path: "/count",
4437
+ operationId: `${modelName}.countWithFilter`,
4438
+ summary: `Count ${modelName} documents with a filter`,
4439
+ body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.count") ?? countBodySchema)
4440
+ });
3791
4441
  router.get(`/:${options.idParam}`, async (req) => {
3792
4442
  await context.assertAllowed(req, "read");
3793
4443
  const id = parsePathParam(req.params[options.idParam], options.idParam);
@@ -3797,16 +4447,23 @@ function setModelDocumentRoutes(context) {
3797
4447
  id,
3798
4448
  {},
3799
4449
  {
3800
- includePermissions: parseBooleanString(include_permissions),
3801
- tryList: parseBooleanString(try_list)
4450
+ includePermissions: (0, import_utils21.parseBooleanString)(include_permissions),
4451
+ tryList: (0, import_utils21.parseBooleanString)(try_list)
3802
4452
  }
3803
4453
  );
3804
4454
  handleResultError(result);
3805
4455
  return unwrapServiceData(result);
3806
4456
  });
4457
+ context.registerOpenApiRoute({
4458
+ method: "get",
4459
+ path: `/:${options.idParam}`,
4460
+ operationId: `${modelName}.read`,
4461
+ summary: `Read a ${modelName} document`,
4462
+ query: requestSchemas.readQuery
4463
+ });
3807
4464
  router.post(`/${options.queryRouteSegment}/__filter`, async (req) => {
3808
4465
  await context.assertAllowed(req, "read");
3809
- const body = parseBodyWithSchema(
4466
+ const body = await parseBodyWithSchema(
3810
4467
  readFilterBodySchema,
3811
4468
  req.body,
3812
4469
  context.getRequestSchema("requestSchemas.advancedReadFilter")
@@ -3823,10 +4480,19 @@ function setModelDocumentRoutes(context) {
3823
4480
  handleResultError(result);
3824
4481
  return unwrapServiceData(result);
3825
4482
  });
4483
+ context.registerOpenApiRoute({
4484
+ method: "post",
4485
+ path: `/${options.queryRouteSegment}/__filter`,
4486
+ operationId: `${modelName}.readByFilterAdvanced`,
4487
+ summary: `Read a ${modelName} document by filter`,
4488
+ body: defineOpenApiSchemaResolver(
4489
+ () => context.getRequestSchema("requestSchemas.advancedReadFilter") ?? readFilterBodySchema
4490
+ )
4491
+ });
3826
4492
  router.post(`/${options.queryRouteSegment}/:${options.idParam}`, async (req) => {
3827
4493
  await context.assertAllowed(req, "read");
3828
4494
  const id = parsePathParam(req.params[options.idParam], options.idParam);
3829
- const body = parseBodyWithSchema(
4495
+ const body = await parseBodyWithSchema(
3830
4496
  readByIdBodySchema,
3831
4497
  req.body,
3832
4498
  context.getRequestSchema("requestSchemas.advancedRead")
@@ -3843,29 +4509,50 @@ function setModelDocumentRoutes(context) {
3843
4509
  handleResultError(result);
3844
4510
  return unwrapServiceData(result);
3845
4511
  });
4512
+ context.registerOpenApiRoute({
4513
+ method: "post",
4514
+ path: `/${options.queryRouteSegment}/:${options.idParam}`,
4515
+ operationId: `${modelName}.readAdvanced`,
4516
+ summary: `Read a ${modelName} document with advanced options`,
4517
+ body: defineOpenApiSchemaResolver(
4518
+ () => context.getRequestSchema("requestSchemas.advancedRead") ?? readByIdBodySchema
4519
+ )
4520
+ });
3846
4521
  router.patch(`/:${options.idParam}`, async (req) => {
3847
4522
  await context.assertAllowed(req, "update");
3848
4523
  const id = parsePathParam(req.params[options.idParam], options.idParam);
3849
4524
  const { returning_all, include_permissions } = parseQuery(requestSchemas.updateQuery, req.query);
3850
- const data = parseBodyWithSchema(updateBodySchema, req.body, context.getRequestSchema("requestSchemas.update"));
4525
+ const data = await parseBodyWithSchema(
4526
+ updateBodySchema,
4527
+ req.body,
4528
+ context.getRequestSchema("requestSchemas.update")
4529
+ );
3851
4530
  const svc = context.getPublicService(req);
3852
4531
  const result = await svc._update(
3853
4532
  id,
3854
4533
  data,
3855
4534
  {},
3856
4535
  {
3857
- returningAll: parseBooleanString(returning_all),
3858
- includePermissions: parseBooleanString(include_permissions)
4536
+ returningAll: (0, import_utils21.parseBooleanString)(returning_all),
4537
+ includePermissions: (0, import_utils21.parseBooleanString)(include_permissions)
3859
4538
  }
3860
4539
  );
3861
4540
  handleResultError(result);
3862
4541
  return unwrapServiceData(result);
3863
4542
  });
4543
+ context.registerOpenApiRoute({
4544
+ method: "patch",
4545
+ path: `/:${options.idParam}`,
4546
+ operationId: `${modelName}.update`,
4547
+ summary: `Update a ${modelName} document`,
4548
+ query: requestSchemas.updateQuery,
4549
+ body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.update") ?? updateBodySchema)
4550
+ });
3864
4551
  router.patch(`/${options.mutationRouteSegment}/:${options.idParam}`, async (req) => {
3865
4552
  await context.assertAllowed(req, "update");
3866
4553
  const id = parsePathParam(req.params[options.idParam], options.idParam);
3867
4554
  const { returning_all, include_permissions } = parseQuery(requestSchemas.updateQuery, req.query);
3868
- const body = parseNestedBodyWithSchema(
4555
+ const body = await parseNestedBodyWithSchema(
3869
4556
  advancedUpdateBodySchema,
3870
4557
  req.body,
3871
4558
  "data",
@@ -3873,7 +4560,7 @@ function setModelDocumentRoutes(context) {
3873
4560
  );
3874
4561
  const { data, select, populate, tasks } = body;
3875
4562
  const advancedOptions = body.options ?? {};
3876
- parseBodyWithSchema(
4563
+ await parseBodyWithSchema(
3877
4564
  advancedUpdateBodySchema,
3878
4565
  { data, select, populate, tasks, options: advancedOptions },
3879
4566
  context.getRequestSchema("requestSchemas.advancedUpdate.default") ?? context.getRequestSchema("requestSchemas.advancedUpdate")
@@ -3885,35 +4572,55 @@ function setModelDocumentRoutes(context) {
3885
4572
  data,
3886
4573
  { select, populate, tasks },
3887
4574
  {
3888
- returningAll: returningAll ?? parseBooleanString(returning_all),
3889
- includePermissions: includePermissions ?? parseBooleanString(include_permissions),
4575
+ returningAll: returningAll ?? (0, import_utils21.parseBooleanString)(returning_all),
4576
+ includePermissions: includePermissions ?? (0, import_utils21.parseBooleanString)(include_permissions),
3890
4577
  populateAccess
3891
4578
  }
3892
4579
  );
3893
4580
  handleResultError(result);
3894
4581
  return unwrapServiceData(result);
3895
4582
  });
4583
+ context.registerOpenApiRoute({
4584
+ method: "patch",
4585
+ path: `/${options.mutationRouteSegment}/:${options.idParam}`,
4586
+ operationId: `${modelName}.updateAdvanced`,
4587
+ summary: `Advanced update a ${modelName} document`,
4588
+ query: requestSchemas.updateQuery,
4589
+ body: defineOpenApiSchemaResolver(getAdvancedUpdateOpenApiBody)
4590
+ });
3896
4591
  router.put(`/`, async (req) => {
3897
4592
  await context.assertAllowed(req, "upsert");
3898
4593
  const svc = context.getPublicService(req);
3899
4594
  const { returning_all, include_permissions } = parseQuery(requestSchemas.upsertQuery, req.query);
3900
- const body = parseBodyWithSchema(upsertBodySchema, req.body, context.getRequestSchema("requestSchemas.upsert"));
4595
+ const body = await parseBodyWithSchema(
4596
+ upsertBodySchema,
4597
+ req.body,
4598
+ context.getRequestSchema("requestSchemas.upsert")
4599
+ );
3901
4600
  const result = await svc._upsert(
3902
4601
  body,
3903
4602
  {},
3904
4603
  {
3905
- returningAll: parseBooleanString(returning_all),
3906
- includePermissions: parseBooleanString(include_permissions)
4604
+ returningAll: (0, import_utils21.parseBooleanString)(returning_all),
4605
+ includePermissions: (0, import_utils21.parseBooleanString)(include_permissions)
3907
4606
  }
3908
4607
  );
3909
4608
  handleResultError(result);
3910
4609
  return formatModelUpsertResponse(result);
3911
4610
  });
4611
+ context.registerOpenApiRoute({
4612
+ method: "put",
4613
+ path: "/",
4614
+ operationId: `${modelName}.upsert`,
4615
+ summary: `Upsert a ${modelName} document`,
4616
+ query: requestSchemas.upsertQuery,
4617
+ body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.upsert") ?? upsertBodySchema)
4618
+ });
3912
4619
  router.put(`/${options.mutationRouteSegment}`, async (req) => {
3913
4620
  await context.assertAllowed(req, "upsert");
3914
4621
  const svc = context.getPublicService(req);
3915
4622
  const { returning_all, include_permissions } = parseQuery(requestSchemas.upsertQuery, req.query);
3916
- const body = parseNestedBodyWithSchema(
4623
+ const body = await parseNestedBodyWithSchema(
3917
4624
  advancedUpsertBodySchema,
3918
4625
  req.body,
3919
4626
  "data",
@@ -3921,7 +4628,7 @@ function setModelDocumentRoutes(context) {
3921
4628
  );
3922
4629
  const { data, select, populate, tasks } = body;
3923
4630
  const advancedOptions = body.options ?? {};
3924
- parseBodyWithSchema(
4631
+ await parseBodyWithSchema(
3925
4632
  advancedUpsertBodySchema,
3926
4633
  { data, select, populate, tasks, options: advancedOptions },
3927
4634
  context.getRequestSchema("requestSchemas.advancedUpsert.default") ?? context.getRequestSchema("requestSchemas.advancedUpsert")
@@ -3931,14 +4638,22 @@ function setModelDocumentRoutes(context) {
3931
4638
  data,
3932
4639
  { select, populate, tasks },
3933
4640
  {
3934
- returningAll: returningAll ?? parseBooleanString(returning_all),
3935
- includePermissions: includePermissions ?? parseBooleanString(include_permissions),
4641
+ returningAll: returningAll ?? (0, import_utils21.parseBooleanString)(returning_all),
4642
+ includePermissions: includePermissions ?? (0, import_utils21.parseBooleanString)(include_permissions),
3936
4643
  populateAccess
3937
4644
  }
3938
4645
  );
3939
4646
  handleResultError(result);
3940
4647
  return formatModelUpsertResponse(result);
3941
4648
  });
4649
+ context.registerOpenApiRoute({
4650
+ method: "put",
4651
+ path: `/${options.mutationRouteSegment}`,
4652
+ operationId: `${modelName}.upsertAdvanced`,
4653
+ summary: `Advanced upsert a ${modelName} document`,
4654
+ query: requestSchemas.upsertQuery,
4655
+ body: defineOpenApiSchemaResolver(getAdvancedUpsertOpenApiBody)
4656
+ });
3942
4657
  router.delete(`/:${options.idParam}`, async (req) => {
3943
4658
  await context.assertAllowed(req, "delete");
3944
4659
  const id = parsePathParam(req.params[options.idParam], options.idParam);
@@ -3947,6 +4662,12 @@ function setModelDocumentRoutes(context) {
3947
4662
  handleResultError(result);
3948
4663
  return unwrapServiceData(result);
3949
4664
  });
4665
+ context.registerOpenApiRoute({
4666
+ method: "delete",
4667
+ path: `/:${options.idParam}`,
4668
+ operationId: `${modelName}.delete`,
4669
+ summary: `Delete a ${modelName} document`
4670
+ });
3950
4671
  router.get("/distinct/:field", async (req) => {
3951
4672
  await context.assertAllowed(req, "distinct");
3952
4673
  const field = parsePathParam(req.params.field, "field");
@@ -3955,10 +4676,16 @@ function setModelDocumentRoutes(context) {
3955
4676
  handleResultError(result);
3956
4677
  return unwrapServiceData(result);
3957
4678
  });
4679
+ context.registerOpenApiRoute({
4680
+ method: "get",
4681
+ path: "/distinct/:field",
4682
+ operationId: `${modelName}.distinct`,
4683
+ summary: `Get distinct values for a ${modelName} field`
4684
+ });
3958
4685
  router.post("/distinct/:field", async (req) => {
3959
4686
  await context.assertAllowed(req, "distinct");
3960
4687
  const field = parsePathParam(req.params.field, "field");
3961
- const { filter: filter2 } = parseBodyWithSchema(
4688
+ const { filter: filter2 } = await parseBodyWithSchema(
3962
4689
  distinctBodySchema,
3963
4690
  req.body,
3964
4691
  context.getRequestSchema("requestSchemas.distinct")
@@ -3968,10 +4695,17 @@ function setModelDocumentRoutes(context) {
3968
4695
  handleResultError(result);
3969
4696
  return unwrapServiceData(result);
3970
4697
  });
4698
+ context.registerOpenApiRoute({
4699
+ method: "post",
4700
+ path: "/distinct/:field",
4701
+ operationId: `${modelName}.distinctWithFilter`,
4702
+ summary: `Get distinct values for a ${modelName} field with a filter`,
4703
+ body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.distinct") ?? distinctBodySchema)
4704
+ });
3971
4705
  }
3972
4706
 
3973
4707
  // src/routers/model-router-subdocument-routes.ts
3974
- var import_utils18 = require("@web-ts-toolkit/utils");
4708
+ var import_utils22 = require("@web-ts-toolkit/utils");
3975
4709
  function setModelSubDocumentRoutes(context) {
3976
4710
  const subs = getModelSub(context.modelName);
3977
4711
  for (let x = 0; x < subs.length; x++) {
@@ -3984,12 +4718,18 @@ function setModelSubDocumentRoutes(context) {
3984
4718
  handleResultError(result);
3985
4719
  return unwrapServiceData(result);
3986
4720
  });
4721
+ context.registerOpenApiRoute({
4722
+ method: "get",
4723
+ path: `/:${context.options.idParam}/${sub}`,
4724
+ operationId: `${context.modelName}.${sub}.list`,
4725
+ summary: `List ${sub} subdocuments`
4726
+ });
3987
4727
  context.router.post(
3988
4728
  `/:${context.options.idParam}/${sub}/${context.options.queryRouteSegment}`,
3989
4729
  async (req) => {
3990
4730
  await context.assertAllowed(req, `subs.${sub}.list`);
3991
4731
  const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
3992
- const body = parseBodyWithSchema(
4732
+ const body = await parseBodyWithSchema(
3993
4733
  subListBodySchema,
3994
4734
  req.body,
3995
4735
  context.getRequestSchema("requestSchemas.subList")
@@ -4000,10 +4740,17 @@ function setModelSubDocumentRoutes(context) {
4000
4740
  return unwrapServiceData(result);
4001
4741
  }
4002
4742
  );
4743
+ context.registerOpenApiRoute({
4744
+ method: "post",
4745
+ path: `/:${context.options.idParam}/${sub}/${context.options.queryRouteSegment}`,
4746
+ operationId: `${context.modelName}.${sub}.listAdvanced`,
4747
+ summary: `Advanced list ${sub} subdocuments`,
4748
+ body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.subList") ?? subListBodySchema)
4749
+ });
4003
4750
  context.router.patch(`/:${context.options.idParam}/${sub}`, async (req) => {
4004
4751
  await context.assertAllowed(req, `subs.${sub}.update`);
4005
4752
  const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
4006
- const data = parseBodyWithSchema(
4753
+ const data = await parseBodyWithSchema(
4007
4754
  subMutationBodySchema,
4008
4755
  req.body,
4009
4756
  context.getRequestSchema("requestSchemas.subBulkUpdate")
@@ -4013,6 +4760,15 @@ function setModelSubDocumentRoutes(context) {
4013
4760
  handleResultError(result);
4014
4761
  return unwrapServiceData(result);
4015
4762
  });
4763
+ context.registerOpenApiRoute({
4764
+ method: "patch",
4765
+ path: `/:${context.options.idParam}/${sub}`,
4766
+ operationId: `${context.modelName}.${sub}.bulkUpdate`,
4767
+ summary: `Bulk update ${sub} subdocuments`,
4768
+ body: defineOpenApiSchemaResolver(
4769
+ () => context.getRequestSchema("requestSchemas.subBulkUpdate") ?? subMutationBodySchema
4770
+ )
4771
+ });
4016
4772
  context.router.get(`/:${context.options.idParam}/${sub}/:subId`, async (req) => {
4017
4773
  await context.assertAllowed(req, `subs.${sub}.read`);
4018
4774
  const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
@@ -4022,30 +4778,43 @@ function setModelSubDocumentRoutes(context) {
4022
4778
  handleResultError(result);
4023
4779
  return unwrapServiceData(result);
4024
4780
  });
4781
+ context.registerOpenApiRoute({
4782
+ method: "get",
4783
+ path: `/:${context.options.idParam}/${sub}/:subId`,
4784
+ operationId: `${context.modelName}.${sub}.read`,
4785
+ summary: `Read a ${sub} subdocument`
4786
+ });
4025
4787
  context.router.post(
4026
4788
  `/:${context.options.idParam}/${sub}/:subId/${context.options.queryRouteSegment}`,
4027
4789
  async (req) => {
4028
4790
  await context.assertAllowed(req, `subs.${sub}.read`);
4029
4791
  const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
4030
4792
  const subId = parsePathParam(req.params.subId, "subId");
4031
- const body = parseBodyWithSchema(
4793
+ const body = await parseBodyWithSchema(
4032
4794
  subReadBodySchema,
4033
4795
  req.body,
4034
4796
  context.getRequestSchema("requestSchemas.subRead")
4035
4797
  );
4036
4798
  const populate = body.populate;
4037
- const normalizedPopulate = Array.isArray(populate) ? populate.map((item) => (0, import_utils18.isString)(item) ? { path: item } : item) : (0, import_utils18.isString)(populate) ? { path: populate } : populate ?? [];
4799
+ const normalizedPopulate = Array.isArray(populate) ? populate.map((item) => (0, import_utils22.isString)(item) ? { path: item } : item) : (0, import_utils22.isString)(populate) ? { path: populate } : populate ?? [];
4038
4800
  const svc = context.getPublicService(req);
4039
4801
  const result = await svc.readSub(id, sub, subId, { select: body.select ?? [], populate: normalizedPopulate });
4040
4802
  handleResultError(result);
4041
4803
  return unwrapServiceData(result);
4042
4804
  }
4043
4805
  );
4806
+ context.registerOpenApiRoute({
4807
+ method: "post",
4808
+ path: `/:${context.options.idParam}/${sub}/:subId/${context.options.queryRouteSegment}`,
4809
+ operationId: `${context.modelName}.${sub}.readAdvanced`,
4810
+ summary: `Advanced read a ${sub} subdocument`,
4811
+ body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.subRead") ?? subReadBodySchema)
4812
+ });
4044
4813
  context.router.patch(`/:${context.options.idParam}/${sub}/:subId`, async (req) => {
4045
4814
  await context.assertAllowed(req, `subs.${sub}.update`);
4046
4815
  const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
4047
4816
  const subId = parsePathParam(req.params.subId, "subId");
4048
- const data = parseBodyWithSchema(
4817
+ const data = await parseBodyWithSchema(
4049
4818
  subMutationBodySchema,
4050
4819
  req.body,
4051
4820
  context.getRequestSchema("requestSchemas.subUpdate")
@@ -4055,10 +4824,19 @@ function setModelSubDocumentRoutes(context) {
4055
4824
  handleResultError(result);
4056
4825
  return unwrapServiceData(result);
4057
4826
  });
4827
+ context.registerOpenApiRoute({
4828
+ method: "patch",
4829
+ path: `/:${context.options.idParam}/${sub}/:subId`,
4830
+ operationId: `${context.modelName}.${sub}.update`,
4831
+ summary: `Update a ${sub} subdocument`,
4832
+ body: defineOpenApiSchemaResolver(
4833
+ () => context.getRequestSchema("requestSchemas.subUpdate") ?? subMutationBodySchema
4834
+ )
4835
+ });
4058
4836
  context.router.post(`/:${context.options.idParam}/${sub}`, async (req) => {
4059
4837
  await context.assertAllowed(req, `subs.${sub}.create`);
4060
4838
  const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
4061
- const data = parseBodyWithSchema(
4839
+ const data = await parseBodyWithSchema(
4062
4840
  subMutationBodySchema,
4063
4841
  req.body,
4064
4842
  context.getRequestSchema("requestSchemas.subCreate")
@@ -4068,6 +4846,15 @@ function setModelSubDocumentRoutes(context) {
4068
4846
  handleResultError(result);
4069
4847
  return formatModelCreatedResponse(result);
4070
4848
  });
4849
+ context.registerOpenApiRoute({
4850
+ method: "post",
4851
+ path: `/:${context.options.idParam}/${sub}`,
4852
+ operationId: `${context.modelName}.${sub}.create`,
4853
+ summary: `Create a ${sub} subdocument`,
4854
+ body: defineOpenApiSchemaResolver(
4855
+ () => context.getRequestSchema("requestSchemas.subCreate") ?? subMutationBodySchema
4856
+ )
4857
+ });
4071
4858
  context.router.delete(`/:${context.options.idParam}/${sub}/:subId`, async (req) => {
4072
4859
  await context.assertAllowed(req, `subs.${sub}.delete`);
4073
4860
  const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
@@ -4077,14 +4864,30 @@ function setModelSubDocumentRoutes(context) {
4077
4864
  handleResultError(result);
4078
4865
  return unwrapServiceData(result);
4079
4866
  });
4867
+ context.registerOpenApiRoute({
4868
+ method: "delete",
4869
+ path: `/:${context.options.idParam}/${sub}/:subId`,
4870
+ operationId: `${context.modelName}.${sub}.delete`,
4871
+ summary: `Delete a ${sub} subdocument`
4872
+ });
4080
4873
  }
4081
4874
  }
4082
4875
 
4876
+ // src/openapi/route-registration.ts
4877
+ var import_utils23 = require("@web-ts-toolkit/utils");
4878
+ function registerOpenApiRoute(runtime, basePath, defaultTag, route) {
4879
+ runtime.registerOpenApiRoute({
4880
+ ...route,
4881
+ path: (0, import_utils23.normalizeUrlPath)(basePath + route.path),
4882
+ tags: route.tags ?? [defaultTag]
4883
+ });
4884
+ }
4885
+
4083
4886
  // src/routers/model-router.ts
4084
4887
  var clientErrors2 = import_express_json_router5.default.clientErrors;
4085
4888
  function setOption(parentKey, optionKey, option) {
4086
- const key = (0, import_utils19.isUndefined)(option) ? parentKey : `${parentKey}.${optionKey}`;
4087
- const value = (0, import_utils19.isUndefined)(option) ? optionKey : option;
4889
+ const key = (0, import_utils24.isUndefined)(option) ? parentKey : `${parentKey}.${optionKey}`;
4890
+ const value = (0, import_utils24.isUndefined)(option) ? optionKey : option;
4088
4891
  assertMutableRouterOption("model", key);
4089
4892
  this.runtime.setModelOption(this.modelName, key, value);
4090
4893
  return this;
@@ -4245,7 +5048,7 @@ var ModelRouter = class {
4245
5048
  this.runtime.setModelOptions(modelName, initialOptions);
4246
5049
  attachRuntimeToModel(modelName, this.runtime);
4247
5050
  this.options = this.runtime.getModelOptions(modelName);
4248
- this.fullBasePath = (0, import_utils19.normalizeUrlPath)(this.options.parentPath + this.options.basePath);
5051
+ this.fullBasePath = (0, import_utils24.normalizeUrlPath)(this.options.parentPath + this.options.basePath);
4249
5052
  this.modelName = modelName;
4250
5053
  this.router = new import_express_json_router5.default(this.options.basePath, createSetCore(this.runtime), accessRouterResponseHandler);
4251
5054
  this.model = new model_default(modelName);
@@ -4270,6 +5073,9 @@ var ModelRouter = class {
4270
5073
  const allowed = await req.macl.isAllowed(this.modelName, access);
4271
5074
  if (!allowed) throw new clientErrors2.UnauthorizedError();
4272
5075
  }
5076
+ registerOpenApiRoute(route) {
5077
+ registerOpenApiRoute(this.runtime, this.fullBasePath, this.modelName, route);
5078
+ }
4273
5079
  ///////////////////////
4274
5080
  // Collection Routes //
4275
5081
  ///////////////////////
@@ -4280,7 +5086,8 @@ var ModelRouter = class {
4280
5086
  options: this.options,
4281
5087
  getRequestSchema: this.getRequestSchema.bind(this),
4282
5088
  getPublicService: this.getPublicService.bind(this),
4283
- assertAllowed: this.assertAllowed.bind(this)
5089
+ assertAllowed: this.assertAllowed.bind(this),
5090
+ registerOpenApiRoute: this.registerOpenApiRoute.bind(this)
4284
5091
  });
4285
5092
  }
4286
5093
  /////////////////////
@@ -4293,7 +5100,8 @@ var ModelRouter = class {
4293
5100
  options: this.options,
4294
5101
  getRequestSchema: this.getRequestSchema.bind(this),
4295
5102
  getPublicService: this.getPublicService.bind(this),
4296
- assertAllowed: this.assertAllowed.bind(this)
5103
+ assertAllowed: this.assertAllowed.bind(this),
5104
+ registerOpenApiRoute: this.registerOpenApiRoute.bind(this)
4297
5105
  });
4298
5106
  }
4299
5107
  /////////////////////////
@@ -4306,18 +5114,19 @@ var ModelRouter = class {
4306
5114
  options: this.options,
4307
5115
  getRequestSchema: this.getRequestSchema.bind(this),
4308
5116
  getPublicService: this.getPublicService.bind(this),
4309
- assertAllowed: this.assertAllowed.bind(this)
5117
+ assertAllowed: this.assertAllowed.bind(this),
5118
+ registerOpenApiRoute: this.registerOpenApiRoute.bind(this)
4310
5119
  });
4311
5120
  }
4312
5121
  logEndpoints() {
4313
5122
  runWithRuntime(this.runtime, () => {
4314
- (0, import_utils19.forEach)(this.router.endpoints, ({ method, path }) => {
4315
- logger.info(`${(0, import_utils19.padEnd)(method, 6)} ${(0, import_utils19.normalizeUrlPath)(this.options.parentPath + path)}`);
5123
+ (0, import_utils24.forEach)(this.router.endpoints, ({ method, path }) => {
5124
+ logger.info(`${(0, import_utils24.padEnd)(method, 6)} ${(0, import_utils24.normalizeUrlPath)(this.options.parentPath + path)}`);
4316
5125
  });
4317
5126
  });
4318
5127
  }
4319
5128
  set(keyOrOptions, value) {
4320
- if (arguments.length === 2 && (0, import_utils19.isString)(keyOrOptions)) {
5129
+ if (arguments.length === 2 && (0, import_utils24.isString)(keyOrOptions)) {
4321
5130
  assertMutableRouterOption("model", keyOrOptions);
4322
5131
  this.runtime.setModelOption(
4323
5132
  this.modelName,
@@ -4325,7 +5134,7 @@ var ModelRouter = class {
4325
5134
  value
4326
5135
  );
4327
5136
  }
4328
- if (arguments.length === 1 && (0, import_utils19.isPlainObject)(keyOrOptions)) {
5137
+ if (arguments.length === 1 && (0, import_utils24.isPlainObject)(keyOrOptions)) {
4329
5138
  assertMutableRouterOptions("model", keyOrOptions);
4330
5139
  this.runtime.setModelOptions(this.modelName, keyOrOptions);
4331
5140
  }
@@ -4348,7 +5157,7 @@ var ModelRouter = class {
4348
5157
 
4349
5158
  // src/routers/root-router.ts
4350
5159
  var import_express_json_router6 = __toESM(require("@web-ts-toolkit/express-json-router"));
4351
- var import_utils20 = require("@web-ts-toolkit/utils");
5160
+ var import_utils25 = require("@web-ts-toolkit/utils");
4352
5161
 
4353
5162
  // src/core-data.ts
4354
5163
  var DataCore = class {
@@ -4521,7 +5330,7 @@ var createErrorResult = (code, detail) => ({
4521
5330
  code,
4522
5331
  errors: [{ detail }]
4523
5332
  });
4524
- var normalizeSubPopulate = (populate) => Array.isArray(populate) ? populate.map((item) => (0, import_utils20.isString)(item) ? { path: item } : item) : (0, import_utils20.isString)(populate) ? { path: populate } : populate ?? [];
5333
+ var normalizeSubPopulate = (populate) => Array.isArray(populate) ? populate.map((item) => (0, import_utils25.isString)(item) ? { path: item } : item) : (0, import_utils25.isString)(populate) ? { path: populate } : populate ?? [];
4525
5334
  var RootRouter = class {
4526
5335
  constructor(options = { basePath: "", operationAccess: true }, runtime = defaultRuntime) {
4527
5336
  this.modelOperations = {
@@ -4594,6 +5403,9 @@ var RootRouter = class {
4594
5403
  );
4595
5404
  this.setRoutes();
4596
5405
  }
5406
+ registerOpenApiRoute(route) {
5407
+ registerOpenApiRoute(this.runtime, (0, import_utils25.normalizeUrlPath)(this.basename), "root", route);
5408
+ }
4597
5409
  wrapResult(index, item, result) {
4598
5410
  return {
4599
5411
  index,
@@ -4653,7 +5465,7 @@ var RootRouter = class {
4653
5465
  groupItemsByOrder(items) {
4654
5466
  return items.reduce((acc, item, index) => {
4655
5467
  let order = 0;
4656
- if ((0, import_utils20.isNumber)(item.order)) {
5468
+ if ((0, import_utils25.isNumber)(item.order)) {
4657
5469
  order = item.order < 0 ? 0 : item.order;
4658
5470
  }
4659
5471
  if (!acc[order]) {
@@ -4677,7 +5489,14 @@ var RootRouter = class {
4677
5489
  const arrResult = await Promise.all(groupedItems[x].map(({ item, index }) => this.processOp(req, item, index)));
4678
5490
  results.push(...arrResult);
4679
5491
  }
4680
- return (0, import_utils20.orderBy)(results, ["index"], ["asc"]);
5492
+ return (0, import_utils25.orderBy)(results, ["index"], ["asc"]);
5493
+ });
5494
+ this.registerOpenApiRoute({
5495
+ method: "post",
5496
+ path: "",
5497
+ operationId: "root.query",
5498
+ summary: "Execute batched model and data operations",
5499
+ body: rootQuerySchema
4681
5500
  });
4682
5501
  }
4683
5502
  get routes() {
@@ -4687,11 +5506,11 @@ var RootRouter = class {
4687
5506
 
4688
5507
  // src/routers/data-router.ts
4689
5508
  var import_express_json_router7 = __toESM(require("@web-ts-toolkit/express-json-router"));
4690
- var import_utils21 = require("@web-ts-toolkit/utils");
5509
+ var import_utils26 = require("@web-ts-toolkit/utils");
4691
5510
  var clientErrors4 = import_express_json_router7.default.clientErrors;
4692
5511
  function setOption2(parentKey, optionKey, option) {
4693
- const key = (0, import_utils21.isUndefined)(option) ? parentKey : `${parentKey}.${optionKey}`;
4694
- const value = (0, import_utils21.isUndefined)(option) ? optionKey : option;
5512
+ const key = (0, import_utils26.isUndefined)(option) ? parentKey : `${parentKey}.${optionKey}`;
5513
+ const value = (0, import_utils26.isUndefined)(option) ? optionKey : option;
4695
5514
  assertMutableRouterOption("data", key);
4696
5515
  this.runtime.setDataOption(this.dataName, key, value);
4697
5516
  return this;
@@ -4727,7 +5546,7 @@ var DataRouter = class {
4727
5546
  this.runtime = runtime;
4728
5547
  this.runtime.setDataOptions(dataName, initialOptions);
4729
5548
  this.options = this.runtime.getDataOptions(dataName);
4730
- this.fullBasePath = (0, import_utils21.normalizeUrlPath)(this.options.parentPath + this.options.basePath);
5549
+ this.fullBasePath = (0, import_utils26.normalizeUrlPath)(this.options.parentPath + this.options.basePath);
4731
5550
  this.dataName = dataName;
4732
5551
  this.router = new import_express_json_router7.default(this.options.basePath, createSetDataCore(this.runtime), accessRouterResponseHandler);
4733
5552
  this.setCollectionRoutes();
@@ -4746,6 +5565,9 @@ var DataRouter = class {
4746
5565
  const allowed = await req.dacl.isAllowed(this.dataName, access);
4747
5566
  if (!allowed) throw new clientErrors4.UnauthorizedError();
4748
5567
  }
5568
+ registerOpenApiRoute(route) {
5569
+ registerOpenApiRoute(this.runtime, this.fullBasePath, this.dataName, route);
5570
+ }
4749
5571
  ///////////////////////
4750
5572
  // Collection Routes //
4751
5573
  ///////////////////////
@@ -4757,8 +5579,8 @@ var DataRouter = class {
4757
5579
  req.query
4758
5580
  );
4759
5581
  const svc = this.getService(req);
4760
- const includeCount = parseBooleanString(include_count);
4761
- const includeExtraHeaders = parseBooleanString(include_extra_headers);
5582
+ const includeCount = (0, import_utils21.parseBooleanString)(include_count);
5583
+ const includeExtraHeaders = (0, import_utils21.parseBooleanString)(include_extra_headers);
4762
5584
  const result = await svc.find(
4763
5585
  {},
4764
5586
  { skip, limit, page, pageSize: page_size },
@@ -4770,6 +5592,13 @@ var DataRouter = class {
4770
5592
  const decoratedResult = await decorateDataListResult(svc, result);
4771
5593
  return formatListResponse(req, decoratedResult, includeCount, includeExtraHeaders);
4772
5594
  });
5595
+ this.registerOpenApiRoute({
5596
+ method: "get",
5597
+ path: "",
5598
+ operationId: `${this.dataName}.list`,
5599
+ summary: `List ${this.dataName} records`,
5600
+ query: requestSchemas.listQuery
5601
+ });
4773
5602
  this.router.post(`/${this.options.queryRouteSegment}`, async (req) => {
4774
5603
  await this.assertAllowed(req, "list");
4775
5604
  let {
@@ -4781,7 +5610,7 @@ var DataRouter = class {
4781
5610
  page,
4782
5611
  pageSize,
4783
5612
  options = {}
4784
- } = parseBodyWithSchema(dataListBodySchema, req.body, this.getRequestSchema("requestSchemas.advancedList"));
5613
+ } = await parseBodyWithSchema(dataListBodySchema, req.body, this.getRequestSchema("requestSchemas.advancedList"));
4785
5614
  const { includeCount, includeExtraHeaders } = options;
4786
5615
  const svc = this.getService(req);
4787
5616
  const result = await svc.find(
@@ -4793,6 +5622,15 @@ var DataRouter = class {
4793
5622
  const decoratedResult = await decorateDataListResult(svc, result);
4794
5623
  return formatListResponse(req, decoratedResult, includeCount, includeExtraHeaders);
4795
5624
  });
5625
+ this.registerOpenApiRoute({
5626
+ method: "post",
5627
+ path: `/${this.options.queryRouteSegment}`,
5628
+ operationId: `${this.dataName}.listAdvanced`,
5629
+ summary: `Advanced list ${this.dataName} records`,
5630
+ body: defineOpenApiSchemaResolver(
5631
+ () => this.getRequestSchema("requestSchemas.advancedList") ?? dataListBodySchema
5632
+ )
5633
+ });
4796
5634
  }
4797
5635
  /////////////////////
4798
5636
  // Document Routes //
@@ -4807,9 +5645,15 @@ var DataRouter = class {
4807
5645
  const decoratedResult = await decorateDataSingleResult(svc, result);
4808
5646
  return decoratedResult.data;
4809
5647
  });
5648
+ this.registerOpenApiRoute({
5649
+ method: "get",
5650
+ path: `/:${this.options.idParam}`,
5651
+ operationId: `${this.dataName}.read`,
5652
+ summary: `Read a ${this.dataName} record`
5653
+ });
4810
5654
  this.router.post(`/${this.options.queryRouteSegment}/__filter`, async (req) => {
4811
5655
  await this.assertAllowed(req, "read");
4812
- let { filter: filter2, select } = parseBodyWithSchema(
5656
+ let { filter: filter2, select } = await parseBodyWithSchema(
4813
5657
  dataReadFilterBodySchema,
4814
5658
  req.body,
4815
5659
  this.getRequestSchema("requestSchemas.advancedReadFilter")
@@ -4820,10 +5664,19 @@ var DataRouter = class {
4820
5664
  const decoratedResult = await decorateDataSingleResult(svc, result);
4821
5665
  return decoratedResult.data;
4822
5666
  });
5667
+ this.registerOpenApiRoute({
5668
+ method: "post",
5669
+ path: `/${this.options.queryRouteSegment}/__filter`,
5670
+ operationId: `${this.dataName}.readByFilter`,
5671
+ summary: `Read a ${this.dataName} record by filter`,
5672
+ body: defineOpenApiSchemaResolver(
5673
+ () => this.getRequestSchema("requestSchemas.advancedReadFilter") ?? dataReadFilterBodySchema
5674
+ )
5675
+ });
4823
5676
  this.router.post(`/${this.options.queryRouteSegment}/:${this.options.idParam}`, async (req) => {
4824
5677
  await this.assertAllowed(req, "read");
4825
5678
  const id = parsePathParam(req.params[this.options.idParam], this.options.idParam);
4826
- let { select } = parseBodyWithSchema(
5679
+ let { select } = await parseBodyWithSchema(
4827
5680
  dataReadByIdBodySchema,
4828
5681
  req.body,
4829
5682
  this.getRequestSchema("requestSchemas.advancedRead")
@@ -4834,13 +5687,22 @@ var DataRouter = class {
4834
5687
  const decoratedResult = await decorateDataSingleResult(svc, result);
4835
5688
  return decoratedResult.data;
4836
5689
  });
5690
+ this.registerOpenApiRoute({
5691
+ method: "post",
5692
+ path: `/${this.options.queryRouteSegment}/:${this.options.idParam}`,
5693
+ operationId: `${this.dataName}.readAdvanced`,
5694
+ summary: `Advanced read a ${this.dataName} record`,
5695
+ body: defineOpenApiSchemaResolver(
5696
+ () => this.getRequestSchema("requestSchemas.advancedRead") ?? dataReadByIdBodySchema
5697
+ )
5698
+ });
4837
5699
  }
4838
5700
  set(keyOrOptions, value) {
4839
- if (arguments.length === 2 && (0, import_utils21.isString)(keyOrOptions)) {
5701
+ if (arguments.length === 2 && (0, import_utils26.isString)(keyOrOptions)) {
4840
5702
  assertMutableRouterOption("data", keyOrOptions);
4841
5703
  this.runtime.setDataOption(this.dataName, keyOrOptions, value);
4842
5704
  }
4843
- if (arguments.length === 1 && (0, import_utils21.isPlainObject)(keyOrOptions)) {
5705
+ if (arguments.length === 1 && (0, import_utils26.isPlainObject)(keyOrOptions)) {
4844
5706
  assertMutableRouterOptions("data", keyOrOptions);
4845
5707
  this.runtime.setDataOptions(this.dataName, keyOrOptions);
4846
5708
  }
@@ -4863,6 +5725,62 @@ var DataRouter = class {
4863
5725
 
4864
5726
  // src/routers/index.ts
4865
5727
  var import_express_json_router8 = __toESM(require("@web-ts-toolkit/express-json-router"));
5728
+
5729
+ // src/openapi/router.ts
5730
+ var import_express = __toESM(require("express"));
5731
+ var import_node_path = require("path");
5732
+ var escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
5733
+ var renderDocsHtml = (specPath, title, cssUrl, bundleUrl) => `<!doctype html>
5734
+ <html lang="en">
5735
+ <head>
5736
+ <meta charset="utf-8" />
5737
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
5738
+ <title>${escapeHtml(title)}</title>
5739
+ <link rel="stylesheet" href="${escapeHtml(cssUrl)}" />
5740
+ </head>
5741
+ <body>
5742
+ <div id="swagger-ui"></div>
5743
+ <script src="${escapeHtml(bundleUrl)}"></script>
5744
+ <script>
5745
+ window.ui = SwaggerUIBundle({
5746
+ url: ${JSON.stringify(specPath)},
5747
+ dom_id: '#swagger-ui',
5748
+ deepLinking: true,
5749
+ presets: [SwaggerUIBundle.presets.apis],
5750
+ layout: 'BaseLayout',
5751
+ });
5752
+ </script>
5753
+ </body>
5754
+ </html>`;
5755
+ var getRelativeSpecPath = (docsPath, jsonPath) => {
5756
+ const docsDir = import_node_path.posix.dirname(docsPath.startsWith("/") ? docsPath : `/${docsPath}`);
5757
+ const normalizedJsonPath = jsonPath.startsWith("/") ? jsonPath : `/${jsonPath}`;
5758
+ return import_node_path.posix.relative(docsDir, normalizedJsonPath) || import_node_path.posix.basename(normalizedJsonPath);
5759
+ };
5760
+ function createOpenApiRouter(runtime, options = {}) {
5761
+ const router = import_express.default.Router();
5762
+ const jsonPath = options.jsonPath ?? "/openapi.json";
5763
+ const docsPath = options.docsPath ?? "/docs";
5764
+ const swaggerUiCssUrl = options.swaggerUiCssUrl ?? "https://unpkg.com/swagger-ui-dist@5/swagger-ui.css";
5765
+ const swaggerUiBundleUrl = options.swaggerUiBundleUrl ?? "https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js";
5766
+ const info = {
5767
+ title: options.title ?? "Access Router API",
5768
+ version: options.version ?? "0.0.0",
5769
+ description: options.description,
5770
+ servers: options.servers
5771
+ };
5772
+ router.get(jsonPath, (_req, res) => {
5773
+ res.json(runtime.getOpenApiSpec(info));
5774
+ });
5775
+ if (docsPath !== false) {
5776
+ router.get(docsPath, (_req, res) => {
5777
+ res.type("html").send(renderDocsHtml(getRelativeSpecPath(docsPath, jsonPath), info.title, swaggerUiCssUrl, swaggerUiBundleUrl));
5778
+ });
5779
+ }
5780
+ return router;
5781
+ }
5782
+
5783
+ // src/routers/index.ts
4866
5784
  var hasRoutes = (input) => {
4867
5785
  return typeof input === "object" && input !== null && "routes" in input;
4868
5786
  };
@@ -4870,7 +5788,7 @@ var resolveRoutes = (input) => {
4870
5788
  return hasRoutes(input) ? input.routes : input;
4871
5789
  };
4872
5790
  function combineRoutes(...inputs) {
4873
- const router = import_express.default.Router();
5791
+ const router = import_express2.default.Router();
4874
5792
  inputs.forEach((input) => {
4875
5793
  router.use(resolveRoutes(input));
4876
5794
  });
@@ -4882,7 +5800,7 @@ var accessRouterResponseHandler = import_express_json_router8.default.createHand
4882
5800
  });
4883
5801
  accessRouterResponseHandler.errorMessageProvider = function(error) {
4884
5802
  const errorLike = error;
4885
- console.error(error);
5803
+ logger.error(error);
4886
5804
  return errorLike.message || errorLike._message || String(error);
4887
5805
  };
4888
5806
 
@@ -4904,17 +5822,20 @@ function createRuntimeApi(runtime) {
4904
5822
  wtt2.runtime = runtime;
4905
5823
  wtt2.createRouter = function(modelName, options) {
4906
5824
  const resolvedModelName = typeof modelName === "string" ? modelName : modelName && "modelName" in modelName ? modelName.modelName : modelName;
4907
- return (0, import_utils22.isUndefined)(options) ? new RootRouter(modelName, runtime) : new ModelRouter(resolvedModelName, options, runtime);
5825
+ return (0, import_utils27.isUndefined)(options) ? new RootRouter(modelName, runtime) : new ModelRouter(resolvedModelName, options, runtime);
4908
5826
  };
4909
5827
  wtt2.createDataRouter = function(dataName, options) {
4910
5828
  return new DataRouter(dataName, options, runtime);
4911
5829
  };
5830
+ wtt2.createOpenApiRouter = function(options) {
5831
+ return createOpenApiRouter(runtime, options);
5832
+ };
4912
5833
  wtt2.combineRoutes = combineRoutes;
4913
5834
  wtt2.set = function(keyOrOptions, value) {
4914
- if (arguments.length === 2 && (0, import_utils22.isString)(keyOrOptions)) {
5835
+ if (arguments.length === 2 && (0, import_utils27.isString)(keyOrOptions)) {
4915
5836
  return runtime.setGlobalOption(keyOrOptions, value);
4916
5837
  }
4917
- if (arguments.length === 1 && (0, import_utils22.isPlainObject)(keyOrOptions)) {
5838
+ if (arguments.length === 1 && (0, import_utils27.isPlainObject)(keyOrOptions)) {
4918
5839
  return runtime.setGlobalOptions(keyOrOptions);
4919
5840
  }
4920
5841
  };
@@ -4952,6 +5873,18 @@ var index_default = acl;
4952
5873
  acl,
4953
5874
  combineRoutes,
4954
5875
  createAccessRuntime,
5876
+ createOpenApiRouter,
5877
+ defineRequestSchema,
5878
+ fromAjv,
5879
+ fromArkType,
5880
+ fromIoTs,
5881
+ fromJoi,
5882
+ fromStandardSchema,
5883
+ fromSuperstruct,
5884
+ fromValibot,
5885
+ fromVine,
5886
+ fromYup,
5887
+ fromZod,
4955
5888
  getDefaultModelOption,
4956
5889
  getDefaultModelOptions,
4957
5890
  getGlobalOption,