@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/README.md +59 -7
- package/advanced.d.mts +39 -171
- package/advanced.d.ts +39 -171
- package/advanced.js +326 -20
- package/advanced.mjs +315 -19
- package/index.d.mts +81 -3
- package/index.d.ts +81 -3
- package/index.js +1514 -581
- package/index.mjs +1333 -421
- package/package.json +12 -8
- package/{service-DLKAswCS.d.mts → parsers-Ce1grlLx.d.mts} +363 -60
- package/{service-DLKAswCS.d.ts → parsers-Ce1grlLx.d.ts} +363 -60
package/index.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import { isPlainObject as
|
|
2
|
+
import { isPlainObject as isPlainObject14, isString as isString12, isUndefined as isUndefined4 } from "@web-ts-toolkit/utils";
|
|
3
3
|
|
|
4
4
|
// src/middleware.ts
|
|
5
5
|
import JsonRouter2 from "@web-ts-toolkit/express-json-router";
|
|
6
|
-
import { isArray as
|
|
6
|
+
import { isArray as isArray10, isFunction as isFunction6, isPlainObject as isPlainObject11, isString as isString7 } from "@web-ts-toolkit/utils";
|
|
7
7
|
|
|
8
8
|
// src/core.ts
|
|
9
9
|
import {
|
|
10
10
|
castArray as castArray5,
|
|
11
11
|
compact as compact3,
|
|
12
|
-
forEach as
|
|
13
|
-
isArray as
|
|
12
|
+
forEach as forEach7,
|
|
13
|
+
isArray as isArray9,
|
|
14
14
|
isBoolean as isBoolean5,
|
|
15
15
|
isFunction as isFunction5,
|
|
16
16
|
isString as isString6,
|
|
@@ -25,11 +25,11 @@ import {
|
|
|
25
25
|
addLeadingSlash,
|
|
26
26
|
forEach as forEach2,
|
|
27
27
|
get as get3,
|
|
28
|
-
isArray as
|
|
28
|
+
isArray as isArray4,
|
|
29
29
|
isBoolean,
|
|
30
30
|
isFunction,
|
|
31
31
|
isNil as isNil2,
|
|
32
|
-
isPlainObject as
|
|
32
|
+
isPlainObject as isPlainObject7,
|
|
33
33
|
isString as isString4,
|
|
34
34
|
keys
|
|
35
35
|
} from "@web-ts-toolkit/utils";
|
|
@@ -51,20 +51,11 @@ var findElementById = (collection, id) => {
|
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
// src/helpers/document.ts
|
|
54
|
-
import {
|
|
55
|
-
|
|
56
|
-
// src/lib.ts
|
|
57
|
-
import { Document, Schema } from "mongoose";
|
|
58
|
-
import { isPlainObject } from "@web-ts-toolkit/utils";
|
|
59
|
-
var isSchema = (val) => val instanceof Schema;
|
|
60
|
-
var isObjectIdType = (val) => val === "ObjectId" || val === Schema.Types.ObjectId;
|
|
61
|
-
var isReference = (val) => isPlainObject(val) && !!val.ref && isObjectIdType(val.type);
|
|
62
|
-
var isDocument = function isDocument2(doc) {
|
|
63
|
-
return doc instanceof Document;
|
|
64
|
-
};
|
|
54
|
+
import { Document } from "mongoose";
|
|
55
|
+
import { get, isPlainObject as isPlainObject2, pick, set } from "@web-ts-toolkit/utils";
|
|
65
56
|
|
|
66
57
|
// src/helpers/query.ts
|
|
67
|
-
import { flattenDeep, isNaN, isNil, isPlainObject
|
|
58
|
+
import { flattenDeep, isNaN, isNil, isPlainObject, isString, reduce } from "@web-ts-toolkit/utils";
|
|
68
59
|
function genPagination({
|
|
69
60
|
skip,
|
|
70
61
|
limit,
|
|
@@ -92,7 +83,7 @@ function parseSortString(sortString) {
|
|
|
92
83
|
}
|
|
93
84
|
function normalizeSelect(select) {
|
|
94
85
|
if (Array.isArray(select)) return flattenDeep(select.map(normalizeSelect));
|
|
95
|
-
if (
|
|
86
|
+
if (isPlainObject(select)) {
|
|
96
87
|
return reduce(
|
|
97
88
|
select,
|
|
98
89
|
(ret, val, key) => {
|
|
@@ -108,17 +99,21 @@ function normalizeSelect(select) {
|
|
|
108
99
|
}
|
|
109
100
|
|
|
110
101
|
// src/helpers/document.ts
|
|
111
|
-
|
|
102
|
+
import { isArray, isPromise, isString as isString2 } from "@web-ts-toolkit/utils";
|
|
103
|
+
function isDocument(doc) {
|
|
104
|
+
return doc instanceof Document;
|
|
105
|
+
}
|
|
106
|
+
function getDocValue(doc, path, defaultValue) {
|
|
112
107
|
if (isDocument(doc)) {
|
|
113
|
-
return get(doc._doc, path,
|
|
114
|
-
} else if (
|
|
115
|
-
return get(doc, path,
|
|
108
|
+
return get(doc._doc, path, defaultValue);
|
|
109
|
+
} else if (isPlainObject2(doc)) {
|
|
110
|
+
return get(doc, path, defaultValue);
|
|
116
111
|
}
|
|
117
112
|
}
|
|
118
113
|
function setDocValue(doc, path, value) {
|
|
119
114
|
if (isDocument(doc)) {
|
|
120
115
|
set(doc._doc, path, value);
|
|
121
|
-
} else if (
|
|
116
|
+
} else if (isPlainObject2(doc)) {
|
|
122
117
|
set(doc, path, value);
|
|
123
118
|
}
|
|
124
119
|
}
|
|
@@ -207,16 +202,19 @@ function handleResultError(result) {
|
|
|
207
202
|
}
|
|
208
203
|
|
|
209
204
|
// src/helpers/index.ts
|
|
210
|
-
import {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
205
|
+
import { forEach, isArray as isArray2, isEmpty, isObject, isPlainObject as isPlainObject4, isString as isString3, mapValuesAsync } from "@web-ts-toolkit/utils";
|
|
206
|
+
|
|
207
|
+
// src/lib.ts
|
|
208
|
+
import { Document as Document2, Schema } from "mongoose";
|
|
209
|
+
import { isPlainObject as isPlainObject3 } from "@web-ts-toolkit/utils";
|
|
210
|
+
var isSchema = (val) => val instanceof Schema;
|
|
211
|
+
var isObjectIdType = (val) => val === "ObjectId" || val === Schema.Types.ObjectId;
|
|
212
|
+
var isReference = (val) => isPlainObject3(val) && !!val.ref && isObjectIdType(val.type);
|
|
213
|
+
var isDocument2 = function isDocument3(doc) {
|
|
214
|
+
return doc instanceof Document2;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
// src/helpers/index.ts
|
|
220
218
|
function recurseObject(obj) {
|
|
221
219
|
if (isSchema(obj)) {
|
|
222
220
|
return buildRefs(obj.tree);
|
|
@@ -266,7 +264,7 @@ function buildSubPaths(schema) {
|
|
|
266
264
|
}
|
|
267
265
|
async function iterateQuery(query, handler) {
|
|
268
266
|
if (!isPlainObject4(query)) return query;
|
|
269
|
-
if (!handler) return
|
|
267
|
+
if (!handler) return query;
|
|
270
268
|
const queryObject = query;
|
|
271
269
|
return mapValuesAsync(queryObject, async (val, key) => {
|
|
272
270
|
if (isPlainObject4(val)) {
|
|
@@ -295,6 +293,252 @@ var createValidator = (fn) => {
|
|
|
295
293
|
return { stringHandler, arrayHandler };
|
|
296
294
|
};
|
|
297
295
|
|
|
296
|
+
// src/openapi/build-spec.ts
|
|
297
|
+
import { isArray as isArray3, isPlainObject as isPlainObject6 } from "@web-ts-toolkit/utils";
|
|
298
|
+
|
|
299
|
+
// src/openapi/responses.ts
|
|
300
|
+
var json = (schema) => ({
|
|
301
|
+
content: {
|
|
302
|
+
"application/json": {
|
|
303
|
+
schema
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
var problemJson = {
|
|
308
|
+
content: {
|
|
309
|
+
"application/problem+json": {
|
|
310
|
+
schema: {
|
|
311
|
+
type: "object",
|
|
312
|
+
properties: {
|
|
313
|
+
type: { type: "string" },
|
|
314
|
+
title: { type: "string" },
|
|
315
|
+
status: { type: "number" },
|
|
316
|
+
detail: { type: "string" },
|
|
317
|
+
errors: { type: "array", items: {} }
|
|
318
|
+
},
|
|
319
|
+
additionalProperties: true
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
var genericDataSchema = { type: "object", additionalProperties: true };
|
|
325
|
+
var genericListSchema = { type: "array", items: genericDataSchema };
|
|
326
|
+
var openApiResponses = {
|
|
327
|
+
single(description = "Success") {
|
|
328
|
+
return {
|
|
329
|
+
200: { description, ...json(genericDataSchema) },
|
|
330
|
+
400: { description: "Bad Request", ...problemJson },
|
|
331
|
+
401: { description: "Unauthorized", ...problemJson },
|
|
332
|
+
404: { description: "Not Found", ...problemJson }
|
|
333
|
+
};
|
|
334
|
+
},
|
|
335
|
+
list(description = "Success") {
|
|
336
|
+
return {
|
|
337
|
+
200: { description, ...json(genericListSchema) },
|
|
338
|
+
400: { description: "Bad Request", ...problemJson },
|
|
339
|
+
401: { description: "Unauthorized", ...problemJson }
|
|
340
|
+
};
|
|
341
|
+
},
|
|
342
|
+
create(description = "Created") {
|
|
343
|
+
return {
|
|
344
|
+
201: { description, ...json(genericDataSchema) },
|
|
345
|
+
400: { description: "Bad Request", ...problemJson },
|
|
346
|
+
401: { description: "Unauthorized", ...problemJson }
|
|
347
|
+
};
|
|
348
|
+
},
|
|
349
|
+
delete(description = "Deleted") {
|
|
350
|
+
return {
|
|
351
|
+
200: { description, ...json(genericDataSchema) },
|
|
352
|
+
400: { description: "Bad Request", ...problemJson },
|
|
353
|
+
401: { description: "Unauthorized", ...problemJson },
|
|
354
|
+
404: { description: "Not Found", ...problemJson }
|
|
355
|
+
};
|
|
356
|
+
},
|
|
357
|
+
batch(description = "Success") {
|
|
358
|
+
return {
|
|
359
|
+
200: { description, ...json(genericListSchema) },
|
|
360
|
+
400: { description: "Bad Request", ...problemJson },
|
|
361
|
+
401: { description: "Unauthorized", ...problemJson }
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
// src/openapi/schemas.ts
|
|
367
|
+
import { z } from "zod";
|
|
368
|
+
import { isPlainObject as isPlainObject5 } from "@web-ts-toolkit/utils";
|
|
369
|
+
var fallbackObjectSchema = { type: "object", additionalProperties: true };
|
|
370
|
+
function patchOpenApiObjectSchema(source, properties) {
|
|
371
|
+
return {
|
|
372
|
+
kind: "objectProperties",
|
|
373
|
+
source,
|
|
374
|
+
properties
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
function defineOpenApiSchemaResolver(resolve) {
|
|
378
|
+
return {
|
|
379
|
+
kind: "schemaResolver",
|
|
380
|
+
resolve
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
function getNestedOpenApiSchemaDataSource(source) {
|
|
384
|
+
return isPlainObject5(source) && "data" in source ? source.data : void 0;
|
|
385
|
+
}
|
|
386
|
+
function unwrapNestedOpenApiSchemaSource(source, fallback) {
|
|
387
|
+
if (isPlainObject5(source) && ("default" in source || "data" in source)) {
|
|
388
|
+
return source.default ?? fallback;
|
|
389
|
+
}
|
|
390
|
+
return source ?? fallback;
|
|
391
|
+
}
|
|
392
|
+
function isOpenApiSchemaPatch(source) {
|
|
393
|
+
return isPlainObject5(source) && source.kind === "objectProperties";
|
|
394
|
+
}
|
|
395
|
+
function isOpenApiSchemaResolver(source) {
|
|
396
|
+
return isPlainObject5(source) && source.kind === "schemaResolver" && typeof source.resolve === "function";
|
|
397
|
+
}
|
|
398
|
+
function isJsonSchemaLike(source) {
|
|
399
|
+
return isPlainObject5(source) && ("type" in source || "properties" in source || "$ref" in source || "anyOf" in source);
|
|
400
|
+
}
|
|
401
|
+
function hasOpenApiSchema(source) {
|
|
402
|
+
return isPlainObject5(source) && isJsonSchemaLike(source.openapi);
|
|
403
|
+
}
|
|
404
|
+
function toOpenApiSchema(source) {
|
|
405
|
+
if (!source) return void 0;
|
|
406
|
+
const resolvedSource = isOpenApiSchemaResolver(source) ? source.resolve() : source;
|
|
407
|
+
if (!resolvedSource) return void 0;
|
|
408
|
+
if (isOpenApiSchemaPatch(resolvedSource)) {
|
|
409
|
+
const schema = toOpenApiSchema(resolvedSource.source) ?? { ...fallbackObjectSchema };
|
|
410
|
+
const properties = isPlainObject5(schema.properties) ? { ...schema.properties } : {};
|
|
411
|
+
for (const [key, value] of Object.entries(resolvedSource.properties)) {
|
|
412
|
+
properties[key] = toOpenApiSchema(value) ?? fallbackObjectSchema;
|
|
413
|
+
}
|
|
414
|
+
return {
|
|
415
|
+
...schema,
|
|
416
|
+
type: schema.type ?? "object",
|
|
417
|
+
properties
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
if (hasOpenApiSchema(resolvedSource)) {
|
|
421
|
+
return resolvedSource.openapi;
|
|
422
|
+
}
|
|
423
|
+
if (isJsonSchemaLike(resolvedSource)) {
|
|
424
|
+
return resolvedSource;
|
|
425
|
+
}
|
|
426
|
+
try {
|
|
427
|
+
return z.toJSONSchema(resolvedSource);
|
|
428
|
+
} catch {
|
|
429
|
+
return fallbackObjectSchema;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// src/openapi/build-spec.ts
|
|
434
|
+
var openApiMediaType = "application/json";
|
|
435
|
+
var normalizePath = (path) => {
|
|
436
|
+
if (!path) return "/";
|
|
437
|
+
return path.startsWith("/") ? path : `/${path}`;
|
|
438
|
+
};
|
|
439
|
+
var toOpenApiPath = (path) => normalizePath(path).replace(/:([A-Za-z0-9_]+)/g, "{$1}");
|
|
440
|
+
var schemaToQueryParameters = (schema) => {
|
|
441
|
+
const jsonSchema = toOpenApiSchema(schema);
|
|
442
|
+
if (!jsonSchema || jsonSchema.type !== "object") return [];
|
|
443
|
+
const properties = isPlainObject6(jsonSchema.properties) ? jsonSchema.properties : {};
|
|
444
|
+
const required = new Set(
|
|
445
|
+
isArray3(jsonSchema.required) ? jsonSchema.required.filter((item) => typeof item === "string") : []
|
|
446
|
+
);
|
|
447
|
+
return Object.entries(properties).map(([name, value]) => ({
|
|
448
|
+
name,
|
|
449
|
+
in: "query",
|
|
450
|
+
required: required.has(name),
|
|
451
|
+
schema: value
|
|
452
|
+
}));
|
|
453
|
+
};
|
|
454
|
+
var schemaToPathParameters = (path, pathParams) => {
|
|
455
|
+
const names = [...toOpenApiPath(path).matchAll(/\{([^}]+)\}/g)].map((item) => item[1]);
|
|
456
|
+
return names.map((name) => ({
|
|
457
|
+
name,
|
|
458
|
+
in: "path",
|
|
459
|
+
required: true,
|
|
460
|
+
schema: (pathParams && name in pathParams ? toOpenApiSchema(pathParams[name]) : void 0) ?? { type: "string" }
|
|
461
|
+
}));
|
|
462
|
+
};
|
|
463
|
+
var getDefaultResponses = (route) => {
|
|
464
|
+
if (route.operationId === "root.query") return openApiResponses.batch();
|
|
465
|
+
if (route.method === "delete") return openApiResponses.delete();
|
|
466
|
+
if (route.operationId?.toLowerCase().includes("create")) return openApiResponses.create();
|
|
467
|
+
if (route.operationId?.toLowerCase().includes("list")) return openApiResponses.list();
|
|
468
|
+
if (route.operationId?.toLowerCase().includes("distinct")) return openApiResponses.list();
|
|
469
|
+
return openApiResponses.single();
|
|
470
|
+
};
|
|
471
|
+
var buildOperation = (route) => {
|
|
472
|
+
const queryParameters = schemaToQueryParameters(route.query);
|
|
473
|
+
const pathParameters = schemaToPathParameters(route.path, route.pathParams);
|
|
474
|
+
const bodySchema = toOpenApiSchema(route.body);
|
|
475
|
+
const responses = route.responses ?? getDefaultResponses(route);
|
|
476
|
+
const operation = {
|
|
477
|
+
operationId: route.operationId,
|
|
478
|
+
summary: route.summary,
|
|
479
|
+
description: route.description,
|
|
480
|
+
tags: route.tags,
|
|
481
|
+
deprecated: route.deprecated,
|
|
482
|
+
responses
|
|
483
|
+
};
|
|
484
|
+
const parameters = [...pathParameters, ...queryParameters];
|
|
485
|
+
if (parameters.length) {
|
|
486
|
+
operation.parameters = parameters;
|
|
487
|
+
}
|
|
488
|
+
if (bodySchema) {
|
|
489
|
+
operation.requestBody = {
|
|
490
|
+
required: true,
|
|
491
|
+
content: {
|
|
492
|
+
[openApiMediaType]: {
|
|
493
|
+
schema: bodySchema
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
if (route.acl) {
|
|
499
|
+
operation["x-access-router-acl"] = route.acl;
|
|
500
|
+
}
|
|
501
|
+
return operation;
|
|
502
|
+
};
|
|
503
|
+
function buildOpenApiSpec(routes, options) {
|
|
504
|
+
const paths = {};
|
|
505
|
+
const { servers, ...info } = options;
|
|
506
|
+
for (const route of routes) {
|
|
507
|
+
const path = toOpenApiPath(route.path);
|
|
508
|
+
if (!paths[path]) {
|
|
509
|
+
paths[path] = {};
|
|
510
|
+
}
|
|
511
|
+
paths[path][route.method] = buildOperation(route);
|
|
512
|
+
}
|
|
513
|
+
return {
|
|
514
|
+
openapi: "3.1.0",
|
|
515
|
+
info,
|
|
516
|
+
servers,
|
|
517
|
+
paths
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// src/openapi/registry.ts
|
|
522
|
+
var OpenApiRegistry = class {
|
|
523
|
+
constructor() {
|
|
524
|
+
this.routes = [];
|
|
525
|
+
}
|
|
526
|
+
register(route) {
|
|
527
|
+
const existingIndex = this.routes.findIndex((item) => item.method === route.method && item.path === route.path);
|
|
528
|
+
if (existingIndex === -1) {
|
|
529
|
+
this.routes.push(route);
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
this.routes[existingIndex] = route;
|
|
533
|
+
}
|
|
534
|
+
getRoutes() {
|
|
535
|
+
return [...this.routes];
|
|
536
|
+
}
|
|
537
|
+
getSpec(info) {
|
|
538
|
+
return buildOpenApiSpec(this.routes, info);
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
|
|
298
542
|
// src/logger-default.ts
|
|
299
543
|
import util from "util";
|
|
300
544
|
import { createLogger, format, transports } from "winston";
|
|
@@ -401,9 +645,9 @@ var hasModelPermission = (value, modelPermissionPrefix) => {
|
|
|
401
645
|
if (isString4(value)) {
|
|
402
646
|
return value.trim().split(" ").some((item) => item.startsWith(modelPermissionPrefix));
|
|
403
647
|
}
|
|
404
|
-
if (
|
|
648
|
+
if (isArray4(value)) {
|
|
405
649
|
return value.some((item) => {
|
|
406
|
-
if (isString4(item) ||
|
|
650
|
+
if (isString4(item) || isArray4(item)) {
|
|
407
651
|
return hasModelPermission(item, modelPermissionPrefix);
|
|
408
652
|
}
|
|
409
653
|
return true;
|
|
@@ -417,13 +661,13 @@ var classifyPermissionSchema = (permissionSchema, modelPermissionPrefix) => {
|
|
|
417
661
|
const modelPermissionKeys = {};
|
|
418
662
|
forEach2(schemaKeys, (schemaKey) => {
|
|
419
663
|
const schemaRule = permissionSchema[schemaKey];
|
|
420
|
-
const ruleEntries =
|
|
664
|
+
const ruleEntries = isPlainObject7(schemaRule) ? Object.entries(schemaRule) : FIELD_ACCESS_KEYS.map((accessKey) => [accessKey, schemaRule]);
|
|
421
665
|
for (let x = 0; x < ruleEntries.length; x++) {
|
|
422
666
|
const [accessKey, value] = ruleEntries[x];
|
|
423
|
-
if (!
|
|
667
|
+
if (!isArray4(globalPermissionKeys[accessKey])) {
|
|
424
668
|
globalPermissionKeys[accessKey] = [];
|
|
425
669
|
}
|
|
426
|
-
if (!
|
|
670
|
+
if (!isArray4(modelPermissionKeys[accessKey])) {
|
|
427
671
|
modelPermissionKeys[accessKey] = [];
|
|
428
672
|
}
|
|
429
673
|
if (isBoolean(value)) {
|
|
@@ -467,6 +711,16 @@ var AccessRuntime = class {
|
|
|
467
711
|
this.modelRefs = {};
|
|
468
712
|
this.modelSubs = {};
|
|
469
713
|
this.modelAtts = {};
|
|
714
|
+
this.openApiRegistry = new OpenApiRegistry();
|
|
715
|
+
}
|
|
716
|
+
registerOpenApiRoute(route) {
|
|
717
|
+
this.openApiRegistry.register(route);
|
|
718
|
+
}
|
|
719
|
+
getOpenApiRoutes() {
|
|
720
|
+
return this.openApiRegistry.getRoutes();
|
|
721
|
+
}
|
|
722
|
+
getOpenApiSpec(info) {
|
|
723
|
+
return this.openApiRegistry.getSpec(info);
|
|
470
724
|
}
|
|
471
725
|
setGlobalOptions(options) {
|
|
472
726
|
this.globalOptions.assign(options);
|
|
@@ -738,19 +992,19 @@ import {
|
|
|
738
992
|
forEach as forEach3,
|
|
739
993
|
get as get4,
|
|
740
994
|
intersectionBy,
|
|
741
|
-
isArray as
|
|
742
|
-
isPlainObject as
|
|
995
|
+
isArray as isArray5,
|
|
996
|
+
isPlainObject as isPlainObject8,
|
|
743
997
|
uniq
|
|
744
998
|
} from "@web-ts-toolkit/utils";
|
|
745
999
|
function validateClientFilter(filter2) {
|
|
746
1000
|
const errors = [];
|
|
747
1001
|
const blockedOperators = /* @__PURE__ */ new Set(["$where", "$expr", "$function", "$accumulator"]);
|
|
748
1002
|
const visit = (value, path) => {
|
|
749
|
-
if (
|
|
1003
|
+
if (isArray5(value)) {
|
|
750
1004
|
value.forEach((item, index) => visit(item, `${path}[${index}]`));
|
|
751
1005
|
return;
|
|
752
1006
|
}
|
|
753
|
-
if (!
|
|
1007
|
+
if (!isPlainObject8(value)) return;
|
|
754
1008
|
Object.entries(value).forEach(([key, child]) => {
|
|
755
1009
|
const nextPath = path ? `${path}.${key}` : key;
|
|
756
1010
|
if (blockedOperators.has(key)) {
|
|
@@ -866,7 +1120,7 @@ var Base = class {
|
|
|
866
1120
|
if (!include) return docs;
|
|
867
1121
|
const includes = compact(castArray(include));
|
|
868
1122
|
if (includes.length === 0) return docs;
|
|
869
|
-
const isSingle = !
|
|
1123
|
+
const isSingle = !isArray5(docs);
|
|
870
1124
|
if (isSingle) docs = [docs];
|
|
871
1125
|
for (let x = 0; x < includes.length; x++) {
|
|
872
1126
|
const include2 = includes[x];
|
|
@@ -951,14 +1205,16 @@ var Base = class {
|
|
|
951
1205
|
if (!result.success) return null;
|
|
952
1206
|
let ret = result.data;
|
|
953
1207
|
if (sqOptions.path) {
|
|
954
|
-
ret =
|
|
1208
|
+
ret = isArray5(ret) ? flatten(ret.map((v) => get4(v, sqOptions.path))) : get4(ret, sqOptions.path);
|
|
955
1209
|
}
|
|
956
1210
|
if (sqOptions.compact) {
|
|
957
1211
|
ret = compact(castArray(ret));
|
|
958
1212
|
}
|
|
959
1213
|
return ret;
|
|
960
1214
|
}
|
|
961
|
-
|
|
1215
|
+
handleDate(val, key) {
|
|
1216
|
+
if (val instanceof Date) return val;
|
|
1217
|
+
if (typeof val === "string" || typeof val === "number") return new Date(val);
|
|
962
1218
|
return /* @__PURE__ */ new Date();
|
|
963
1219
|
}
|
|
964
1220
|
};
|
|
@@ -966,7 +1222,7 @@ var Base = class {
|
|
|
966
1222
|
// src/services/service.ts
|
|
967
1223
|
import {
|
|
968
1224
|
castArray as castArray2,
|
|
969
|
-
isArray as
|
|
1225
|
+
isArray as isArray6,
|
|
970
1226
|
isBoolean as isBoolean3,
|
|
971
1227
|
isFunction as isFunction3,
|
|
972
1228
|
omit,
|
|
@@ -977,6 +1233,21 @@ import diff from "deep-diff";
|
|
|
977
1233
|
|
|
978
1234
|
// src/model.ts
|
|
979
1235
|
import mongoose3 from "mongoose";
|
|
1236
|
+
|
|
1237
|
+
// src/logger.ts
|
|
1238
|
+
var passthrough = (level) => (...args) => {
|
|
1239
|
+
const globalLogger = getGlobalOption("logger");
|
|
1240
|
+
const target = globalLogger?.[level] ?? defaultLogger[level];
|
|
1241
|
+
return target.apply(globalLogger ?? defaultLogger, args);
|
|
1242
|
+
};
|
|
1243
|
+
var logger = {
|
|
1244
|
+
debug: passthrough("debug"),
|
|
1245
|
+
info: passthrough("info"),
|
|
1246
|
+
warn: passthrough("warn"),
|
|
1247
|
+
error: passthrough("error")
|
|
1248
|
+
};
|
|
1249
|
+
|
|
1250
|
+
// src/model.ts
|
|
980
1251
|
var Model = class {
|
|
981
1252
|
constructor(modelName) {
|
|
982
1253
|
this.modelName = modelName;
|
|
@@ -1006,12 +1277,15 @@ var Model = class {
|
|
|
1006
1277
|
if (lean) builder.lean();
|
|
1007
1278
|
return builder;
|
|
1008
1279
|
}
|
|
1009
|
-
|
|
1010
|
-
validateSort(sort, logError = console.error) {
|
|
1280
|
+
validateSort(sort, logError = logger.error) {
|
|
1011
1281
|
const validSortOrders = [1, -1, "asc", "ascending", "desc", "descending"];
|
|
1282
|
+
const fieldPathPattern = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*)*$/;
|
|
1283
|
+
const isValidFieldPath = (field) => fieldPathPattern.test(field);
|
|
1012
1284
|
if (sort === null || sort === void 0) return true;
|
|
1013
1285
|
if (typeof sort === "string") {
|
|
1014
|
-
|
|
1286
|
+
const fields = sort.trim().split(/\s+/).filter(Boolean);
|
|
1287
|
+
const isValid = fields.every((field) => isValidFieldPath(field.startsWith("-") ? field.slice(1) : field));
|
|
1288
|
+
if (!isValid) {
|
|
1015
1289
|
logError("Invalid sort string:", sort);
|
|
1016
1290
|
return false;
|
|
1017
1291
|
}
|
|
@@ -1024,8 +1298,8 @@ var Model = class {
|
|
|
1024
1298
|
return false;
|
|
1025
1299
|
}
|
|
1026
1300
|
const [key, order] = pair;
|
|
1027
|
-
if (typeof key !== "string") {
|
|
1028
|
-
logError("Invalid sort array key: must be string", key);
|
|
1301
|
+
if (typeof key !== "string" || !isValidFieldPath(key)) {
|
|
1302
|
+
logError("Invalid sort array key: must be a field path string", key);
|
|
1029
1303
|
return false;
|
|
1030
1304
|
}
|
|
1031
1305
|
if (!validSortOrders.includes(order)) {
|
|
@@ -1037,7 +1311,11 @@ var Model = class {
|
|
|
1037
1311
|
return isValid;
|
|
1038
1312
|
}
|
|
1039
1313
|
if (typeof sort === "object" && !(sort instanceof Map)) {
|
|
1040
|
-
const isValid = Object.
|
|
1314
|
+
const isValid = Object.entries(sort).every(([key, order]) => {
|
|
1315
|
+
if (!isValidFieldPath(key)) {
|
|
1316
|
+
logError("Invalid sort object key: must be a field path string", key);
|
|
1317
|
+
return false;
|
|
1318
|
+
}
|
|
1041
1319
|
if (!validSortOrders.includes(order)) {
|
|
1042
1320
|
logError('Invalid sort object value: must be 1, -1, "asc", or "desc"', order);
|
|
1043
1321
|
return false;
|
|
@@ -1047,7 +1325,11 @@ var Model = class {
|
|
|
1047
1325
|
return isValid;
|
|
1048
1326
|
}
|
|
1049
1327
|
if (sort instanceof Map) {
|
|
1050
|
-
const isValid = Array.from(sort.
|
|
1328
|
+
const isValid = Array.from(sort.entries()).every(([key, order]) => {
|
|
1329
|
+
if (!isValidFieldPath(key)) {
|
|
1330
|
+
logError("Invalid sort Map key: must be a field path string", key);
|
|
1331
|
+
return false;
|
|
1332
|
+
}
|
|
1051
1333
|
if (!validSortOrders.includes(order)) {
|
|
1052
1334
|
logError('Invalid sort Map value: must be 1, -1, "asc", or "desc"', order);
|
|
1053
1335
|
return false;
|
|
@@ -1070,9 +1352,6 @@ var Model = class {
|
|
|
1070
1352
|
if (lean) builder.lean();
|
|
1071
1353
|
return builder;
|
|
1072
1354
|
}
|
|
1073
|
-
findOneAndDelete(filter2) {
|
|
1074
|
-
return this.model.findOneAndDelete(filter2);
|
|
1075
|
-
}
|
|
1076
1355
|
exists(filter2) {
|
|
1077
1356
|
if (!filter2) return null;
|
|
1078
1357
|
return this.findOne(filter2).select("_id").lean();
|
|
@@ -1081,10 +1360,6 @@ var Model = class {
|
|
|
1081
1360
|
countDocuments(filter2 = {}) {
|
|
1082
1361
|
return this.model.countDocuments(filter2);
|
|
1083
1362
|
}
|
|
1084
|
-
// see https://mongoosejs.com/docs/api.html#model_Model.estimatedDocumentCount
|
|
1085
|
-
estimatedDocumentCount() {
|
|
1086
|
-
return this.model.estimatedDocumentCount();
|
|
1087
|
-
}
|
|
1088
1363
|
// see https://mongoosejs.com/docs/api.html#model_Model.distinct
|
|
1089
1364
|
distinct(field, conditions = {}) {
|
|
1090
1365
|
return this.model.distinct(field, conditions);
|
|
@@ -1092,19 +1367,6 @@ var Model = class {
|
|
|
1092
1367
|
};
|
|
1093
1368
|
var model_default = Model;
|
|
1094
1369
|
|
|
1095
|
-
// src/logger.ts
|
|
1096
|
-
var passthrough = (level) => (...args) => {
|
|
1097
|
-
const globalLogger = getGlobalOption("logger");
|
|
1098
|
-
const target = globalLogger?.[level] ?? defaultLogger[level];
|
|
1099
|
-
return target.apply(globalLogger ?? defaultLogger, args);
|
|
1100
|
-
};
|
|
1101
|
-
var logger = {
|
|
1102
|
-
debug: passthrough("debug"),
|
|
1103
|
-
info: passthrough("info"),
|
|
1104
|
-
warn: passthrough("warn"),
|
|
1105
|
-
error: passthrough("error")
|
|
1106
|
-
};
|
|
1107
|
-
|
|
1108
1370
|
// src/services/model-subdocument-service.ts
|
|
1109
1371
|
import { forEach as forEach4, get as get5, pick as pick3 } from "@web-ts-toolkit/utils";
|
|
1110
1372
|
async function listSub(service, id, sub, options) {
|
|
@@ -1328,7 +1590,7 @@ function resolveExistsOptions(service, options = {}) {
|
|
|
1328
1590
|
|
|
1329
1591
|
// src/services/service.ts
|
|
1330
1592
|
var assertModelDocument = (value, modelName, hookName) => {
|
|
1331
|
-
if (
|
|
1593
|
+
if (isDocument2(value)) {
|
|
1332
1594
|
return value;
|
|
1333
1595
|
}
|
|
1334
1596
|
throw new Error(`${hookName} hook for model=${modelName} must return a Mongoose document instance`);
|
|
@@ -1422,7 +1684,7 @@ var Service = class extends Base {
|
|
|
1422
1684
|
genPagination({ skip, limit, page, pageSize }, this.options.listHardLimit)
|
|
1423
1685
|
]);
|
|
1424
1686
|
const finalSelect = normalizeSelect(_select);
|
|
1425
|
-
const filteredPopulate =
|
|
1687
|
+
const filteredPopulate = isArray6(finalSelect) && isArray6(_populate) ? _populate.filter((p) => finalSelect.includes(p.path.split(".")[0])) : _populate;
|
|
1426
1688
|
const { includes, includeLocalFields, includePaths } = this.processInclude(include);
|
|
1427
1689
|
const query = {
|
|
1428
1690
|
filter: _filter,
|
|
@@ -1505,7 +1767,7 @@ var Service = class extends Base {
|
|
|
1505
1767
|
validationError = { success: false, code: "bad_request" /* BadRequest */ };
|
|
1506
1768
|
return;
|
|
1507
1769
|
}
|
|
1508
|
-
} else if (
|
|
1770
|
+
} else if (isArray6(validated)) {
|
|
1509
1771
|
if (validated.length > 0) {
|
|
1510
1772
|
validationError = { success: false, code: "bad_request" /* BadRequest */, errors: validated };
|
|
1511
1773
|
return;
|
|
@@ -1595,7 +1857,7 @@ var Service = class extends Base {
|
|
|
1595
1857
|
const validated = await this.validate(allowedData, "update", context);
|
|
1596
1858
|
if (isBoolean3(validated)) {
|
|
1597
1859
|
if (!validated) return { success: false, code: "bad_request" /* BadRequest */ };
|
|
1598
|
-
} else if (
|
|
1860
|
+
} else if (isArray6(validated)) {
|
|
1599
1861
|
if (validated.length > 0) return { success: false, code: "bad_request" /* BadRequest */, errors: validated };
|
|
1600
1862
|
}
|
|
1601
1863
|
const prepared = await this.prepare(allowedData, "update", context);
|
|
@@ -2199,29 +2461,29 @@ var DataService = class {
|
|
|
2199
2461
|
};
|
|
2200
2462
|
|
|
2201
2463
|
// src/processors.ts
|
|
2202
|
-
import { castArray as castArray3, cloneDeep, forEach as
|
|
2464
|
+
import { castArray as castArray3, cloneDeep, forEach as forEach6, get as get7, isArray as isArray7, map as map2, set as set5 } from "@web-ts-toolkit/utils";
|
|
2203
2465
|
var copyAndDepopulate = (docObject, operations, options = { mutable: true, idField: "_id" }) => {
|
|
2204
|
-
const obj =
|
|
2205
|
-
const idField =
|
|
2206
|
-
|
|
2466
|
+
const obj = get7(options, "mutable", true) ? docObject : cloneDeep(docObject);
|
|
2467
|
+
const idField = get7(options, "idField", "_id");
|
|
2468
|
+
forEach6(castArray3(operations), (op) => {
|
|
2207
2469
|
if (!op.src || !op.dest) return;
|
|
2208
2470
|
let targets = [obj];
|
|
2209
2471
|
const segs = op.src.split(".");
|
|
2210
|
-
|
|
2472
|
+
forEach6(segs, (seg, ind) => {
|
|
2211
2473
|
if (segs.length === ind + 1) {
|
|
2212
|
-
|
|
2474
|
+
forEach6(targets, (target) => {
|
|
2213
2475
|
const targetObject = target;
|
|
2214
|
-
set5(targetObject, op.dest,
|
|
2476
|
+
set5(targetObject, op.dest, get7(targetObject, seg));
|
|
2215
2477
|
set5(
|
|
2216
2478
|
targetObject,
|
|
2217
2479
|
seg,
|
|
2218
|
-
|
|
2480
|
+
isArray7(targetObject[seg]) ? map2(targetObject[seg], idField) : get7(targetObject, `${seg}.${idField}`)
|
|
2219
2481
|
);
|
|
2220
2482
|
});
|
|
2221
2483
|
} else {
|
|
2222
2484
|
targets = targets.reduce((ret, target) => {
|
|
2223
2485
|
const targetObject = target;
|
|
2224
|
-
if (
|
|
2486
|
+
if (isArray7(targetObject[seg])) ret.push(...targetObject[seg]);
|
|
2225
2487
|
else ret.push(targetObject[seg]);
|
|
2226
2488
|
return ret;
|
|
2227
2489
|
}, []);
|
|
@@ -2272,12 +2534,12 @@ var Cache = class {
|
|
|
2272
2534
|
import {
|
|
2273
2535
|
castArray as castArray4,
|
|
2274
2536
|
arrayToRecord,
|
|
2275
|
-
isArray as
|
|
2537
|
+
isArray as isArray8,
|
|
2276
2538
|
isBoolean as isBoolean4,
|
|
2277
2539
|
isEmpty as isEmpty2,
|
|
2278
2540
|
isEqual,
|
|
2279
2541
|
isFunction as isFunction4,
|
|
2280
|
-
isPlainObject as
|
|
2542
|
+
isPlainObject as isPlainObject10,
|
|
2281
2543
|
isString as isString5
|
|
2282
2544
|
} from "@web-ts-toolkit/utils";
|
|
2283
2545
|
|
|
@@ -2317,10 +2579,10 @@ var permission_default = Permission;
|
|
|
2317
2579
|
|
|
2318
2580
|
// src/core-shared.ts
|
|
2319
2581
|
function isAndFilter(filter2) {
|
|
2320
|
-
return !!filter2 &&
|
|
2582
|
+
return !!filter2 && isPlainObject10(filter2) && Object.keys(filter2).length === 1 && isArray8(filter2.$and);
|
|
2321
2583
|
}
|
|
2322
2584
|
function isMergeableClause(filter2) {
|
|
2323
|
-
return !!filter2 &&
|
|
2585
|
+
return !!filter2 && isPlainObject10(filter2) && Object.keys(filter2).every((key) => !key.startsWith("$"));
|
|
2324
2586
|
}
|
|
2325
2587
|
function optimizeAndFilter(clausesInput) {
|
|
2326
2588
|
const clauses = [];
|
|
@@ -2365,7 +2627,7 @@ function optimizeAndFilter(clausesInput) {
|
|
|
2365
2627
|
}
|
|
2366
2628
|
function normalizeFilter(filter2) {
|
|
2367
2629
|
if (filter2 === false) return false;
|
|
2368
|
-
if (!filter2 || !
|
|
2630
|
+
if (!filter2 || !isPlainObject10(filter2) || isEmpty2(filter2)) return null;
|
|
2369
2631
|
if (!isAndFilter(filter2)) {
|
|
2370
2632
|
return filter2;
|
|
2371
2633
|
}
|
|
@@ -2417,8 +2679,8 @@ async function setRequestPermissions(req) {
|
|
|
2417
2679
|
const globalPermissions = getGlobalOption("globalPermissions");
|
|
2418
2680
|
if (!isFunction4(globalPermissions)) return;
|
|
2419
2681
|
const permissions = await globalPermissions.call(req, req);
|
|
2420
|
-
if (
|
|
2421
|
-
else if (
|
|
2682
|
+
if (isPlainObject10(permissions)) req[requestPermissionField] = permissions;
|
|
2683
|
+
else if (isArray8(permissions)) req[requestPermissionField] = arrayToRecord(permissions);
|
|
2422
2684
|
else if (isString5(permissions)) req[requestPermissionField] = { [permissions]: true };
|
|
2423
2685
|
}
|
|
2424
2686
|
async function evaluateRouteGuard(req, permissions, routeGuard) {
|
|
@@ -2430,7 +2692,7 @@ async function evaluateRouteGuard(req, permissions, routeGuard) {
|
|
|
2430
2692
|
if (isString5(routeGuard)) {
|
|
2431
2693
|
return stringHandler(routeGuard);
|
|
2432
2694
|
}
|
|
2433
|
-
if (
|
|
2695
|
+
if (isArray8(routeGuard)) {
|
|
2434
2696
|
return arrayHandler(routeGuard);
|
|
2435
2697
|
}
|
|
2436
2698
|
if (isFunction4(routeGuard)) {
|
|
@@ -2468,7 +2730,7 @@ async function collectSchemaFields({
|
|
|
2468
2730
|
if (value) fields.push(key);
|
|
2469
2731
|
} else if (isString5(value)) {
|
|
2470
2732
|
if (stringHandler(value)) fields.push(key);
|
|
2471
|
-
} else if (
|
|
2733
|
+
} else if (isArray8(value)) {
|
|
2472
2734
|
if (arrayHandler(value)) fields.push(key);
|
|
2473
2735
|
} else if (isFunction4(value)) {
|
|
2474
2736
|
if (await value.call(req, ...functionArgs)) fields.push(key);
|
|
@@ -2757,7 +3019,7 @@ var Core = class {
|
|
|
2757
3019
|
if (isFunction5(validate)) {
|
|
2758
3020
|
const permissions = this.getGlobalPermissions();
|
|
2759
3021
|
return validate.call(this.req, allowedData, permissions, context);
|
|
2760
|
-
} else if (isBoolean5(validate) ||
|
|
3022
|
+
} else if (isBoolean5(validate) || isArray9(validate)) {
|
|
2761
3023
|
return validate;
|
|
2762
3024
|
} else {
|
|
2763
3025
|
return true;
|
|
@@ -2888,7 +3150,7 @@ var Core = class {
|
|
|
2888
3150
|
runTasks(modelName, docObject, task) {
|
|
2889
3151
|
const tasks = compact3(castArray5(task));
|
|
2890
3152
|
if (tasks.length === 0) return docObject;
|
|
2891
|
-
|
|
3153
|
+
forEach7(tasks, (task2) => {
|
|
2892
3154
|
const { type, args, options } = task2;
|
|
2893
3155
|
switch (type) {
|
|
2894
3156
|
case "COPY_AND_DEPOPULATE":
|
|
@@ -2971,19 +3233,19 @@ function guard(condition) {
|
|
|
2971
3233
|
const permissions = req[PERMISSIONS];
|
|
2972
3234
|
let cond = condition;
|
|
2973
3235
|
let phas = (key) => permissions.has(key);
|
|
2974
|
-
if (
|
|
3236
|
+
if (isPlainObject11(condition)) {
|
|
2975
3237
|
const { modelName, id, condition: _cond } = condition;
|
|
2976
3238
|
const svc = req.macl.getPublicService(modelName);
|
|
2977
3239
|
const select = getModelOption(modelName, `alwaysSelectFields.read`, void 0);
|
|
2978
3240
|
let _id = isString7(id) ? id : null;
|
|
2979
|
-
if (
|
|
3241
|
+
if (isPlainObject11(id)) {
|
|
2980
3242
|
const { type = "param", key } = id;
|
|
2981
3243
|
if (type === "param") {
|
|
2982
3244
|
const paramValue = req.params[key];
|
|
2983
|
-
_id =
|
|
3245
|
+
_id = isArray10(paramValue) ? paramValue[0] ?? null : paramValue ?? null;
|
|
2984
3246
|
} else if (type === "query") {
|
|
2985
3247
|
const _qval = req.query[key];
|
|
2986
|
-
if (
|
|
3248
|
+
if (isArray10(_qval)) _id = _qval.length > 0 ? _qval[0] : null;
|
|
2987
3249
|
else _id = _qval;
|
|
2988
3250
|
} else {
|
|
2989
3251
|
_id = null;
|
|
@@ -3003,7 +3265,7 @@ function guard(condition) {
|
|
|
3003
3265
|
const { stringHandler, arrayHandler } = createValidator(phas);
|
|
3004
3266
|
if (isString7(cond)) {
|
|
3005
3267
|
if (stringHandler(cond)) return next();
|
|
3006
|
-
} else if (
|
|
3268
|
+
} else if (isArray10(cond)) {
|
|
3007
3269
|
if (arrayHandler(cond)) return next();
|
|
3008
3270
|
} else if (isFunction6(cond)) {
|
|
3009
3271
|
const result = await cond.call(req, permissions);
|
|
@@ -3014,11 +3276,11 @@ function guard(condition) {
|
|
|
3014
3276
|
}
|
|
3015
3277
|
|
|
3016
3278
|
// src/routers/index.ts
|
|
3017
|
-
import
|
|
3279
|
+
import express2 from "express";
|
|
3018
3280
|
|
|
3019
3281
|
// src/routers/model-router.ts
|
|
3020
3282
|
import JsonRouter5 from "@web-ts-toolkit/express-json-router";
|
|
3021
|
-
import { forEach as
|
|
3283
|
+
import { forEach as forEach8, isPlainObject as isPlainObject12, isString as isString9, isUndefined as isUndefined2, normalizeUrlPath as normalizeUrlPath2, padEnd } from "@web-ts-toolkit/utils";
|
|
3022
3284
|
|
|
3023
3285
|
// src/routers/router-mutation.ts
|
|
3024
3286
|
var MODEL_BUILD_TIME_OPTION_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -3110,88 +3372,88 @@ function formatModelUpsertResponse(result) {
|
|
|
3110
3372
|
import JsonRouter4 from "@web-ts-toolkit/express-json-router";
|
|
3111
3373
|
|
|
3112
3374
|
// src/validation/common.ts
|
|
3113
|
-
import { z } from "zod";
|
|
3114
|
-
var stringOrStringArray =
|
|
3115
|
-
var queryBooleanString =
|
|
3116
|
-
var positiveIntegerString =
|
|
3117
|
-
var nonNegativeIntegerSchema =
|
|
3118
|
-
var unknownRecord =
|
|
3119
|
-
var projectionObjectSchema =
|
|
3120
|
-
var projectionSchema =
|
|
3121
|
-
var sortOrderSchema =
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3375
|
+
import { z as z2 } from "zod";
|
|
3376
|
+
var stringOrStringArray = z2.union([z2.string(), z2.array(z2.string())]);
|
|
3377
|
+
var queryBooleanString = z2.enum(["true", "false"]);
|
|
3378
|
+
var positiveIntegerString = z2.string().regex(/^\d+$/, "Expected a non-negative integer");
|
|
3379
|
+
var nonNegativeIntegerSchema = z2.number().int().min(0);
|
|
3380
|
+
var unknownRecord = z2.record(z2.string(), z2.unknown());
|
|
3381
|
+
var projectionObjectSchema = z2.record(z2.string(), z2.union([z2.literal(1), z2.literal(-1)]));
|
|
3382
|
+
var projectionSchema = z2.union([z2.string(), z2.array(z2.string()), projectionObjectSchema]);
|
|
3383
|
+
var sortOrderSchema = z2.union([
|
|
3384
|
+
z2.literal(-1),
|
|
3385
|
+
z2.literal(1),
|
|
3386
|
+
z2.literal("asc"),
|
|
3387
|
+
z2.literal("ascending"),
|
|
3388
|
+
z2.literal("desc"),
|
|
3389
|
+
z2.literal("descending")
|
|
3128
3390
|
]);
|
|
3129
|
-
var sortSchema =
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3391
|
+
var sortSchema = z2.union([
|
|
3392
|
+
z2.string(),
|
|
3393
|
+
z2.record(z2.string(), sortOrderSchema),
|
|
3394
|
+
z2.array(z2.tuple([z2.string(), sortOrderSchema])),
|
|
3395
|
+
z2.null()
|
|
3134
3396
|
]);
|
|
3135
|
-
var populateSchema =
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
path:
|
|
3397
|
+
var populateSchema = z2.union([
|
|
3398
|
+
z2.string(),
|
|
3399
|
+
z2.array(
|
|
3400
|
+
z2.union([
|
|
3401
|
+
z2.string(),
|
|
3402
|
+
z2.object({
|
|
3403
|
+
path: z2.string().min(1),
|
|
3142
3404
|
select: projectionSchema.optional(),
|
|
3143
|
-
match:
|
|
3144
|
-
access:
|
|
3405
|
+
match: z2.unknown().optional(),
|
|
3406
|
+
access: z2.enum(["list", "read"]).optional()
|
|
3145
3407
|
}).passthrough()
|
|
3146
3408
|
])
|
|
3147
3409
|
),
|
|
3148
|
-
|
|
3149
|
-
path:
|
|
3410
|
+
z2.object({
|
|
3411
|
+
path: z2.string().min(1),
|
|
3150
3412
|
select: projectionSchema.optional(),
|
|
3151
|
-
match:
|
|
3152
|
-
access:
|
|
3413
|
+
match: z2.unknown().optional(),
|
|
3414
|
+
access: z2.enum(["list", "read"]).optional()
|
|
3153
3415
|
}).passthrough()
|
|
3154
3416
|
]);
|
|
3155
|
-
var subPopulateSchema =
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
path:
|
|
3417
|
+
var subPopulateSchema = z2.union([
|
|
3418
|
+
z2.string(),
|
|
3419
|
+
z2.array(
|
|
3420
|
+
z2.union([
|
|
3421
|
+
z2.string(),
|
|
3422
|
+
z2.object({
|
|
3423
|
+
path: z2.string().min(1),
|
|
3162
3424
|
select: projectionSchema.optional()
|
|
3163
3425
|
}).passthrough()
|
|
3164
3426
|
])
|
|
3165
3427
|
),
|
|
3166
|
-
|
|
3167
|
-
path:
|
|
3428
|
+
z2.object({
|
|
3429
|
+
path: z2.string().min(1),
|
|
3168
3430
|
select: projectionSchema.optional()
|
|
3169
3431
|
}).passthrough()
|
|
3170
3432
|
]);
|
|
3171
|
-
var includeItemSchema =
|
|
3172
|
-
model:
|
|
3173
|
-
op:
|
|
3174
|
-
path:
|
|
3175
|
-
filter:
|
|
3176
|
-
localField:
|
|
3177
|
-
foreignField:
|
|
3178
|
-
args:
|
|
3179
|
-
options:
|
|
3433
|
+
var includeItemSchema = z2.object({
|
|
3434
|
+
model: z2.string().min(1),
|
|
3435
|
+
op: z2.enum(["list", "read", "count"]),
|
|
3436
|
+
path: z2.string().min(1),
|
|
3437
|
+
filter: z2.record(z2.string(), z2.unknown()).optional(),
|
|
3438
|
+
localField: z2.string().min(1),
|
|
3439
|
+
foreignField: z2.string().min(1),
|
|
3440
|
+
args: z2.unknown().optional(),
|
|
3441
|
+
options: z2.unknown().optional()
|
|
3180
3442
|
}).passthrough();
|
|
3181
|
-
var includeSchema =
|
|
3182
|
-
var fieldsSchema =
|
|
3183
|
-
var taskSchema =
|
|
3184
|
-
type:
|
|
3185
|
-
args:
|
|
3443
|
+
var includeSchema = z2.union([includeItemSchema, z2.array(includeItemSchema)]);
|
|
3444
|
+
var fieldsSchema = z2.array(z2.string().min(1));
|
|
3445
|
+
var taskSchema = z2.object({
|
|
3446
|
+
type: z2.string().min(1),
|
|
3447
|
+
args: z2.unknown(),
|
|
3186
3448
|
options: unknownRecord.optional()
|
|
3187
3449
|
});
|
|
3188
|
-
var tasksSchema =
|
|
3189
|
-
var objectOrArraySchema =
|
|
3450
|
+
var tasksSchema = z2.union([taskSchema, z2.array(taskSchema)]);
|
|
3451
|
+
var objectOrArraySchema = z2.union([z2.record(z2.string(), z2.unknown()), z2.array(z2.unknown())]);
|
|
3190
3452
|
function rejectKeys(body, ctx, keys2) {
|
|
3191
3453
|
for (const key of keys2) {
|
|
3192
3454
|
if (key in body) {
|
|
3193
3455
|
ctx.addIssue({
|
|
3194
|
-
code:
|
|
3456
|
+
code: z2.ZodIssueCode.custom,
|
|
3195
3457
|
message: `Unsupported field: ${key}`,
|
|
3196
3458
|
path: [key]
|
|
3197
3459
|
});
|
|
@@ -3204,7 +3466,7 @@ var clientErrors = JsonRouter4.clientErrors;
|
|
|
3204
3466
|
function parsePathParam(value, parameter) {
|
|
3205
3467
|
const result = stringOrStringArray.safeParse(value);
|
|
3206
3468
|
if (!result.success) {
|
|
3207
|
-
throwValidationError(result.error.issues, parameter, "parameter");
|
|
3469
|
+
throwValidationError(normalizeIssues(result.error.issues), parameter, "parameter");
|
|
3208
3470
|
}
|
|
3209
3471
|
const param = Array.isArray(result.data) ? result.data[0] : result.data;
|
|
3210
3472
|
if (!param) {
|
|
@@ -3217,49 +3479,336 @@ function parsePathParam(value, parameter) {
|
|
|
3217
3479
|
function parseQuery(schema, value) {
|
|
3218
3480
|
const result = schema.safeParse(value);
|
|
3219
3481
|
if (!result.success) {
|
|
3220
|
-
throwValidationError(result.error.issues, void 0, "parameter");
|
|
3482
|
+
throwValidationError(normalizeIssues(result.error.issues), void 0, "parameter");
|
|
3221
3483
|
}
|
|
3222
3484
|
return result.data;
|
|
3223
3485
|
}
|
|
3224
3486
|
function parseBody(schema, value) {
|
|
3225
3487
|
const result = schema.safeParse(value ?? {});
|
|
3226
3488
|
if (!result.success) {
|
|
3227
|
-
throwValidationError(result.error.issues, void 0, "pointer");
|
|
3489
|
+
throwValidationError(normalizeIssues(result.error.issues), void 0, "pointer");
|
|
3228
3490
|
}
|
|
3229
3491
|
return result.data;
|
|
3230
3492
|
}
|
|
3231
3493
|
function parseBodyWithSchema(schema, value, userSchema) {
|
|
3232
3494
|
const body = parseBody(schema, value);
|
|
3233
|
-
return
|
|
3495
|
+
return isRequestSchema(userSchema) ? parseUserSchema(userSchema, body) : Promise.resolve(body);
|
|
3234
3496
|
}
|
|
3235
|
-
function parseNestedBodyWithSchema(schema, value, nestedKey, userSchema) {
|
|
3497
|
+
async function parseNestedBodyWithSchema(schema, value, nestedKey, userSchema) {
|
|
3236
3498
|
const body = parseBody(schema, value);
|
|
3237
|
-
if (!
|
|
3499
|
+
if (!isRequestSchema(userSchema)) return body;
|
|
3238
3500
|
return {
|
|
3239
3501
|
...body,
|
|
3240
|
-
[nestedKey]: parseUserSchema(userSchema, body?.[nestedKey], [nestedKey])
|
|
3502
|
+
[nestedKey]: await parseUserSchema(userSchema, body?.[nestedKey], [nestedKey])
|
|
3241
3503
|
};
|
|
3242
3504
|
}
|
|
3243
3505
|
function throwValidationError(issues, key, location = "pointer") {
|
|
3244
3506
|
const errors = issues.map((issue) => formatIssue(issue, key, location));
|
|
3245
3507
|
throw new clientErrors.BadRequestError("Bad Request", { errors });
|
|
3246
3508
|
}
|
|
3247
|
-
function parseUserSchema(schema, value, prefix = []) {
|
|
3248
|
-
const
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3509
|
+
async function parseUserSchema(schema, value, prefix = []) {
|
|
3510
|
+
const validator = toRequestSchemaValidator(schema);
|
|
3511
|
+
const result = await validator(value);
|
|
3512
|
+
if (!isRequestSchemaFailure(result)) {
|
|
3513
|
+
return result.data;
|
|
3514
|
+
}
|
|
3515
|
+
const issues = result.issues.map((issue) => ({
|
|
3516
|
+
...issue,
|
|
3517
|
+
path: prefix.concat((issue.path ?? []).map(String))
|
|
3518
|
+
}));
|
|
3519
|
+
throwValidationError(issues, void 0, "pointer");
|
|
3257
3520
|
}
|
|
3258
3521
|
function isZodSchema(schema) {
|
|
3259
3522
|
return typeof schema === "object" && schema !== null && "safeParse" in schema && typeof schema.safeParse === "function";
|
|
3260
3523
|
}
|
|
3524
|
+
function isRequestSchema(schema) {
|
|
3525
|
+
return isZodSchema(schema) || isStandardSchema(schema) || isRequestSchemaValidator(schema) || isRequestSchemaAdapter(schema);
|
|
3526
|
+
}
|
|
3527
|
+
function isRequestSchemaValidator(schema) {
|
|
3528
|
+
return typeof schema === "function";
|
|
3529
|
+
}
|
|
3530
|
+
function isRequestSchemaAdapter(schema) {
|
|
3531
|
+
return typeof schema === "object" && schema !== null && "validate" in schema && typeof schema.validate === "function";
|
|
3532
|
+
}
|
|
3533
|
+
function isStandardSchema(schema) {
|
|
3534
|
+
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";
|
|
3535
|
+
}
|
|
3536
|
+
function isRequestSchemaFailure(result) {
|
|
3537
|
+
return result.success === false;
|
|
3538
|
+
}
|
|
3539
|
+
function toRequestSchemaValidator(schema) {
|
|
3540
|
+
if (isZodSchema(schema)) return fromZod(schema);
|
|
3541
|
+
if (isStandardSchema(schema)) return fromStandardSchema(schema);
|
|
3542
|
+
if (isRequestSchemaValidator(schema)) return schema;
|
|
3543
|
+
return schema.validate;
|
|
3544
|
+
}
|
|
3545
|
+
function defineRequestSchema(validator, options = {}) {
|
|
3546
|
+
return {
|
|
3547
|
+
validate: validator,
|
|
3548
|
+
openapi: options.openapi
|
|
3549
|
+
};
|
|
3550
|
+
}
|
|
3551
|
+
function fromZod(schema) {
|
|
3552
|
+
return (value) => {
|
|
3553
|
+
const result = schema.safeParse(value);
|
|
3554
|
+
if (result.success) {
|
|
3555
|
+
return {
|
|
3556
|
+
success: true,
|
|
3557
|
+
data: result.data
|
|
3558
|
+
};
|
|
3559
|
+
}
|
|
3560
|
+
return {
|
|
3561
|
+
success: false,
|
|
3562
|
+
issues: normalizeIssues(result.error.issues)
|
|
3563
|
+
};
|
|
3564
|
+
};
|
|
3565
|
+
}
|
|
3566
|
+
function fromStandardSchema(schema) {
|
|
3567
|
+
return async (value) => {
|
|
3568
|
+
const result = await schema["~standard"].validate(value);
|
|
3569
|
+
if (!isStandardSchemaFailure(result)) {
|
|
3570
|
+
return {
|
|
3571
|
+
success: true,
|
|
3572
|
+
data: result.value
|
|
3573
|
+
};
|
|
3574
|
+
}
|
|
3575
|
+
return {
|
|
3576
|
+
success: false,
|
|
3577
|
+
issues: normalizeIssues(result.issues)
|
|
3578
|
+
};
|
|
3579
|
+
};
|
|
3580
|
+
}
|
|
3581
|
+
function fromYup(schema) {
|
|
3582
|
+
return async (value) => {
|
|
3583
|
+
try {
|
|
3584
|
+
const data = await schema.validate(value, { abortEarly: false });
|
|
3585
|
+
return {
|
|
3586
|
+
success: true,
|
|
3587
|
+
data
|
|
3588
|
+
};
|
|
3589
|
+
} catch (error) {
|
|
3590
|
+
return {
|
|
3591
|
+
success: false,
|
|
3592
|
+
issues: normalizeYupIssues(error)
|
|
3593
|
+
};
|
|
3594
|
+
}
|
|
3595
|
+
};
|
|
3596
|
+
}
|
|
3597
|
+
function fromJoi(schema) {
|
|
3598
|
+
return async (value) => {
|
|
3599
|
+
const result = await schema.validate(value, { abortEarly: false });
|
|
3600
|
+
if (!result.error?.details?.length) {
|
|
3601
|
+
return {
|
|
3602
|
+
success: true,
|
|
3603
|
+
data: result.value
|
|
3604
|
+
};
|
|
3605
|
+
}
|
|
3606
|
+
return {
|
|
3607
|
+
success: false,
|
|
3608
|
+
issues: normalizeJoiIssues(result.error.details)
|
|
3609
|
+
};
|
|
3610
|
+
};
|
|
3611
|
+
}
|
|
3612
|
+
function fromAjv(validator) {
|
|
3613
|
+
return async (value) => {
|
|
3614
|
+
const valid = await validator(value);
|
|
3615
|
+
if (valid) {
|
|
3616
|
+
return {
|
|
3617
|
+
success: true,
|
|
3618
|
+
data: value
|
|
3619
|
+
};
|
|
3620
|
+
}
|
|
3621
|
+
return {
|
|
3622
|
+
success: false,
|
|
3623
|
+
issues: normalizeAjvIssues(validator.errors ?? [])
|
|
3624
|
+
};
|
|
3625
|
+
};
|
|
3626
|
+
}
|
|
3627
|
+
function fromValibot(schema, safeParse) {
|
|
3628
|
+
return async (value) => {
|
|
3629
|
+
const result = await safeParse(schema, value, { abortEarly: false });
|
|
3630
|
+
if (result.success) {
|
|
3631
|
+
return {
|
|
3632
|
+
success: true,
|
|
3633
|
+
data: result.output
|
|
3634
|
+
};
|
|
3635
|
+
}
|
|
3636
|
+
return {
|
|
3637
|
+
success: false,
|
|
3638
|
+
issues: normalizeValibotIssues(result.issues)
|
|
3639
|
+
};
|
|
3640
|
+
};
|
|
3641
|
+
}
|
|
3642
|
+
function fromArkType(type) {
|
|
3643
|
+
return async (value) => {
|
|
3644
|
+
const result = await type(value);
|
|
3645
|
+
if (!isArkTypeErrors(result)) {
|
|
3646
|
+
return {
|
|
3647
|
+
success: true,
|
|
3648
|
+
data: result
|
|
3649
|
+
};
|
|
3650
|
+
}
|
|
3651
|
+
return {
|
|
3652
|
+
success: false,
|
|
3653
|
+
issues: normalizeArkTypeIssues(result)
|
|
3654
|
+
};
|
|
3655
|
+
};
|
|
3656
|
+
}
|
|
3657
|
+
function fromIoTs(decoder) {
|
|
3658
|
+
return async (value) => {
|
|
3659
|
+
const result = decoder.decode(value);
|
|
3660
|
+
if (result._tag === "Right") {
|
|
3661
|
+
return {
|
|
3662
|
+
success: true,
|
|
3663
|
+
data: result.right
|
|
3664
|
+
};
|
|
3665
|
+
}
|
|
3666
|
+
return {
|
|
3667
|
+
success: false,
|
|
3668
|
+
issues: normalizeIoTsIssues(result.left)
|
|
3669
|
+
};
|
|
3670
|
+
};
|
|
3671
|
+
}
|
|
3672
|
+
function fromSuperstruct(struct, validate) {
|
|
3673
|
+
return async (value) => {
|
|
3674
|
+
const [failure, output] = await validate(value, struct);
|
|
3675
|
+
if (!failure) {
|
|
3676
|
+
return {
|
|
3677
|
+
success: true,
|
|
3678
|
+
data: output
|
|
3679
|
+
};
|
|
3680
|
+
}
|
|
3681
|
+
return {
|
|
3682
|
+
success: false,
|
|
3683
|
+
issues: normalizeSuperstructFailure(failure)
|
|
3684
|
+
};
|
|
3685
|
+
};
|
|
3686
|
+
}
|
|
3687
|
+
function fromVine(validator) {
|
|
3688
|
+
return async (value) => {
|
|
3689
|
+
try {
|
|
3690
|
+
const output = await validator.validate(value);
|
|
3691
|
+
return {
|
|
3692
|
+
success: true,
|
|
3693
|
+
data: output
|
|
3694
|
+
};
|
|
3695
|
+
} catch (error) {
|
|
3696
|
+
return {
|
|
3697
|
+
success: false,
|
|
3698
|
+
issues: normalizeVineError(error)
|
|
3699
|
+
};
|
|
3700
|
+
}
|
|
3701
|
+
};
|
|
3702
|
+
}
|
|
3703
|
+
function isStandardSchemaFailure(result) {
|
|
3704
|
+
return Array.isArray(result.issues);
|
|
3705
|
+
}
|
|
3706
|
+
function normalizeIssues(issues) {
|
|
3707
|
+
return issues.map((issue) => ({
|
|
3708
|
+
message: issue.message,
|
|
3709
|
+
path: issue.path?.flatMap((segment) => normalizePathSegment(segment))
|
|
3710
|
+
}));
|
|
3711
|
+
}
|
|
3712
|
+
function normalizePathSegment(segment) {
|
|
3713
|
+
const key = isStandardSchemaPathSegment(segment) ? segment.key : segment;
|
|
3714
|
+
return typeof key === "string" || typeof key === "number" ? [key] : [];
|
|
3715
|
+
}
|
|
3716
|
+
function isStandardSchemaPathSegment(segment) {
|
|
3717
|
+
return typeof segment === "object" && segment !== null && "key" in segment;
|
|
3718
|
+
}
|
|
3719
|
+
function normalizeYupIssues(error) {
|
|
3720
|
+
if (!isYupValidationError(error)) {
|
|
3721
|
+
return [{ message: "Validation failed" }];
|
|
3722
|
+
}
|
|
3723
|
+
const issues = error.inner?.length ? error.inner : [error];
|
|
3724
|
+
return issues.map((issue) => ({
|
|
3725
|
+
message: issue.message,
|
|
3726
|
+
path: parsePathString(issue.path)
|
|
3727
|
+
}));
|
|
3728
|
+
}
|
|
3729
|
+
function normalizeJoiIssues(issues) {
|
|
3730
|
+
return issues.map((issue) => ({
|
|
3731
|
+
message: issue.message,
|
|
3732
|
+
path: issue.path ? [...issue.path] : void 0
|
|
3733
|
+
}));
|
|
3734
|
+
}
|
|
3735
|
+
function normalizeAjvIssues(issues) {
|
|
3736
|
+
return issues.map((issue) => ({
|
|
3737
|
+
message: issue.message ?? "Validation failed",
|
|
3738
|
+
path: parseAjvPath(issue)
|
|
3739
|
+
}));
|
|
3740
|
+
}
|
|
3741
|
+
function normalizeValibotIssues(issues) {
|
|
3742
|
+
return issues.map((issue) => ({
|
|
3743
|
+
message: issue.message,
|
|
3744
|
+
path: issue.path?.flatMap(
|
|
3745
|
+
(item) => typeof item.key === "string" || typeof item.key === "number" ? [item.key] : []
|
|
3746
|
+
)
|
|
3747
|
+
}));
|
|
3748
|
+
}
|
|
3749
|
+
function normalizeArkTypeIssues(issues) {
|
|
3750
|
+
const normalized = issues.map((issue) => ({
|
|
3751
|
+
message: issue.message ?? issue.problem ?? issues.summary ?? "Validation failed",
|
|
3752
|
+
path: issue.path ? [...issue.path] : void 0
|
|
3753
|
+
}));
|
|
3754
|
+
return normalized.length ? normalized : [{ message: issues.summary ?? "Validation failed" }];
|
|
3755
|
+
}
|
|
3756
|
+
function normalizeIoTsIssues(issues) {
|
|
3757
|
+
return issues.map((issue) => ({
|
|
3758
|
+
message: issue.message ?? "Validation failed",
|
|
3759
|
+
path: issue.context.map((entry) => entry.key).filter(Boolean)
|
|
3760
|
+
}));
|
|
3761
|
+
}
|
|
3762
|
+
function normalizeSuperstructFailure(failure) {
|
|
3763
|
+
const failures = failure.failures?.() ?? [failure];
|
|
3764
|
+
return failures.map((entry) => ({
|
|
3765
|
+
message: entry.message ?? "Validation failed",
|
|
3766
|
+
path: normalizeSuperstructPath(entry)
|
|
3767
|
+
}));
|
|
3768
|
+
}
|
|
3769
|
+
function normalizeSuperstructPath(failure) {
|
|
3770
|
+
if (failure.path?.length) return [...failure.path];
|
|
3771
|
+
if (typeof failure.key === "string" || typeof failure.key === "number") return [failure.key];
|
|
3772
|
+
return void 0;
|
|
3773
|
+
}
|
|
3774
|
+
function normalizeVineError(error) {
|
|
3775
|
+
if (!isVineValidationError(error)) {
|
|
3776
|
+
return [{ message: "Validation failed" }];
|
|
3777
|
+
}
|
|
3778
|
+
return error.messages.map((message) => ({
|
|
3779
|
+
message: message.message,
|
|
3780
|
+
path: normalizeVineField(message)
|
|
3781
|
+
}));
|
|
3782
|
+
}
|
|
3783
|
+
function normalizeVineField(message) {
|
|
3784
|
+
const path = message.field.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
|
|
3785
|
+
if (typeof message.index === "number" && path.length === 0) {
|
|
3786
|
+
return [message.index];
|
|
3787
|
+
}
|
|
3788
|
+
return path.length ? path : void 0;
|
|
3789
|
+
}
|
|
3790
|
+
function parseAjvPath(issue) {
|
|
3791
|
+
const path = issue.instancePath?.split("/").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
|
|
3792
|
+
if (issue.params?.missingProperty) {
|
|
3793
|
+
return (path ?? []).concat(issue.params.missingProperty);
|
|
3794
|
+
}
|
|
3795
|
+
return path;
|
|
3796
|
+
}
|
|
3797
|
+
function parsePathString(path) {
|
|
3798
|
+
if (!path) return void 0;
|
|
3799
|
+
return path.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
|
|
3800
|
+
}
|
|
3801
|
+
function isYupValidationError(error) {
|
|
3802
|
+
return typeof error === "object" && error !== null && "message" in error;
|
|
3803
|
+
}
|
|
3804
|
+
function isArkTypeErrors(value) {
|
|
3805
|
+
return Array.isArray(value);
|
|
3806
|
+
}
|
|
3807
|
+
function isVineValidationError(error) {
|
|
3808
|
+
return typeof error === "object" && error !== null && "messages" in error && Array.isArray(error.messages);
|
|
3809
|
+
}
|
|
3261
3810
|
function formatIssue(issue, key, location = "pointer") {
|
|
3262
|
-
const path = issue.path.map(String);
|
|
3811
|
+
const path = (issue.path ?? []).map(String);
|
|
3263
3812
|
const joinedPath = path.join(".");
|
|
3264
3813
|
if (location === "parameter") {
|
|
3265
3814
|
return {
|
|
@@ -3277,8 +3826,8 @@ function buildPointer(path) {
|
|
|
3277
3826
|
}
|
|
3278
3827
|
|
|
3279
3828
|
// src/validation/model-router.ts
|
|
3280
|
-
import { z as
|
|
3281
|
-
var listQuerySchema =
|
|
3829
|
+
import { z as z3 } from "zod";
|
|
3830
|
+
var listQuerySchema = z3.object({
|
|
3282
3831
|
skip: positiveIntegerString.optional(),
|
|
3283
3832
|
limit: positiveIntegerString.optional(),
|
|
3284
3833
|
page: positiveIntegerString.optional(),
|
|
@@ -3288,122 +3837,122 @@ var listQuerySchema = z2.object({
|
|
|
3288
3837
|
include_count: queryBooleanString.optional(),
|
|
3289
3838
|
include_extra_headers: queryBooleanString.optional()
|
|
3290
3839
|
}).passthrough();
|
|
3291
|
-
var createQuerySchema =
|
|
3840
|
+
var createQuerySchema = z3.object({
|
|
3292
3841
|
include_permissions: queryBooleanString.optional()
|
|
3293
3842
|
}).passthrough();
|
|
3294
|
-
var readQuerySchema =
|
|
3843
|
+
var readQuerySchema = z3.object({
|
|
3295
3844
|
include_permissions: queryBooleanString.optional(),
|
|
3296
3845
|
try_list: queryBooleanString.optional()
|
|
3297
3846
|
}).passthrough();
|
|
3298
|
-
var updateQuerySchema =
|
|
3847
|
+
var updateQuerySchema = z3.object({
|
|
3299
3848
|
returning_all: queryBooleanString.optional(),
|
|
3300
3849
|
include_permissions: queryBooleanString.optional()
|
|
3301
3850
|
}).passthrough();
|
|
3302
|
-
var upsertQuerySchema =
|
|
3851
|
+
var upsertQuerySchema = z3.object({
|
|
3303
3852
|
returning_all: queryBooleanString.optional(),
|
|
3304
3853
|
include_permissions: queryBooleanString.optional()
|
|
3305
3854
|
}).passthrough();
|
|
3306
|
-
var listBodySchema =
|
|
3855
|
+
var listBodySchema = z3.object({
|
|
3307
3856
|
filter: objectOrArraySchema.optional(),
|
|
3308
3857
|
select: projectionSchema.optional(),
|
|
3309
3858
|
sort: sortSchema.optional(),
|
|
3310
3859
|
populate: populateSchema.optional(),
|
|
3311
3860
|
include: includeSchema.optional(),
|
|
3312
3861
|
tasks: tasksSchema.optional(),
|
|
3313
|
-
skip:
|
|
3314
|
-
limit:
|
|
3315
|
-
page:
|
|
3316
|
-
pageSize:
|
|
3317
|
-
options:
|
|
3318
|
-
skim:
|
|
3319
|
-
includePermissions:
|
|
3320
|
-
includeCount:
|
|
3321
|
-
includeExtraHeaders:
|
|
3322
|
-
populateAccess:
|
|
3862
|
+
skip: z3.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
3863
|
+
limit: z3.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
3864
|
+
page: z3.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
3865
|
+
pageSize: z3.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
3866
|
+
options: z3.object({
|
|
3867
|
+
skim: z3.boolean().optional(),
|
|
3868
|
+
includePermissions: z3.boolean().optional(),
|
|
3869
|
+
includeCount: z3.boolean().optional(),
|
|
3870
|
+
includeExtraHeaders: z3.boolean().optional(),
|
|
3871
|
+
populateAccess: z3.unknown().optional()
|
|
3323
3872
|
}).passthrough().optional()
|
|
3324
3873
|
}).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query"]));
|
|
3325
|
-
var countBodySchema =
|
|
3874
|
+
var countBodySchema = z3.object({
|
|
3326
3875
|
filter: objectOrArraySchema.optional(),
|
|
3327
|
-
options:
|
|
3328
|
-
access:
|
|
3876
|
+
options: z3.object({
|
|
3877
|
+
access: z3.unknown().optional()
|
|
3329
3878
|
}).passthrough().optional()
|
|
3330
3879
|
}).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query", "access"]));
|
|
3331
|
-
var readFilterBodySchema =
|
|
3880
|
+
var readFilterBodySchema = z3.object({
|
|
3332
3881
|
filter: objectOrArraySchema.optional(),
|
|
3333
3882
|
select: projectionSchema.optional(),
|
|
3334
3883
|
sort: sortSchema.optional(),
|
|
3335
3884
|
populate: populateSchema.optional(),
|
|
3336
3885
|
include: includeSchema.optional(),
|
|
3337
3886
|
tasks: tasksSchema.optional(),
|
|
3338
|
-
options:
|
|
3339
|
-
skim:
|
|
3340
|
-
includePermissions:
|
|
3341
|
-
tryList:
|
|
3342
|
-
populateAccess:
|
|
3887
|
+
options: z3.object({
|
|
3888
|
+
skim: z3.boolean().optional(),
|
|
3889
|
+
includePermissions: z3.boolean().optional(),
|
|
3890
|
+
tryList: z3.boolean().optional(),
|
|
3891
|
+
populateAccess: z3.unknown().optional()
|
|
3343
3892
|
}).passthrough().optional()
|
|
3344
3893
|
}).passthrough();
|
|
3345
|
-
var readByIdBodySchema =
|
|
3894
|
+
var readByIdBodySchema = z3.object({
|
|
3346
3895
|
select: projectionSchema.optional(),
|
|
3347
3896
|
populate: populateSchema.optional(),
|
|
3348
3897
|
include: includeSchema.optional(),
|
|
3349
3898
|
tasks: tasksSchema.optional(),
|
|
3350
|
-
options:
|
|
3351
|
-
skim:
|
|
3352
|
-
includePermissions:
|
|
3353
|
-
tryList:
|
|
3354
|
-
populateAccess:
|
|
3899
|
+
options: z3.object({
|
|
3900
|
+
skim: z3.boolean().optional(),
|
|
3901
|
+
includePermissions: z3.boolean().optional(),
|
|
3902
|
+
tryList: z3.boolean().optional(),
|
|
3903
|
+
populateAccess: z3.unknown().optional()
|
|
3355
3904
|
}).passthrough().optional()
|
|
3356
3905
|
}).passthrough();
|
|
3357
|
-
var advancedCreateBodySchema =
|
|
3358
|
-
data:
|
|
3906
|
+
var advancedCreateBodySchema = z3.object({
|
|
3907
|
+
data: z3.unknown(),
|
|
3359
3908
|
select: projectionSchema.optional(),
|
|
3360
3909
|
populate: populateSchema.optional(),
|
|
3361
3910
|
tasks: tasksSchema.optional(),
|
|
3362
|
-
options:
|
|
3363
|
-
includePermissions:
|
|
3364
|
-
populateAccess:
|
|
3911
|
+
options: z3.object({
|
|
3912
|
+
includePermissions: z3.boolean().optional(),
|
|
3913
|
+
populateAccess: z3.unknown().optional()
|
|
3365
3914
|
}).passthrough().optional()
|
|
3366
3915
|
}).passthrough();
|
|
3367
|
-
var createBodySchema =
|
|
3368
|
-
|
|
3369
|
-
|
|
3916
|
+
var createBodySchema = z3.union([
|
|
3917
|
+
z3.record(z3.string(), z3.unknown()),
|
|
3918
|
+
z3.array(z3.record(z3.string(), z3.unknown()))
|
|
3370
3919
|
]);
|
|
3371
|
-
var updateBodySchema =
|
|
3372
|
-
var advancedUpdateBodySchema =
|
|
3373
|
-
data:
|
|
3920
|
+
var updateBodySchema = z3.record(z3.string(), z3.unknown());
|
|
3921
|
+
var advancedUpdateBodySchema = z3.object({
|
|
3922
|
+
data: z3.unknown(),
|
|
3374
3923
|
select: projectionSchema.optional(),
|
|
3375
3924
|
populate: populateSchema.optional(),
|
|
3376
3925
|
tasks: tasksSchema.optional(),
|
|
3377
|
-
options:
|
|
3378
|
-
returningAll:
|
|
3379
|
-
includePermissions:
|
|
3380
|
-
populateAccess:
|
|
3926
|
+
options: z3.object({
|
|
3927
|
+
returningAll: z3.boolean().optional(),
|
|
3928
|
+
includePermissions: z3.boolean().optional(),
|
|
3929
|
+
populateAccess: z3.unknown().optional()
|
|
3381
3930
|
}).passthrough().optional()
|
|
3382
3931
|
}).passthrough();
|
|
3383
|
-
var upsertBodySchema =
|
|
3384
|
-
var advancedUpsertBodySchema =
|
|
3385
|
-
data:
|
|
3932
|
+
var upsertBodySchema = z3.record(z3.string(), z3.unknown());
|
|
3933
|
+
var advancedUpsertBodySchema = z3.object({
|
|
3934
|
+
data: z3.record(z3.string(), z3.unknown()),
|
|
3386
3935
|
select: projectionSchema.optional(),
|
|
3387
3936
|
populate: populateSchema.optional(),
|
|
3388
3937
|
tasks: tasksSchema.optional(),
|
|
3389
|
-
options:
|
|
3390
|
-
returningAll:
|
|
3391
|
-
includePermissions:
|
|
3392
|
-
populateAccess:
|
|
3938
|
+
options: z3.object({
|
|
3939
|
+
returningAll: z3.boolean().optional(),
|
|
3940
|
+
includePermissions: z3.boolean().optional(),
|
|
3941
|
+
populateAccess: z3.unknown().optional()
|
|
3393
3942
|
}).passthrough().optional()
|
|
3394
3943
|
}).passthrough();
|
|
3395
|
-
var distinctBodySchema =
|
|
3944
|
+
var distinctBodySchema = z3.object({
|
|
3396
3945
|
filter: objectOrArraySchema.optional()
|
|
3397
3946
|
}).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query"]));
|
|
3398
|
-
var subListBodySchema =
|
|
3399
|
-
filter:
|
|
3947
|
+
var subListBodySchema = z3.object({
|
|
3948
|
+
filter: z3.record(z3.string(), z3.unknown()).optional(),
|
|
3400
3949
|
select: fieldsSchema.optional()
|
|
3401
3950
|
}).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["fields"]));
|
|
3402
|
-
var subMutationBodySchema =
|
|
3403
|
-
|
|
3404
|
-
|
|
3951
|
+
var subMutationBodySchema = z3.union([
|
|
3952
|
+
z3.record(z3.string(), z3.unknown()),
|
|
3953
|
+
z3.array(z3.record(z3.string(), z3.unknown()))
|
|
3405
3954
|
]);
|
|
3406
|
-
var subReadBodySchema =
|
|
3955
|
+
var subReadBodySchema = z3.object({
|
|
3407
3956
|
select: fieldsSchema.optional(),
|
|
3408
3957
|
populate: subPopulateSchema.optional()
|
|
3409
3958
|
}).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["fields"]));
|
|
@@ -3416,54 +3965,54 @@ var requestSchemas = {
|
|
|
3416
3965
|
};
|
|
3417
3966
|
|
|
3418
3967
|
// src/validation/data-router.ts
|
|
3419
|
-
import { z as
|
|
3420
|
-
var dataListBodySchema =
|
|
3968
|
+
import { z as z4 } from "zod";
|
|
3969
|
+
var dataListBodySchema = z4.object({
|
|
3421
3970
|
filter: objectOrArraySchema.optional(),
|
|
3422
3971
|
select: projectionSchema.optional(),
|
|
3423
|
-
sort:
|
|
3424
|
-
skip:
|
|
3425
|
-
limit:
|
|
3426
|
-
page:
|
|
3427
|
-
pageSize:
|
|
3428
|
-
options:
|
|
3429
|
-
includeCount:
|
|
3430
|
-
includeExtraHeaders:
|
|
3972
|
+
sort: z4.string().optional(),
|
|
3973
|
+
skip: z4.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
3974
|
+
limit: z4.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
3975
|
+
page: z4.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
3976
|
+
pageSize: z4.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
3977
|
+
options: z4.object({
|
|
3978
|
+
includeCount: z4.boolean().optional(),
|
|
3979
|
+
includeExtraHeaders: z4.boolean().optional()
|
|
3431
3980
|
}).passthrough().optional()
|
|
3432
3981
|
}).passthrough();
|
|
3433
|
-
var dataReadFilterBodySchema =
|
|
3982
|
+
var dataReadFilterBodySchema = z4.object({
|
|
3434
3983
|
filter: objectOrArraySchema.optional(),
|
|
3435
3984
|
select: projectionSchema.optional()
|
|
3436
3985
|
}).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["options"]));
|
|
3437
|
-
var dataReadByIdBodySchema =
|
|
3986
|
+
var dataReadByIdBodySchema = z4.object({
|
|
3438
3987
|
select: projectionSchema.optional()
|
|
3439
3988
|
}).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["options"]));
|
|
3440
3989
|
|
|
3441
3990
|
// src/validation/root-router.ts
|
|
3442
|
-
import { z as
|
|
3991
|
+
import { z as z5 } from "zod";
|
|
3443
3992
|
var rootEntryBaseSchema = {
|
|
3444
|
-
target:
|
|
3445
|
-
name:
|
|
3446
|
-
order:
|
|
3993
|
+
target: z5.enum(["model", "data"]),
|
|
3994
|
+
name: z5.string().min(1),
|
|
3995
|
+
order: z5.number().int().optional()
|
|
3447
3996
|
};
|
|
3448
|
-
var rootModelListArgsSchema =
|
|
3997
|
+
var rootModelListArgsSchema = z5.object({
|
|
3449
3998
|
select: projectionSchema.optional(),
|
|
3450
3999
|
populate: populateSchema.optional(),
|
|
3451
4000
|
include: includeSchema.optional(),
|
|
3452
4001
|
sort: sortSchema.optional(),
|
|
3453
|
-
skip:
|
|
3454
|
-
limit:
|
|
3455
|
-
page:
|
|
3456
|
-
pageSize:
|
|
4002
|
+
skip: z5.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
4003
|
+
limit: z5.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
4004
|
+
page: z5.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
4005
|
+
pageSize: z5.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
3457
4006
|
tasks: tasksSchema.optional()
|
|
3458
4007
|
}).passthrough();
|
|
3459
|
-
var rootModelListOptionsSchema =
|
|
3460
|
-
skim:
|
|
3461
|
-
includePermissions:
|
|
3462
|
-
includeCount:
|
|
3463
|
-
populateAccess:
|
|
3464
|
-
lean:
|
|
4008
|
+
var rootModelListOptionsSchema = z5.object({
|
|
4009
|
+
skim: z5.boolean().optional(),
|
|
4010
|
+
includePermissions: z5.boolean().optional(),
|
|
4011
|
+
includeCount: z5.boolean().optional(),
|
|
4012
|
+
populateAccess: z5.unknown().optional(),
|
|
4013
|
+
lean: z5.boolean().optional()
|
|
3465
4014
|
}).passthrough();
|
|
3466
|
-
var rootModelReadArgsSchema =
|
|
4015
|
+
var rootModelReadArgsSchema = z5.object({
|
|
3467
4016
|
select: projectionSchema.optional(),
|
|
3468
4017
|
populate: populateSchema.optional(),
|
|
3469
4018
|
include: includeSchema.optional(),
|
|
@@ -3472,210 +4021,219 @@ var rootModelReadArgsSchema = z4.object({
|
|
|
3472
4021
|
var rootModelReadFilterArgsSchema = rootModelReadArgsSchema.extend({
|
|
3473
4022
|
sort: sortSchema.optional()
|
|
3474
4023
|
});
|
|
3475
|
-
var rootModelReadOptionsSchema =
|
|
3476
|
-
skim:
|
|
3477
|
-
includePermissions:
|
|
3478
|
-
tryList:
|
|
3479
|
-
populateAccess:
|
|
3480
|
-
lean:
|
|
4024
|
+
var rootModelReadOptionsSchema = z5.object({
|
|
4025
|
+
skim: z5.boolean().optional(),
|
|
4026
|
+
includePermissions: z5.boolean().optional(),
|
|
4027
|
+
tryList: z5.boolean().optional(),
|
|
4028
|
+
populateAccess: z5.unknown().optional(),
|
|
4029
|
+
lean: z5.boolean().optional()
|
|
3481
4030
|
}).passthrough();
|
|
3482
|
-
var rootModelCreateArgsSchema =
|
|
4031
|
+
var rootModelCreateArgsSchema = z5.object({
|
|
3483
4032
|
select: projectionSchema.optional(),
|
|
3484
4033
|
populate: populateSchema.optional(),
|
|
3485
4034
|
tasks: tasksSchema.optional()
|
|
3486
4035
|
}).passthrough();
|
|
3487
|
-
var rootModelCreateOptionsSchema =
|
|
3488
|
-
skim:
|
|
3489
|
-
includePermissions:
|
|
3490
|
-
populateAccess:
|
|
4036
|
+
var rootModelCreateOptionsSchema = z5.object({
|
|
4037
|
+
skim: z5.boolean().optional(),
|
|
4038
|
+
includePermissions: z5.boolean().optional(),
|
|
4039
|
+
populateAccess: z5.unknown().optional()
|
|
3491
4040
|
}).passthrough();
|
|
3492
|
-
var rootModelUpdateArgsSchema =
|
|
4041
|
+
var rootModelUpdateArgsSchema = z5.object({
|
|
3493
4042
|
select: projectionSchema.optional(),
|
|
3494
4043
|
populate: populateSchema.optional(),
|
|
3495
4044
|
tasks: tasksSchema.optional()
|
|
3496
4045
|
}).passthrough();
|
|
3497
|
-
var rootModelUpdateOptionsSchema =
|
|
3498
|
-
skim:
|
|
3499
|
-
returningAll:
|
|
3500
|
-
includePermissions:
|
|
3501
|
-
populateAccess:
|
|
4046
|
+
var rootModelUpdateOptionsSchema = z5.object({
|
|
4047
|
+
skim: z5.boolean().optional(),
|
|
4048
|
+
returningAll: z5.boolean().optional(),
|
|
4049
|
+
includePermissions: z5.boolean().optional(),
|
|
4050
|
+
populateAccess: z5.unknown().optional()
|
|
3502
4051
|
}).passthrough();
|
|
3503
4052
|
var rootModelUpsertArgsSchema = rootModelUpdateArgsSchema;
|
|
3504
4053
|
var rootModelUpsertOptionsSchema = rootModelUpdateOptionsSchema;
|
|
3505
|
-
var rootModelSubListArgsSchema =
|
|
4054
|
+
var rootModelSubListArgsSchema = z5.object({
|
|
3506
4055
|
select: fieldsSchema.optional()
|
|
3507
4056
|
}).passthrough();
|
|
3508
|
-
var rootModelSubReadArgsSchema =
|
|
4057
|
+
var rootModelSubReadArgsSchema = z5.object({
|
|
3509
4058
|
select: fieldsSchema.optional(),
|
|
3510
4059
|
populate: subPopulateSchema.optional()
|
|
3511
4060
|
}).passthrough();
|
|
3512
|
-
var rootModelCountOptionsSchema =
|
|
3513
|
-
access:
|
|
4061
|
+
var rootModelCountOptionsSchema = z5.object({
|
|
4062
|
+
access: z5.unknown().optional()
|
|
3514
4063
|
}).passthrough();
|
|
3515
|
-
var rootDataListArgsSchema =
|
|
4064
|
+
var rootDataListArgsSchema = z5.object({
|
|
3516
4065
|
select: projectionSchema.optional(),
|
|
3517
|
-
sort:
|
|
3518
|
-
skip:
|
|
3519
|
-
limit:
|
|
3520
|
-
page:
|
|
3521
|
-
pageSize:
|
|
4066
|
+
sort: z5.string().optional(),
|
|
4067
|
+
skip: z5.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
4068
|
+
limit: z5.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
4069
|
+
page: z5.union([nonNegativeIntegerSchema, positiveIntegerString]).optional(),
|
|
4070
|
+
pageSize: z5.union([nonNegativeIntegerSchema, positiveIntegerString]).optional()
|
|
3522
4071
|
}).passthrough();
|
|
3523
|
-
var rootDataListOptionsSchema =
|
|
3524
|
-
includeCount:
|
|
4072
|
+
var rootDataListOptionsSchema = z5.object({
|
|
4073
|
+
includeCount: z5.boolean().optional()
|
|
3525
4074
|
}).passthrough();
|
|
3526
|
-
var rootDataReadArgsSchema =
|
|
4075
|
+
var rootDataReadArgsSchema = z5.object({
|
|
3527
4076
|
select: projectionSchema.optional()
|
|
3528
4077
|
}).passthrough();
|
|
3529
|
-
var rootModelQueryEntrySchema =
|
|
3530
|
-
|
|
3531
|
-
|
|
4078
|
+
var rootModelQueryEntrySchema = z5.union([
|
|
4079
|
+
z5.object({ ...rootEntryBaseSchema, target: z5.literal("model"), op: z5.literal("new") }).passthrough(),
|
|
4080
|
+
z5.object({
|
|
3532
4081
|
...rootEntryBaseSchema,
|
|
3533
|
-
target:
|
|
3534
|
-
op:
|
|
4082
|
+
target: z5.literal("model"),
|
|
4083
|
+
op: z5.literal("list"),
|
|
3535
4084
|
filter: objectOrArraySchema.optional(),
|
|
3536
4085
|
args: rootModelListArgsSchema.optional(),
|
|
3537
4086
|
options: rootModelListOptionsSchema.optional()
|
|
3538
4087
|
}).passthrough(),
|
|
3539
|
-
|
|
4088
|
+
z5.object({
|
|
3540
4089
|
...rootEntryBaseSchema,
|
|
3541
|
-
target:
|
|
3542
|
-
op:
|
|
3543
|
-
id:
|
|
4090
|
+
target: z5.literal("model"),
|
|
4091
|
+
op: z5.literal("read"),
|
|
4092
|
+
id: z5.string().min(1),
|
|
3544
4093
|
args: rootModelReadArgsSchema.optional(),
|
|
3545
4094
|
options: rootModelReadOptionsSchema.optional()
|
|
3546
4095
|
}).passthrough(),
|
|
3547
|
-
|
|
4096
|
+
z5.object({
|
|
3548
4097
|
...rootEntryBaseSchema,
|
|
3549
|
-
target:
|
|
3550
|
-
op:
|
|
4098
|
+
target: z5.literal("model"),
|
|
4099
|
+
op: z5.literal("read"),
|
|
3551
4100
|
filter: objectOrArraySchema,
|
|
3552
4101
|
args: rootModelReadFilterArgsSchema.optional(),
|
|
3553
4102
|
options: rootModelReadOptionsSchema.optional()
|
|
3554
4103
|
}).passthrough(),
|
|
3555
|
-
|
|
4104
|
+
z5.object({
|
|
3556
4105
|
...rootEntryBaseSchema,
|
|
3557
|
-
target:
|
|
3558
|
-
op:
|
|
3559
|
-
data:
|
|
4106
|
+
target: z5.literal("model"),
|
|
4107
|
+
op: z5.literal("create"),
|
|
4108
|
+
data: z5.unknown(),
|
|
3560
4109
|
args: rootModelCreateArgsSchema.optional(),
|
|
3561
4110
|
options: rootModelCreateOptionsSchema.optional()
|
|
3562
4111
|
}).passthrough(),
|
|
3563
|
-
|
|
4112
|
+
z5.object({
|
|
3564
4113
|
...rootEntryBaseSchema,
|
|
3565
|
-
target:
|
|
3566
|
-
op:
|
|
3567
|
-
id:
|
|
3568
|
-
data:
|
|
4114
|
+
target: z5.literal("model"),
|
|
4115
|
+
op: z5.literal("update"),
|
|
4116
|
+
id: z5.string().min(1),
|
|
4117
|
+
data: z5.unknown(),
|
|
3569
4118
|
args: rootModelUpdateArgsSchema.optional(),
|
|
3570
4119
|
options: rootModelUpdateOptionsSchema.optional()
|
|
3571
4120
|
}).passthrough(),
|
|
3572
|
-
|
|
4121
|
+
z5.object({
|
|
3573
4122
|
...rootEntryBaseSchema,
|
|
3574
|
-
target:
|
|
3575
|
-
op:
|
|
3576
|
-
data:
|
|
4123
|
+
target: z5.literal("model"),
|
|
4124
|
+
op: z5.literal("upsert"),
|
|
4125
|
+
data: z5.record(z5.string(), z5.unknown()),
|
|
3577
4126
|
args: rootModelUpsertArgsSchema.optional(),
|
|
3578
4127
|
options: rootModelUpsertOptionsSchema.optional()
|
|
3579
4128
|
}).passthrough(),
|
|
3580
|
-
|
|
3581
|
-
|
|
4129
|
+
z5.object({ ...rootEntryBaseSchema, target: z5.literal("model"), op: z5.literal("delete"), id: z5.string().min(1) }).passthrough(),
|
|
4130
|
+
z5.object({
|
|
3582
4131
|
...rootEntryBaseSchema,
|
|
3583
|
-
target:
|
|
3584
|
-
op:
|
|
3585
|
-
id:
|
|
3586
|
-
sub:
|
|
3587
|
-
filter:
|
|
4132
|
+
target: z5.literal("model"),
|
|
4133
|
+
op: z5.literal("subList"),
|
|
4134
|
+
id: z5.string().min(1),
|
|
4135
|
+
sub: z5.string().min(1),
|
|
4136
|
+
filter: z5.record(z5.string(), z5.unknown()).optional(),
|
|
3588
4137
|
args: rootModelSubListArgsSchema.optional()
|
|
3589
4138
|
}).passthrough(),
|
|
3590
|
-
|
|
4139
|
+
z5.object({
|
|
3591
4140
|
...rootEntryBaseSchema,
|
|
3592
|
-
target:
|
|
3593
|
-
op:
|
|
3594
|
-
id:
|
|
3595
|
-
sub:
|
|
3596
|
-
subId:
|
|
4141
|
+
target: z5.literal("model"),
|
|
4142
|
+
op: z5.literal("subRead"),
|
|
4143
|
+
id: z5.string().min(1),
|
|
4144
|
+
sub: z5.string().min(1),
|
|
4145
|
+
subId: z5.string().min(1),
|
|
3597
4146
|
args: rootModelSubReadArgsSchema.optional()
|
|
3598
4147
|
}).passthrough(),
|
|
3599
|
-
|
|
4148
|
+
z5.object({
|
|
3600
4149
|
...rootEntryBaseSchema,
|
|
3601
|
-
target:
|
|
3602
|
-
op:
|
|
3603
|
-
id:
|
|
3604
|
-
sub:
|
|
3605
|
-
data:
|
|
4150
|
+
target: z5.literal("model"),
|
|
4151
|
+
op: z5.literal("subCreate"),
|
|
4152
|
+
id: z5.string().min(1),
|
|
4153
|
+
sub: z5.string().min(1),
|
|
4154
|
+
data: z5.union([z5.record(z5.string(), z5.unknown()), z5.array(z5.record(z5.string(), z5.unknown()))])
|
|
3606
4155
|
}).passthrough(),
|
|
3607
|
-
|
|
4156
|
+
z5.object({
|
|
3608
4157
|
...rootEntryBaseSchema,
|
|
3609
|
-
target:
|
|
3610
|
-
op:
|
|
3611
|
-
id:
|
|
3612
|
-
sub:
|
|
3613
|
-
subId:
|
|
3614
|
-
data:
|
|
4158
|
+
target: z5.literal("model"),
|
|
4159
|
+
op: z5.literal("subUpdate"),
|
|
4160
|
+
id: z5.string().min(1),
|
|
4161
|
+
sub: z5.string().min(1),
|
|
4162
|
+
subId: z5.string().min(1),
|
|
4163
|
+
data: z5.union([z5.record(z5.string(), z5.unknown()), z5.array(z5.record(z5.string(), z5.unknown()))])
|
|
3615
4164
|
}).passthrough(),
|
|
3616
|
-
|
|
4165
|
+
z5.object({
|
|
3617
4166
|
...rootEntryBaseSchema,
|
|
3618
|
-
target:
|
|
3619
|
-
op:
|
|
3620
|
-
id:
|
|
3621
|
-
sub:
|
|
3622
|
-
data:
|
|
4167
|
+
target: z5.literal("model"),
|
|
4168
|
+
op: z5.literal("subBulkUpdate"),
|
|
4169
|
+
id: z5.string().min(1),
|
|
4170
|
+
sub: z5.string().min(1),
|
|
4171
|
+
data: z5.union([z5.record(z5.string(), z5.unknown()), z5.array(z5.record(z5.string(), z5.unknown()))])
|
|
3623
4172
|
}).passthrough(),
|
|
3624
|
-
|
|
4173
|
+
z5.object({
|
|
3625
4174
|
...rootEntryBaseSchema,
|
|
3626
|
-
target:
|
|
3627
|
-
op:
|
|
3628
|
-
id:
|
|
3629
|
-
sub:
|
|
3630
|
-
subId:
|
|
4175
|
+
target: z5.literal("model"),
|
|
4176
|
+
op: z5.literal("subDelete"),
|
|
4177
|
+
id: z5.string().min(1),
|
|
4178
|
+
sub: z5.string().min(1),
|
|
4179
|
+
subId: z5.string().min(1)
|
|
3631
4180
|
}).passthrough(),
|
|
3632
|
-
|
|
4181
|
+
z5.object({
|
|
3633
4182
|
...rootEntryBaseSchema,
|
|
3634
|
-
target:
|
|
3635
|
-
op:
|
|
3636
|
-
field:
|
|
4183
|
+
target: z5.literal("model"),
|
|
4184
|
+
op: z5.literal("distinct"),
|
|
4185
|
+
field: z5.string().min(1),
|
|
3637
4186
|
filter: objectOrArraySchema.optional()
|
|
3638
4187
|
}).passthrough(),
|
|
3639
|
-
|
|
4188
|
+
z5.object({
|
|
3640
4189
|
...rootEntryBaseSchema,
|
|
3641
|
-
target:
|
|
3642
|
-
op:
|
|
4190
|
+
target: z5.literal("model"),
|
|
4191
|
+
op: z5.literal("count"),
|
|
3643
4192
|
filter: objectOrArraySchema.optional(),
|
|
3644
4193
|
options: rootModelCountOptionsSchema.optional()
|
|
3645
4194
|
}).passthrough()
|
|
3646
4195
|
]);
|
|
3647
|
-
var rootDataQueryEntrySchema =
|
|
3648
|
-
|
|
4196
|
+
var rootDataQueryEntrySchema = z5.union([
|
|
4197
|
+
z5.object({
|
|
3649
4198
|
...rootEntryBaseSchema,
|
|
3650
|
-
target:
|
|
3651
|
-
op:
|
|
4199
|
+
target: z5.literal("data"),
|
|
4200
|
+
op: z5.literal("list"),
|
|
3652
4201
|
filter: objectOrArraySchema.optional(),
|
|
3653
4202
|
args: rootDataListArgsSchema.optional(),
|
|
3654
4203
|
options: rootDataListOptionsSchema.optional()
|
|
3655
4204
|
}).passthrough(),
|
|
3656
|
-
|
|
4205
|
+
z5.object({
|
|
3657
4206
|
...rootEntryBaseSchema,
|
|
3658
|
-
target:
|
|
3659
|
-
op:
|
|
3660
|
-
id:
|
|
4207
|
+
target: z5.literal("data"),
|
|
4208
|
+
op: z5.literal("read"),
|
|
4209
|
+
id: z5.string().min(1),
|
|
3661
4210
|
args: rootDataReadArgsSchema.optional()
|
|
3662
4211
|
}).passthrough(),
|
|
3663
|
-
|
|
4212
|
+
z5.object({
|
|
3664
4213
|
...rootEntryBaseSchema,
|
|
3665
|
-
target:
|
|
3666
|
-
op:
|
|
4214
|
+
target: z5.literal("data"),
|
|
4215
|
+
op: z5.literal("read"),
|
|
3667
4216
|
filter: objectOrArraySchema,
|
|
3668
4217
|
args: rootDataReadArgsSchema.optional()
|
|
3669
4218
|
}).passthrough()
|
|
3670
4219
|
]);
|
|
3671
|
-
var rootQuerySchema =
|
|
4220
|
+
var rootQuerySchema = z5.array(z5.union([rootModelQueryEntrySchema, rootDataQueryEntrySchema]));
|
|
3672
4221
|
|
|
3673
4222
|
// src/routers/shared.ts
|
|
3674
|
-
|
|
4223
|
+
import { parseBooleanString } from "@web-ts-toolkit/utils";
|
|
3675
4224
|
|
|
3676
4225
|
// src/routers/model-router-collection-routes.ts
|
|
3677
4226
|
function setModelCollectionRoutes(context) {
|
|
3678
4227
|
const { router, options } = context;
|
|
4228
|
+
const getAdvancedCreateOpenApiBody = () => {
|
|
4229
|
+
const advancedCreateSchema = context.getRequestSchema("requestSchemas.advancedCreate");
|
|
4230
|
+
const dataSchema = context.getRequestSchema("requestSchemas.advancedCreate.data") ?? getNestedOpenApiSchemaDataSource(advancedCreateSchema);
|
|
4231
|
+
const bodySchema = unwrapNestedOpenApiSchemaSource(
|
|
4232
|
+
context.getRequestSchema("requestSchemas.advancedCreate.default") ?? advancedCreateSchema,
|
|
4233
|
+
advancedCreateBodySchema
|
|
4234
|
+
);
|
|
4235
|
+
return dataSchema ? patchOpenApiObjectSchema(bodySchema, { data: dataSchema }) : bodySchema;
|
|
4236
|
+
};
|
|
3679
4237
|
router.get("", async (req) => {
|
|
3680
4238
|
await context.assertAllowed(req, "list");
|
|
3681
4239
|
const { skip, limit, page, page_size, skim, include_permissions, include_count, include_extra_headers } = parseQuery(requestSchemas.listQuery, req.query);
|
|
@@ -3694,9 +4252,16 @@ function setModelCollectionRoutes(context) {
|
|
|
3694
4252
|
handleResultError(result);
|
|
3695
4253
|
return formatModelListResponse(req, result, includeCount, includeExtraHeaders);
|
|
3696
4254
|
});
|
|
4255
|
+
context.registerOpenApiRoute({
|
|
4256
|
+
method: "get",
|
|
4257
|
+
path: "",
|
|
4258
|
+
operationId: `${context.modelName}.list`,
|
|
4259
|
+
summary: `List ${context.modelName} documents`,
|
|
4260
|
+
query: requestSchemas.listQuery
|
|
4261
|
+
});
|
|
3697
4262
|
router.post(`/${options.queryRouteSegment}`, async (req) => {
|
|
3698
4263
|
await context.assertAllowed(req, "list");
|
|
3699
|
-
const body = parseBodyWithSchema(
|
|
4264
|
+
const body = await parseBodyWithSchema(
|
|
3700
4265
|
listBodySchema,
|
|
3701
4266
|
req.body,
|
|
3702
4267
|
context.getRequestSchema("requestSchemas.advancedList")
|
|
@@ -3719,19 +4284,38 @@ function setModelCollectionRoutes(context) {
|
|
|
3719
4284
|
handleResultError(result);
|
|
3720
4285
|
return formatModelListResponse(req, result, includeCount, includeExtraHeaders);
|
|
3721
4286
|
});
|
|
4287
|
+
context.registerOpenApiRoute({
|
|
4288
|
+
method: "post",
|
|
4289
|
+
path: `/${options.queryRouteSegment}`,
|
|
4290
|
+
operationId: `${context.modelName}.listAdvanced`,
|
|
4291
|
+
summary: `Advanced list ${context.modelName} documents`,
|
|
4292
|
+
body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.advancedList") ?? listBodySchema)
|
|
4293
|
+
});
|
|
3722
4294
|
router.post("", async (req) => {
|
|
3723
4295
|
await context.assertAllowed(req, "create");
|
|
3724
4296
|
const { include_permissions } = parseQuery(requestSchemas.createQuery, req.query);
|
|
3725
|
-
const data = parseBodyWithSchema(
|
|
4297
|
+
const data = await parseBodyWithSchema(
|
|
4298
|
+
createBodySchema,
|
|
4299
|
+
req.body,
|
|
4300
|
+
context.getRequestSchema("requestSchemas.create")
|
|
4301
|
+
);
|
|
3726
4302
|
const svc = context.getPublicService(req);
|
|
3727
4303
|
const result = await svc._create(data, {}, { includePermissions: parseBooleanString(include_permissions) });
|
|
3728
4304
|
handleResultError(result);
|
|
3729
4305
|
return formatModelCreatedResponse(result);
|
|
3730
4306
|
});
|
|
4307
|
+
context.registerOpenApiRoute({
|
|
4308
|
+
method: "post",
|
|
4309
|
+
path: "",
|
|
4310
|
+
operationId: `${context.modelName}.create`,
|
|
4311
|
+
summary: `Create a ${context.modelName} document`,
|
|
4312
|
+
query: requestSchemas.createQuery,
|
|
4313
|
+
body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.create") ?? createBodySchema)
|
|
4314
|
+
});
|
|
3731
4315
|
router.post(`/${options.mutationRouteSegment}`, async (req) => {
|
|
3732
4316
|
await context.assertAllowed(req, "create");
|
|
3733
4317
|
const { include_permissions } = parseQuery(requestSchemas.createQuery, req.query);
|
|
3734
|
-
const body = parseNestedBodyWithSchema(
|
|
4318
|
+
const body = await parseNestedBodyWithSchema(
|
|
3735
4319
|
advancedCreateBodySchema,
|
|
3736
4320
|
req.body,
|
|
3737
4321
|
"data",
|
|
@@ -3739,7 +4323,7 @@ function setModelCollectionRoutes(context) {
|
|
|
3739
4323
|
);
|
|
3740
4324
|
const { data, select, populate, tasks } = body;
|
|
3741
4325
|
const advancedOptions = body.options ?? {};
|
|
3742
|
-
parseBodyWithSchema(
|
|
4326
|
+
await parseBodyWithSchema(
|
|
3743
4327
|
advancedCreateBodySchema,
|
|
3744
4328
|
{ data, select, populate, tasks, options: advancedOptions },
|
|
3745
4329
|
context.getRequestSchema("requestSchemas.advancedCreate.default") ?? context.getRequestSchema("requestSchemas.advancedCreate")
|
|
@@ -3757,17 +4341,49 @@ function setModelCollectionRoutes(context) {
|
|
|
3757
4341
|
handleResultError(result);
|
|
3758
4342
|
return formatModelCreatedResponse(result);
|
|
3759
4343
|
});
|
|
4344
|
+
context.registerOpenApiRoute({
|
|
4345
|
+
method: "post",
|
|
4346
|
+
path: `/${options.mutationRouteSegment}`,
|
|
4347
|
+
operationId: `${context.modelName}.createAdvanced`,
|
|
4348
|
+
summary: `Advanced create a ${context.modelName} document`,
|
|
4349
|
+
query: requestSchemas.createQuery,
|
|
4350
|
+
body: defineOpenApiSchemaResolver(getAdvancedCreateOpenApiBody)
|
|
4351
|
+
});
|
|
3760
4352
|
router.get("/new", async (req) => {
|
|
3761
4353
|
const svc = context.getPublicService(req);
|
|
3762
4354
|
const result = await svc._new();
|
|
3763
4355
|
handleResultError(result);
|
|
3764
4356
|
return unwrapServiceData(result);
|
|
3765
4357
|
});
|
|
4358
|
+
context.registerOpenApiRoute({
|
|
4359
|
+
method: "get",
|
|
4360
|
+
path: "/new",
|
|
4361
|
+
operationId: `${context.modelName}.new`,
|
|
4362
|
+
summary: `Get a new ${context.modelName} document template`
|
|
4363
|
+
});
|
|
3766
4364
|
}
|
|
3767
4365
|
|
|
3768
4366
|
// src/routers/model-router-document-routes.ts
|
|
3769
4367
|
function setModelDocumentRoutes(context) {
|
|
3770
4368
|
const { router, options, modelName } = context;
|
|
4369
|
+
const getAdvancedUpdateOpenApiBody = () => {
|
|
4370
|
+
const advancedUpdateSchema = context.getRequestSchema("requestSchemas.advancedUpdate");
|
|
4371
|
+
const dataSchema = context.getRequestSchema("requestSchemas.advancedUpdate.data") ?? getNestedOpenApiSchemaDataSource(advancedUpdateSchema);
|
|
4372
|
+
const bodySchema = unwrapNestedOpenApiSchemaSource(
|
|
4373
|
+
context.getRequestSchema("requestSchemas.advancedUpdate.default") ?? advancedUpdateSchema,
|
|
4374
|
+
advancedUpdateBodySchema
|
|
4375
|
+
);
|
|
4376
|
+
return dataSchema ? patchOpenApiObjectSchema(bodySchema, { data: dataSchema }) : bodySchema;
|
|
4377
|
+
};
|
|
4378
|
+
const getAdvancedUpsertOpenApiBody = () => {
|
|
4379
|
+
const advancedUpsertSchema = context.getRequestSchema("requestSchemas.advancedUpsert");
|
|
4380
|
+
const dataSchema = context.getRequestSchema("requestSchemas.advancedUpsert.data") ?? getNestedOpenApiSchemaDataSource(advancedUpsertSchema);
|
|
4381
|
+
const bodySchema = unwrapNestedOpenApiSchemaSource(
|
|
4382
|
+
context.getRequestSchema("requestSchemas.advancedUpsert.default") ?? advancedUpsertSchema,
|
|
4383
|
+
advancedUpsertBodySchema
|
|
4384
|
+
);
|
|
4385
|
+
return dataSchema ? patchOpenApiObjectSchema(bodySchema, { data: dataSchema }) : bodySchema;
|
|
4386
|
+
};
|
|
3771
4387
|
router.get("/count", async (req) => {
|
|
3772
4388
|
await context.assertAllowed(req, "count");
|
|
3773
4389
|
const svc = context.getPublicService(req);
|
|
@@ -3775,9 +4391,15 @@ function setModelDocumentRoutes(context) {
|
|
|
3775
4391
|
handleResultError(result);
|
|
3776
4392
|
return unwrapServiceData(result);
|
|
3777
4393
|
});
|
|
4394
|
+
context.registerOpenApiRoute({
|
|
4395
|
+
method: "get",
|
|
4396
|
+
path: "/count",
|
|
4397
|
+
operationId: `${modelName}.count`,
|
|
4398
|
+
summary: `Count ${modelName} documents`
|
|
4399
|
+
});
|
|
3778
4400
|
router.post("/count", async (req) => {
|
|
3779
4401
|
await context.assertAllowed(req, "count");
|
|
3780
|
-
const { filter: filter2, options: countOptions = {} } = parseBodyWithSchema(
|
|
4402
|
+
const { filter: filter2, options: countOptions = {} } = await parseBodyWithSchema(
|
|
3781
4403
|
countBodySchema,
|
|
3782
4404
|
req.body,
|
|
3783
4405
|
context.getRequestSchema("requestSchemas.count")
|
|
@@ -3790,6 +4412,13 @@ function setModelDocumentRoutes(context) {
|
|
|
3790
4412
|
handleResultError(result);
|
|
3791
4413
|
return unwrapServiceData(result);
|
|
3792
4414
|
});
|
|
4415
|
+
context.registerOpenApiRoute({
|
|
4416
|
+
method: "post",
|
|
4417
|
+
path: "/count",
|
|
4418
|
+
operationId: `${modelName}.countWithFilter`,
|
|
4419
|
+
summary: `Count ${modelName} documents with a filter`,
|
|
4420
|
+
body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.count") ?? countBodySchema)
|
|
4421
|
+
});
|
|
3793
4422
|
router.get(`/:${options.idParam}`, async (req) => {
|
|
3794
4423
|
await context.assertAllowed(req, "read");
|
|
3795
4424
|
const id = parsePathParam(req.params[options.idParam], options.idParam);
|
|
@@ -3806,9 +4435,16 @@ function setModelDocumentRoutes(context) {
|
|
|
3806
4435
|
handleResultError(result);
|
|
3807
4436
|
return unwrapServiceData(result);
|
|
3808
4437
|
});
|
|
4438
|
+
context.registerOpenApiRoute({
|
|
4439
|
+
method: "get",
|
|
4440
|
+
path: `/:${options.idParam}`,
|
|
4441
|
+
operationId: `${modelName}.read`,
|
|
4442
|
+
summary: `Read a ${modelName} document`,
|
|
4443
|
+
query: requestSchemas.readQuery
|
|
4444
|
+
});
|
|
3809
4445
|
router.post(`/${options.queryRouteSegment}/__filter`, async (req) => {
|
|
3810
4446
|
await context.assertAllowed(req, "read");
|
|
3811
|
-
const body = parseBodyWithSchema(
|
|
4447
|
+
const body = await parseBodyWithSchema(
|
|
3812
4448
|
readFilterBodySchema,
|
|
3813
4449
|
req.body,
|
|
3814
4450
|
context.getRequestSchema("requestSchemas.advancedReadFilter")
|
|
@@ -3825,10 +4461,19 @@ function setModelDocumentRoutes(context) {
|
|
|
3825
4461
|
handleResultError(result);
|
|
3826
4462
|
return unwrapServiceData(result);
|
|
3827
4463
|
});
|
|
4464
|
+
context.registerOpenApiRoute({
|
|
4465
|
+
method: "post",
|
|
4466
|
+
path: `/${options.queryRouteSegment}/__filter`,
|
|
4467
|
+
operationId: `${modelName}.readByFilterAdvanced`,
|
|
4468
|
+
summary: `Read a ${modelName} document by filter`,
|
|
4469
|
+
body: defineOpenApiSchemaResolver(
|
|
4470
|
+
() => context.getRequestSchema("requestSchemas.advancedReadFilter") ?? readFilterBodySchema
|
|
4471
|
+
)
|
|
4472
|
+
});
|
|
3828
4473
|
router.post(`/${options.queryRouteSegment}/:${options.idParam}`, async (req) => {
|
|
3829
4474
|
await context.assertAllowed(req, "read");
|
|
3830
4475
|
const id = parsePathParam(req.params[options.idParam], options.idParam);
|
|
3831
|
-
const body = parseBodyWithSchema(
|
|
4476
|
+
const body = await parseBodyWithSchema(
|
|
3832
4477
|
readByIdBodySchema,
|
|
3833
4478
|
req.body,
|
|
3834
4479
|
context.getRequestSchema("requestSchemas.advancedRead")
|
|
@@ -3845,11 +4490,24 @@ function setModelDocumentRoutes(context) {
|
|
|
3845
4490
|
handleResultError(result);
|
|
3846
4491
|
return unwrapServiceData(result);
|
|
3847
4492
|
});
|
|
4493
|
+
context.registerOpenApiRoute({
|
|
4494
|
+
method: "post",
|
|
4495
|
+
path: `/${options.queryRouteSegment}/:${options.idParam}`,
|
|
4496
|
+
operationId: `${modelName}.readAdvanced`,
|
|
4497
|
+
summary: `Read a ${modelName} document with advanced options`,
|
|
4498
|
+
body: defineOpenApiSchemaResolver(
|
|
4499
|
+
() => context.getRequestSchema("requestSchemas.advancedRead") ?? readByIdBodySchema
|
|
4500
|
+
)
|
|
4501
|
+
});
|
|
3848
4502
|
router.patch(`/:${options.idParam}`, async (req) => {
|
|
3849
4503
|
await context.assertAllowed(req, "update");
|
|
3850
4504
|
const id = parsePathParam(req.params[options.idParam], options.idParam);
|
|
3851
4505
|
const { returning_all, include_permissions } = parseQuery(requestSchemas.updateQuery, req.query);
|
|
3852
|
-
const data = parseBodyWithSchema(
|
|
4506
|
+
const data = await parseBodyWithSchema(
|
|
4507
|
+
updateBodySchema,
|
|
4508
|
+
req.body,
|
|
4509
|
+
context.getRequestSchema("requestSchemas.update")
|
|
4510
|
+
);
|
|
3853
4511
|
const svc = context.getPublicService(req);
|
|
3854
4512
|
const result = await svc._update(
|
|
3855
4513
|
id,
|
|
@@ -3863,11 +4521,19 @@ function setModelDocumentRoutes(context) {
|
|
|
3863
4521
|
handleResultError(result);
|
|
3864
4522
|
return unwrapServiceData(result);
|
|
3865
4523
|
});
|
|
4524
|
+
context.registerOpenApiRoute({
|
|
4525
|
+
method: "patch",
|
|
4526
|
+
path: `/:${options.idParam}`,
|
|
4527
|
+
operationId: `${modelName}.update`,
|
|
4528
|
+
summary: `Update a ${modelName} document`,
|
|
4529
|
+
query: requestSchemas.updateQuery,
|
|
4530
|
+
body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.update") ?? updateBodySchema)
|
|
4531
|
+
});
|
|
3866
4532
|
router.patch(`/${options.mutationRouteSegment}/:${options.idParam}`, async (req) => {
|
|
3867
4533
|
await context.assertAllowed(req, "update");
|
|
3868
4534
|
const id = parsePathParam(req.params[options.idParam], options.idParam);
|
|
3869
4535
|
const { returning_all, include_permissions } = parseQuery(requestSchemas.updateQuery, req.query);
|
|
3870
|
-
const body = parseNestedBodyWithSchema(
|
|
4536
|
+
const body = await parseNestedBodyWithSchema(
|
|
3871
4537
|
advancedUpdateBodySchema,
|
|
3872
4538
|
req.body,
|
|
3873
4539
|
"data",
|
|
@@ -3875,7 +4541,7 @@ function setModelDocumentRoutes(context) {
|
|
|
3875
4541
|
);
|
|
3876
4542
|
const { data, select, populate, tasks } = body;
|
|
3877
4543
|
const advancedOptions = body.options ?? {};
|
|
3878
|
-
parseBodyWithSchema(
|
|
4544
|
+
await parseBodyWithSchema(
|
|
3879
4545
|
advancedUpdateBodySchema,
|
|
3880
4546
|
{ data, select, populate, tasks, options: advancedOptions },
|
|
3881
4547
|
context.getRequestSchema("requestSchemas.advancedUpdate.default") ?? context.getRequestSchema("requestSchemas.advancedUpdate")
|
|
@@ -3895,11 +4561,23 @@ function setModelDocumentRoutes(context) {
|
|
|
3895
4561
|
handleResultError(result);
|
|
3896
4562
|
return unwrapServiceData(result);
|
|
3897
4563
|
});
|
|
4564
|
+
context.registerOpenApiRoute({
|
|
4565
|
+
method: "patch",
|
|
4566
|
+
path: `/${options.mutationRouteSegment}/:${options.idParam}`,
|
|
4567
|
+
operationId: `${modelName}.updateAdvanced`,
|
|
4568
|
+
summary: `Advanced update a ${modelName} document`,
|
|
4569
|
+
query: requestSchemas.updateQuery,
|
|
4570
|
+
body: defineOpenApiSchemaResolver(getAdvancedUpdateOpenApiBody)
|
|
4571
|
+
});
|
|
3898
4572
|
router.put(`/`, async (req) => {
|
|
3899
4573
|
await context.assertAllowed(req, "upsert");
|
|
3900
4574
|
const svc = context.getPublicService(req);
|
|
3901
4575
|
const { returning_all, include_permissions } = parseQuery(requestSchemas.upsertQuery, req.query);
|
|
3902
|
-
const body = parseBodyWithSchema(
|
|
4576
|
+
const body = await parseBodyWithSchema(
|
|
4577
|
+
upsertBodySchema,
|
|
4578
|
+
req.body,
|
|
4579
|
+
context.getRequestSchema("requestSchemas.upsert")
|
|
4580
|
+
);
|
|
3903
4581
|
const result = await svc._upsert(
|
|
3904
4582
|
body,
|
|
3905
4583
|
{},
|
|
@@ -3911,11 +4589,19 @@ function setModelDocumentRoutes(context) {
|
|
|
3911
4589
|
handleResultError(result);
|
|
3912
4590
|
return formatModelUpsertResponse(result);
|
|
3913
4591
|
});
|
|
4592
|
+
context.registerOpenApiRoute({
|
|
4593
|
+
method: "put",
|
|
4594
|
+
path: "/",
|
|
4595
|
+
operationId: `${modelName}.upsert`,
|
|
4596
|
+
summary: `Upsert a ${modelName} document`,
|
|
4597
|
+
query: requestSchemas.upsertQuery,
|
|
4598
|
+
body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.upsert") ?? upsertBodySchema)
|
|
4599
|
+
});
|
|
3914
4600
|
router.put(`/${options.mutationRouteSegment}`, async (req) => {
|
|
3915
4601
|
await context.assertAllowed(req, "upsert");
|
|
3916
4602
|
const svc = context.getPublicService(req);
|
|
3917
4603
|
const { returning_all, include_permissions } = parseQuery(requestSchemas.upsertQuery, req.query);
|
|
3918
|
-
const body = parseNestedBodyWithSchema(
|
|
4604
|
+
const body = await parseNestedBodyWithSchema(
|
|
3919
4605
|
advancedUpsertBodySchema,
|
|
3920
4606
|
req.body,
|
|
3921
4607
|
"data",
|
|
@@ -3923,7 +4609,7 @@ function setModelDocumentRoutes(context) {
|
|
|
3923
4609
|
);
|
|
3924
4610
|
const { data, select, populate, tasks } = body;
|
|
3925
4611
|
const advancedOptions = body.options ?? {};
|
|
3926
|
-
parseBodyWithSchema(
|
|
4612
|
+
await parseBodyWithSchema(
|
|
3927
4613
|
advancedUpsertBodySchema,
|
|
3928
4614
|
{ data, select, populate, tasks, options: advancedOptions },
|
|
3929
4615
|
context.getRequestSchema("requestSchemas.advancedUpsert.default") ?? context.getRequestSchema("requestSchemas.advancedUpsert")
|
|
@@ -3941,6 +4627,14 @@ function setModelDocumentRoutes(context) {
|
|
|
3941
4627
|
handleResultError(result);
|
|
3942
4628
|
return formatModelUpsertResponse(result);
|
|
3943
4629
|
});
|
|
4630
|
+
context.registerOpenApiRoute({
|
|
4631
|
+
method: "put",
|
|
4632
|
+
path: `/${options.mutationRouteSegment}`,
|
|
4633
|
+
operationId: `${modelName}.upsertAdvanced`,
|
|
4634
|
+
summary: `Advanced upsert a ${modelName} document`,
|
|
4635
|
+
query: requestSchemas.upsertQuery,
|
|
4636
|
+
body: defineOpenApiSchemaResolver(getAdvancedUpsertOpenApiBody)
|
|
4637
|
+
});
|
|
3944
4638
|
router.delete(`/:${options.idParam}`, async (req) => {
|
|
3945
4639
|
await context.assertAllowed(req, "delete");
|
|
3946
4640
|
const id = parsePathParam(req.params[options.idParam], options.idParam);
|
|
@@ -3949,6 +4643,12 @@ function setModelDocumentRoutes(context) {
|
|
|
3949
4643
|
handleResultError(result);
|
|
3950
4644
|
return unwrapServiceData(result);
|
|
3951
4645
|
});
|
|
4646
|
+
context.registerOpenApiRoute({
|
|
4647
|
+
method: "delete",
|
|
4648
|
+
path: `/:${options.idParam}`,
|
|
4649
|
+
operationId: `${modelName}.delete`,
|
|
4650
|
+
summary: `Delete a ${modelName} document`
|
|
4651
|
+
});
|
|
3952
4652
|
router.get("/distinct/:field", async (req) => {
|
|
3953
4653
|
await context.assertAllowed(req, "distinct");
|
|
3954
4654
|
const field = parsePathParam(req.params.field, "field");
|
|
@@ -3957,10 +4657,16 @@ function setModelDocumentRoutes(context) {
|
|
|
3957
4657
|
handleResultError(result);
|
|
3958
4658
|
return unwrapServiceData(result);
|
|
3959
4659
|
});
|
|
4660
|
+
context.registerOpenApiRoute({
|
|
4661
|
+
method: "get",
|
|
4662
|
+
path: "/distinct/:field",
|
|
4663
|
+
operationId: `${modelName}.distinct`,
|
|
4664
|
+
summary: `Get distinct values for a ${modelName} field`
|
|
4665
|
+
});
|
|
3960
4666
|
router.post("/distinct/:field", async (req) => {
|
|
3961
4667
|
await context.assertAllowed(req, "distinct");
|
|
3962
4668
|
const field = parsePathParam(req.params.field, "field");
|
|
3963
|
-
const { filter: filter2 } = parseBodyWithSchema(
|
|
4669
|
+
const { filter: filter2 } = await parseBodyWithSchema(
|
|
3964
4670
|
distinctBodySchema,
|
|
3965
4671
|
req.body,
|
|
3966
4672
|
context.getRequestSchema("requestSchemas.distinct")
|
|
@@ -3970,6 +4676,13 @@ function setModelDocumentRoutes(context) {
|
|
|
3970
4676
|
handleResultError(result);
|
|
3971
4677
|
return unwrapServiceData(result);
|
|
3972
4678
|
});
|
|
4679
|
+
context.registerOpenApiRoute({
|
|
4680
|
+
method: "post",
|
|
4681
|
+
path: "/distinct/:field",
|
|
4682
|
+
operationId: `${modelName}.distinctWithFilter`,
|
|
4683
|
+
summary: `Get distinct values for a ${modelName} field with a filter`,
|
|
4684
|
+
body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.distinct") ?? distinctBodySchema)
|
|
4685
|
+
});
|
|
3973
4686
|
}
|
|
3974
4687
|
|
|
3975
4688
|
// src/routers/model-router-subdocument-routes.ts
|
|
@@ -3986,12 +4699,18 @@ function setModelSubDocumentRoutes(context) {
|
|
|
3986
4699
|
handleResultError(result);
|
|
3987
4700
|
return unwrapServiceData(result);
|
|
3988
4701
|
});
|
|
4702
|
+
context.registerOpenApiRoute({
|
|
4703
|
+
method: "get",
|
|
4704
|
+
path: `/:${context.options.idParam}/${sub}`,
|
|
4705
|
+
operationId: `${context.modelName}.${sub}.list`,
|
|
4706
|
+
summary: `List ${sub} subdocuments`
|
|
4707
|
+
});
|
|
3989
4708
|
context.router.post(
|
|
3990
4709
|
`/:${context.options.idParam}/${sub}/${context.options.queryRouteSegment}`,
|
|
3991
4710
|
async (req) => {
|
|
3992
4711
|
await context.assertAllowed(req, `subs.${sub}.list`);
|
|
3993
4712
|
const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
|
|
3994
|
-
const body = parseBodyWithSchema(
|
|
4713
|
+
const body = await parseBodyWithSchema(
|
|
3995
4714
|
subListBodySchema,
|
|
3996
4715
|
req.body,
|
|
3997
4716
|
context.getRequestSchema("requestSchemas.subList")
|
|
@@ -4002,10 +4721,17 @@ function setModelSubDocumentRoutes(context) {
|
|
|
4002
4721
|
return unwrapServiceData(result);
|
|
4003
4722
|
}
|
|
4004
4723
|
);
|
|
4724
|
+
context.registerOpenApiRoute({
|
|
4725
|
+
method: "post",
|
|
4726
|
+
path: `/:${context.options.idParam}/${sub}/${context.options.queryRouteSegment}`,
|
|
4727
|
+
operationId: `${context.modelName}.${sub}.listAdvanced`,
|
|
4728
|
+
summary: `Advanced list ${sub} subdocuments`,
|
|
4729
|
+
body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.subList") ?? subListBodySchema)
|
|
4730
|
+
});
|
|
4005
4731
|
context.router.patch(`/:${context.options.idParam}/${sub}`, async (req) => {
|
|
4006
4732
|
await context.assertAllowed(req, `subs.${sub}.update`);
|
|
4007
4733
|
const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
|
|
4008
|
-
const data = parseBodyWithSchema(
|
|
4734
|
+
const data = await parseBodyWithSchema(
|
|
4009
4735
|
subMutationBodySchema,
|
|
4010
4736
|
req.body,
|
|
4011
4737
|
context.getRequestSchema("requestSchemas.subBulkUpdate")
|
|
@@ -4015,6 +4741,15 @@ function setModelSubDocumentRoutes(context) {
|
|
|
4015
4741
|
handleResultError(result);
|
|
4016
4742
|
return unwrapServiceData(result);
|
|
4017
4743
|
});
|
|
4744
|
+
context.registerOpenApiRoute({
|
|
4745
|
+
method: "patch",
|
|
4746
|
+
path: `/:${context.options.idParam}/${sub}`,
|
|
4747
|
+
operationId: `${context.modelName}.${sub}.bulkUpdate`,
|
|
4748
|
+
summary: `Bulk update ${sub} subdocuments`,
|
|
4749
|
+
body: defineOpenApiSchemaResolver(
|
|
4750
|
+
() => context.getRequestSchema("requestSchemas.subBulkUpdate") ?? subMutationBodySchema
|
|
4751
|
+
)
|
|
4752
|
+
});
|
|
4018
4753
|
context.router.get(`/:${context.options.idParam}/${sub}/:subId`, async (req) => {
|
|
4019
4754
|
await context.assertAllowed(req, `subs.${sub}.read`);
|
|
4020
4755
|
const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
|
|
@@ -4024,13 +4759,19 @@ function setModelSubDocumentRoutes(context) {
|
|
|
4024
4759
|
handleResultError(result);
|
|
4025
4760
|
return unwrapServiceData(result);
|
|
4026
4761
|
});
|
|
4762
|
+
context.registerOpenApiRoute({
|
|
4763
|
+
method: "get",
|
|
4764
|
+
path: `/:${context.options.idParam}/${sub}/:subId`,
|
|
4765
|
+
operationId: `${context.modelName}.${sub}.read`,
|
|
4766
|
+
summary: `Read a ${sub} subdocument`
|
|
4767
|
+
});
|
|
4027
4768
|
context.router.post(
|
|
4028
4769
|
`/:${context.options.idParam}/${sub}/:subId/${context.options.queryRouteSegment}`,
|
|
4029
4770
|
async (req) => {
|
|
4030
4771
|
await context.assertAllowed(req, `subs.${sub}.read`);
|
|
4031
4772
|
const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
|
|
4032
4773
|
const subId = parsePathParam(req.params.subId, "subId");
|
|
4033
|
-
const body = parseBodyWithSchema(
|
|
4774
|
+
const body = await parseBodyWithSchema(
|
|
4034
4775
|
subReadBodySchema,
|
|
4035
4776
|
req.body,
|
|
4036
4777
|
context.getRequestSchema("requestSchemas.subRead")
|
|
@@ -4043,11 +4784,18 @@ function setModelSubDocumentRoutes(context) {
|
|
|
4043
4784
|
return unwrapServiceData(result);
|
|
4044
4785
|
}
|
|
4045
4786
|
);
|
|
4787
|
+
context.registerOpenApiRoute({
|
|
4788
|
+
method: "post",
|
|
4789
|
+
path: `/:${context.options.idParam}/${sub}/:subId/${context.options.queryRouteSegment}`,
|
|
4790
|
+
operationId: `${context.modelName}.${sub}.readAdvanced`,
|
|
4791
|
+
summary: `Advanced read a ${sub} subdocument`,
|
|
4792
|
+
body: defineOpenApiSchemaResolver(() => context.getRequestSchema("requestSchemas.subRead") ?? subReadBodySchema)
|
|
4793
|
+
});
|
|
4046
4794
|
context.router.patch(`/:${context.options.idParam}/${sub}/:subId`, async (req) => {
|
|
4047
4795
|
await context.assertAllowed(req, `subs.${sub}.update`);
|
|
4048
4796
|
const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
|
|
4049
4797
|
const subId = parsePathParam(req.params.subId, "subId");
|
|
4050
|
-
const data = parseBodyWithSchema(
|
|
4798
|
+
const data = await parseBodyWithSchema(
|
|
4051
4799
|
subMutationBodySchema,
|
|
4052
4800
|
req.body,
|
|
4053
4801
|
context.getRequestSchema("requestSchemas.subUpdate")
|
|
@@ -4057,10 +4805,19 @@ function setModelSubDocumentRoutes(context) {
|
|
|
4057
4805
|
handleResultError(result);
|
|
4058
4806
|
return unwrapServiceData(result);
|
|
4059
4807
|
});
|
|
4808
|
+
context.registerOpenApiRoute({
|
|
4809
|
+
method: "patch",
|
|
4810
|
+
path: `/:${context.options.idParam}/${sub}/:subId`,
|
|
4811
|
+
operationId: `${context.modelName}.${sub}.update`,
|
|
4812
|
+
summary: `Update a ${sub} subdocument`,
|
|
4813
|
+
body: defineOpenApiSchemaResolver(
|
|
4814
|
+
() => context.getRequestSchema("requestSchemas.subUpdate") ?? subMutationBodySchema
|
|
4815
|
+
)
|
|
4816
|
+
});
|
|
4060
4817
|
context.router.post(`/:${context.options.idParam}/${sub}`, async (req) => {
|
|
4061
4818
|
await context.assertAllowed(req, `subs.${sub}.create`);
|
|
4062
4819
|
const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
|
|
4063
|
-
const data = parseBodyWithSchema(
|
|
4820
|
+
const data = await parseBodyWithSchema(
|
|
4064
4821
|
subMutationBodySchema,
|
|
4065
4822
|
req.body,
|
|
4066
4823
|
context.getRequestSchema("requestSchemas.subCreate")
|
|
@@ -4070,6 +4827,15 @@ function setModelSubDocumentRoutes(context) {
|
|
|
4070
4827
|
handleResultError(result);
|
|
4071
4828
|
return formatModelCreatedResponse(result);
|
|
4072
4829
|
});
|
|
4830
|
+
context.registerOpenApiRoute({
|
|
4831
|
+
method: "post",
|
|
4832
|
+
path: `/:${context.options.idParam}/${sub}`,
|
|
4833
|
+
operationId: `${context.modelName}.${sub}.create`,
|
|
4834
|
+
summary: `Create a ${sub} subdocument`,
|
|
4835
|
+
body: defineOpenApiSchemaResolver(
|
|
4836
|
+
() => context.getRequestSchema("requestSchemas.subCreate") ?? subMutationBodySchema
|
|
4837
|
+
)
|
|
4838
|
+
});
|
|
4073
4839
|
context.router.delete(`/:${context.options.idParam}/${sub}/:subId`, async (req) => {
|
|
4074
4840
|
await context.assertAllowed(req, `subs.${sub}.delete`);
|
|
4075
4841
|
const id = parsePathParam(req.params[context.options.idParam], context.options.idParam);
|
|
@@ -4079,9 +4845,25 @@ function setModelSubDocumentRoutes(context) {
|
|
|
4079
4845
|
handleResultError(result);
|
|
4080
4846
|
return unwrapServiceData(result);
|
|
4081
4847
|
});
|
|
4848
|
+
context.registerOpenApiRoute({
|
|
4849
|
+
method: "delete",
|
|
4850
|
+
path: `/:${context.options.idParam}/${sub}/:subId`,
|
|
4851
|
+
operationId: `${context.modelName}.${sub}.delete`,
|
|
4852
|
+
summary: `Delete a ${sub} subdocument`
|
|
4853
|
+
});
|
|
4082
4854
|
}
|
|
4083
4855
|
}
|
|
4084
4856
|
|
|
4857
|
+
// src/openapi/route-registration.ts
|
|
4858
|
+
import { normalizeUrlPath } from "@web-ts-toolkit/utils";
|
|
4859
|
+
function registerOpenApiRoute(runtime, basePath, defaultTag, route) {
|
|
4860
|
+
runtime.registerOpenApiRoute({
|
|
4861
|
+
...route,
|
|
4862
|
+
path: normalizeUrlPath(basePath + route.path),
|
|
4863
|
+
tags: route.tags ?? [defaultTag]
|
|
4864
|
+
});
|
|
4865
|
+
}
|
|
4866
|
+
|
|
4085
4867
|
// src/routers/model-router.ts
|
|
4086
4868
|
var clientErrors2 = JsonRouter5.clientErrors;
|
|
4087
4869
|
function setOption(parentKey, optionKey, option) {
|
|
@@ -4247,7 +5029,7 @@ var ModelRouter = class {
|
|
|
4247
5029
|
this.runtime.setModelOptions(modelName, initialOptions);
|
|
4248
5030
|
attachRuntimeToModel(modelName, this.runtime);
|
|
4249
5031
|
this.options = this.runtime.getModelOptions(modelName);
|
|
4250
|
-
this.fullBasePath =
|
|
5032
|
+
this.fullBasePath = normalizeUrlPath2(this.options.parentPath + this.options.basePath);
|
|
4251
5033
|
this.modelName = modelName;
|
|
4252
5034
|
this.router = new JsonRouter5(this.options.basePath, createSetCore(this.runtime), accessRouterResponseHandler);
|
|
4253
5035
|
this.model = new model_default(modelName);
|
|
@@ -4272,6 +5054,9 @@ var ModelRouter = class {
|
|
|
4272
5054
|
const allowed = await req.macl.isAllowed(this.modelName, access);
|
|
4273
5055
|
if (!allowed) throw new clientErrors2.UnauthorizedError();
|
|
4274
5056
|
}
|
|
5057
|
+
registerOpenApiRoute(route) {
|
|
5058
|
+
registerOpenApiRoute(this.runtime, this.fullBasePath, this.modelName, route);
|
|
5059
|
+
}
|
|
4275
5060
|
///////////////////////
|
|
4276
5061
|
// Collection Routes //
|
|
4277
5062
|
///////////////////////
|
|
@@ -4282,7 +5067,8 @@ var ModelRouter = class {
|
|
|
4282
5067
|
options: this.options,
|
|
4283
5068
|
getRequestSchema: this.getRequestSchema.bind(this),
|
|
4284
5069
|
getPublicService: this.getPublicService.bind(this),
|
|
4285
|
-
assertAllowed: this.assertAllowed.bind(this)
|
|
5070
|
+
assertAllowed: this.assertAllowed.bind(this),
|
|
5071
|
+
registerOpenApiRoute: this.registerOpenApiRoute.bind(this)
|
|
4286
5072
|
});
|
|
4287
5073
|
}
|
|
4288
5074
|
/////////////////////
|
|
@@ -4295,7 +5081,8 @@ var ModelRouter = class {
|
|
|
4295
5081
|
options: this.options,
|
|
4296
5082
|
getRequestSchema: this.getRequestSchema.bind(this),
|
|
4297
5083
|
getPublicService: this.getPublicService.bind(this),
|
|
4298
|
-
assertAllowed: this.assertAllowed.bind(this)
|
|
5084
|
+
assertAllowed: this.assertAllowed.bind(this),
|
|
5085
|
+
registerOpenApiRoute: this.registerOpenApiRoute.bind(this)
|
|
4299
5086
|
});
|
|
4300
5087
|
}
|
|
4301
5088
|
/////////////////////////
|
|
@@ -4308,13 +5095,14 @@ var ModelRouter = class {
|
|
|
4308
5095
|
options: this.options,
|
|
4309
5096
|
getRequestSchema: this.getRequestSchema.bind(this),
|
|
4310
5097
|
getPublicService: this.getPublicService.bind(this),
|
|
4311
|
-
assertAllowed: this.assertAllowed.bind(this)
|
|
5098
|
+
assertAllowed: this.assertAllowed.bind(this),
|
|
5099
|
+
registerOpenApiRoute: this.registerOpenApiRoute.bind(this)
|
|
4312
5100
|
});
|
|
4313
5101
|
}
|
|
4314
5102
|
logEndpoints() {
|
|
4315
5103
|
runWithRuntime(this.runtime, () => {
|
|
4316
|
-
|
|
4317
|
-
logger.info(`${padEnd(method, 6)} ${
|
|
5104
|
+
forEach8(this.router.endpoints, ({ method, path }) => {
|
|
5105
|
+
logger.info(`${padEnd(method, 6)} ${normalizeUrlPath2(this.options.parentPath + path)}`);
|
|
4318
5106
|
});
|
|
4319
5107
|
});
|
|
4320
5108
|
}
|
|
@@ -4327,7 +5115,7 @@ var ModelRouter = class {
|
|
|
4327
5115
|
value
|
|
4328
5116
|
);
|
|
4329
5117
|
}
|
|
4330
|
-
if (arguments.length === 1 &&
|
|
5118
|
+
if (arguments.length === 1 && isPlainObject12(keyOrOptions)) {
|
|
4331
5119
|
assertMutableRouterOptions("model", keyOrOptions);
|
|
4332
5120
|
this.runtime.setModelOptions(this.modelName, keyOrOptions);
|
|
4333
5121
|
}
|
|
@@ -4350,7 +5138,7 @@ var ModelRouter = class {
|
|
|
4350
5138
|
|
|
4351
5139
|
// src/routers/root-router.ts
|
|
4352
5140
|
import JsonRouter6 from "@web-ts-toolkit/express-json-router";
|
|
4353
|
-
import { isNumber as _isNumber, isString as isString10, orderBy as _orderBy } from "@web-ts-toolkit/utils";
|
|
5141
|
+
import { isNumber as _isNumber, isString as isString10, normalizeUrlPath as normalizeUrlPath3, orderBy as _orderBy } from "@web-ts-toolkit/utils";
|
|
4354
5142
|
|
|
4355
5143
|
// src/core-data.ts
|
|
4356
5144
|
var DataCore = class {
|
|
@@ -4596,6 +5384,9 @@ var RootRouter = class {
|
|
|
4596
5384
|
);
|
|
4597
5385
|
this.setRoutes();
|
|
4598
5386
|
}
|
|
5387
|
+
registerOpenApiRoute(route) {
|
|
5388
|
+
registerOpenApiRoute(this.runtime, normalizeUrlPath3(this.basename), "root", route);
|
|
5389
|
+
}
|
|
4599
5390
|
wrapResult(index, item, result) {
|
|
4600
5391
|
return {
|
|
4601
5392
|
index,
|
|
@@ -4681,6 +5472,13 @@ var RootRouter = class {
|
|
|
4681
5472
|
}
|
|
4682
5473
|
return _orderBy(results, ["index"], ["asc"]);
|
|
4683
5474
|
});
|
|
5475
|
+
this.registerOpenApiRoute({
|
|
5476
|
+
method: "post",
|
|
5477
|
+
path: "",
|
|
5478
|
+
operationId: "root.query",
|
|
5479
|
+
summary: "Execute batched model and data operations",
|
|
5480
|
+
body: rootQuerySchema
|
|
5481
|
+
});
|
|
4684
5482
|
}
|
|
4685
5483
|
get routes() {
|
|
4686
5484
|
return this.router.original;
|
|
@@ -4689,7 +5487,7 @@ var RootRouter = class {
|
|
|
4689
5487
|
|
|
4690
5488
|
// src/routers/data-router.ts
|
|
4691
5489
|
import JsonRouter7 from "@web-ts-toolkit/express-json-router";
|
|
4692
|
-
import { isPlainObject as
|
|
5490
|
+
import { isPlainObject as isPlainObject13, isString as isString11, isUndefined as isUndefined3, normalizeUrlPath as normalizeUrlPath4 } from "@web-ts-toolkit/utils";
|
|
4693
5491
|
var clientErrors4 = JsonRouter7.clientErrors;
|
|
4694
5492
|
function setOption2(parentKey, optionKey, option) {
|
|
4695
5493
|
const key = isUndefined3(option) ? parentKey : `${parentKey}.${optionKey}`;
|
|
@@ -4729,7 +5527,7 @@ var DataRouter = class {
|
|
|
4729
5527
|
this.runtime = runtime;
|
|
4730
5528
|
this.runtime.setDataOptions(dataName, initialOptions);
|
|
4731
5529
|
this.options = this.runtime.getDataOptions(dataName);
|
|
4732
|
-
this.fullBasePath =
|
|
5530
|
+
this.fullBasePath = normalizeUrlPath4(this.options.parentPath + this.options.basePath);
|
|
4733
5531
|
this.dataName = dataName;
|
|
4734
5532
|
this.router = new JsonRouter7(this.options.basePath, createSetDataCore(this.runtime), accessRouterResponseHandler);
|
|
4735
5533
|
this.setCollectionRoutes();
|
|
@@ -4748,6 +5546,9 @@ var DataRouter = class {
|
|
|
4748
5546
|
const allowed = await req.dacl.isAllowed(this.dataName, access);
|
|
4749
5547
|
if (!allowed) throw new clientErrors4.UnauthorizedError();
|
|
4750
5548
|
}
|
|
5549
|
+
registerOpenApiRoute(route) {
|
|
5550
|
+
registerOpenApiRoute(this.runtime, this.fullBasePath, this.dataName, route);
|
|
5551
|
+
}
|
|
4751
5552
|
///////////////////////
|
|
4752
5553
|
// Collection Routes //
|
|
4753
5554
|
///////////////////////
|
|
@@ -4772,6 +5573,13 @@ var DataRouter = class {
|
|
|
4772
5573
|
const decoratedResult = await decorateDataListResult(svc, result);
|
|
4773
5574
|
return formatListResponse(req, decoratedResult, includeCount, includeExtraHeaders);
|
|
4774
5575
|
});
|
|
5576
|
+
this.registerOpenApiRoute({
|
|
5577
|
+
method: "get",
|
|
5578
|
+
path: "",
|
|
5579
|
+
operationId: `${this.dataName}.list`,
|
|
5580
|
+
summary: `List ${this.dataName} records`,
|
|
5581
|
+
query: requestSchemas.listQuery
|
|
5582
|
+
});
|
|
4775
5583
|
this.router.post(`/${this.options.queryRouteSegment}`, async (req) => {
|
|
4776
5584
|
await this.assertAllowed(req, "list");
|
|
4777
5585
|
let {
|
|
@@ -4783,7 +5591,7 @@ var DataRouter = class {
|
|
|
4783
5591
|
page,
|
|
4784
5592
|
pageSize,
|
|
4785
5593
|
options = {}
|
|
4786
|
-
} = parseBodyWithSchema(dataListBodySchema, req.body, this.getRequestSchema("requestSchemas.advancedList"));
|
|
5594
|
+
} = await parseBodyWithSchema(dataListBodySchema, req.body, this.getRequestSchema("requestSchemas.advancedList"));
|
|
4787
5595
|
const { includeCount, includeExtraHeaders } = options;
|
|
4788
5596
|
const svc = this.getService(req);
|
|
4789
5597
|
const result = await svc.find(
|
|
@@ -4795,6 +5603,15 @@ var DataRouter = class {
|
|
|
4795
5603
|
const decoratedResult = await decorateDataListResult(svc, result);
|
|
4796
5604
|
return formatListResponse(req, decoratedResult, includeCount, includeExtraHeaders);
|
|
4797
5605
|
});
|
|
5606
|
+
this.registerOpenApiRoute({
|
|
5607
|
+
method: "post",
|
|
5608
|
+
path: `/${this.options.queryRouteSegment}`,
|
|
5609
|
+
operationId: `${this.dataName}.listAdvanced`,
|
|
5610
|
+
summary: `Advanced list ${this.dataName} records`,
|
|
5611
|
+
body: defineOpenApiSchemaResolver(
|
|
5612
|
+
() => this.getRequestSchema("requestSchemas.advancedList") ?? dataListBodySchema
|
|
5613
|
+
)
|
|
5614
|
+
});
|
|
4798
5615
|
}
|
|
4799
5616
|
/////////////////////
|
|
4800
5617
|
// Document Routes //
|
|
@@ -4809,9 +5626,15 @@ var DataRouter = class {
|
|
|
4809
5626
|
const decoratedResult = await decorateDataSingleResult(svc, result);
|
|
4810
5627
|
return decoratedResult.data;
|
|
4811
5628
|
});
|
|
5629
|
+
this.registerOpenApiRoute({
|
|
5630
|
+
method: "get",
|
|
5631
|
+
path: `/:${this.options.idParam}`,
|
|
5632
|
+
operationId: `${this.dataName}.read`,
|
|
5633
|
+
summary: `Read a ${this.dataName} record`
|
|
5634
|
+
});
|
|
4812
5635
|
this.router.post(`/${this.options.queryRouteSegment}/__filter`, async (req) => {
|
|
4813
5636
|
await this.assertAllowed(req, "read");
|
|
4814
|
-
let { filter: filter2, select } = parseBodyWithSchema(
|
|
5637
|
+
let { filter: filter2, select } = await parseBodyWithSchema(
|
|
4815
5638
|
dataReadFilterBodySchema,
|
|
4816
5639
|
req.body,
|
|
4817
5640
|
this.getRequestSchema("requestSchemas.advancedReadFilter")
|
|
@@ -4822,10 +5645,19 @@ var DataRouter = class {
|
|
|
4822
5645
|
const decoratedResult = await decorateDataSingleResult(svc, result);
|
|
4823
5646
|
return decoratedResult.data;
|
|
4824
5647
|
});
|
|
5648
|
+
this.registerOpenApiRoute({
|
|
5649
|
+
method: "post",
|
|
5650
|
+
path: `/${this.options.queryRouteSegment}/__filter`,
|
|
5651
|
+
operationId: `${this.dataName}.readByFilter`,
|
|
5652
|
+
summary: `Read a ${this.dataName} record by filter`,
|
|
5653
|
+
body: defineOpenApiSchemaResolver(
|
|
5654
|
+
() => this.getRequestSchema("requestSchemas.advancedReadFilter") ?? dataReadFilterBodySchema
|
|
5655
|
+
)
|
|
5656
|
+
});
|
|
4825
5657
|
this.router.post(`/${this.options.queryRouteSegment}/:${this.options.idParam}`, async (req) => {
|
|
4826
5658
|
await this.assertAllowed(req, "read");
|
|
4827
5659
|
const id = parsePathParam(req.params[this.options.idParam], this.options.idParam);
|
|
4828
|
-
let { select } = parseBodyWithSchema(
|
|
5660
|
+
let { select } = await parseBodyWithSchema(
|
|
4829
5661
|
dataReadByIdBodySchema,
|
|
4830
5662
|
req.body,
|
|
4831
5663
|
this.getRequestSchema("requestSchemas.advancedRead")
|
|
@@ -4836,13 +5668,22 @@ var DataRouter = class {
|
|
|
4836
5668
|
const decoratedResult = await decorateDataSingleResult(svc, result);
|
|
4837
5669
|
return decoratedResult.data;
|
|
4838
5670
|
});
|
|
5671
|
+
this.registerOpenApiRoute({
|
|
5672
|
+
method: "post",
|
|
5673
|
+
path: `/${this.options.queryRouteSegment}/:${this.options.idParam}`,
|
|
5674
|
+
operationId: `${this.dataName}.readAdvanced`,
|
|
5675
|
+
summary: `Advanced read a ${this.dataName} record`,
|
|
5676
|
+
body: defineOpenApiSchemaResolver(
|
|
5677
|
+
() => this.getRequestSchema("requestSchemas.advancedRead") ?? dataReadByIdBodySchema
|
|
5678
|
+
)
|
|
5679
|
+
});
|
|
4839
5680
|
}
|
|
4840
5681
|
set(keyOrOptions, value) {
|
|
4841
5682
|
if (arguments.length === 2 && isString11(keyOrOptions)) {
|
|
4842
5683
|
assertMutableRouterOption("data", keyOrOptions);
|
|
4843
5684
|
this.runtime.setDataOption(this.dataName, keyOrOptions, value);
|
|
4844
5685
|
}
|
|
4845
|
-
if (arguments.length === 1 &&
|
|
5686
|
+
if (arguments.length === 1 && isPlainObject13(keyOrOptions)) {
|
|
4846
5687
|
assertMutableRouterOptions("data", keyOrOptions);
|
|
4847
5688
|
this.runtime.setDataOptions(this.dataName, keyOrOptions);
|
|
4848
5689
|
}
|
|
@@ -4865,6 +5706,62 @@ var DataRouter = class {
|
|
|
4865
5706
|
|
|
4866
5707
|
// src/routers/index.ts
|
|
4867
5708
|
import JsonRouter8 from "@web-ts-toolkit/express-json-router";
|
|
5709
|
+
|
|
5710
|
+
// src/openapi/router.ts
|
|
5711
|
+
import express from "express";
|
|
5712
|
+
import { posix } from "path";
|
|
5713
|
+
var escapeHtml = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
5714
|
+
var renderDocsHtml = (specPath, title, cssUrl, bundleUrl) => `<!doctype html>
|
|
5715
|
+
<html lang="en">
|
|
5716
|
+
<head>
|
|
5717
|
+
<meta charset="utf-8" />
|
|
5718
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
5719
|
+
<title>${escapeHtml(title)}</title>
|
|
5720
|
+
<link rel="stylesheet" href="${escapeHtml(cssUrl)}" />
|
|
5721
|
+
</head>
|
|
5722
|
+
<body>
|
|
5723
|
+
<div id="swagger-ui"></div>
|
|
5724
|
+
<script src="${escapeHtml(bundleUrl)}"></script>
|
|
5725
|
+
<script>
|
|
5726
|
+
window.ui = SwaggerUIBundle({
|
|
5727
|
+
url: ${JSON.stringify(specPath)},
|
|
5728
|
+
dom_id: '#swagger-ui',
|
|
5729
|
+
deepLinking: true,
|
|
5730
|
+
presets: [SwaggerUIBundle.presets.apis],
|
|
5731
|
+
layout: 'BaseLayout',
|
|
5732
|
+
});
|
|
5733
|
+
</script>
|
|
5734
|
+
</body>
|
|
5735
|
+
</html>`;
|
|
5736
|
+
var getRelativeSpecPath = (docsPath, jsonPath) => {
|
|
5737
|
+
const docsDir = posix.dirname(docsPath.startsWith("/") ? docsPath : `/${docsPath}`);
|
|
5738
|
+
const normalizedJsonPath = jsonPath.startsWith("/") ? jsonPath : `/${jsonPath}`;
|
|
5739
|
+
return posix.relative(docsDir, normalizedJsonPath) || posix.basename(normalizedJsonPath);
|
|
5740
|
+
};
|
|
5741
|
+
function createOpenApiRouter(runtime, options = {}) {
|
|
5742
|
+
const router = express.Router();
|
|
5743
|
+
const jsonPath = options.jsonPath ?? "/openapi.json";
|
|
5744
|
+
const docsPath = options.docsPath ?? "/docs";
|
|
5745
|
+
const swaggerUiCssUrl = options.swaggerUiCssUrl ?? "https://unpkg.com/swagger-ui-dist@5/swagger-ui.css";
|
|
5746
|
+
const swaggerUiBundleUrl = options.swaggerUiBundleUrl ?? "https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js";
|
|
5747
|
+
const info = {
|
|
5748
|
+
title: options.title ?? "Access Router API",
|
|
5749
|
+
version: options.version ?? "0.0.0",
|
|
5750
|
+
description: options.description,
|
|
5751
|
+
servers: options.servers
|
|
5752
|
+
};
|
|
5753
|
+
router.get(jsonPath, (_req, res) => {
|
|
5754
|
+
res.json(runtime.getOpenApiSpec(info));
|
|
5755
|
+
});
|
|
5756
|
+
if (docsPath !== false) {
|
|
5757
|
+
router.get(docsPath, (_req, res) => {
|
|
5758
|
+
res.type("html").send(renderDocsHtml(getRelativeSpecPath(docsPath, jsonPath), info.title, swaggerUiCssUrl, swaggerUiBundleUrl));
|
|
5759
|
+
});
|
|
5760
|
+
}
|
|
5761
|
+
return router;
|
|
5762
|
+
}
|
|
5763
|
+
|
|
5764
|
+
// src/routers/index.ts
|
|
4868
5765
|
var hasRoutes = (input) => {
|
|
4869
5766
|
return typeof input === "object" && input !== null && "routes" in input;
|
|
4870
5767
|
};
|
|
@@ -4872,7 +5769,7 @@ var resolveRoutes = (input) => {
|
|
|
4872
5769
|
return hasRoutes(input) ? input.routes : input;
|
|
4873
5770
|
};
|
|
4874
5771
|
function combineRoutes(...inputs) {
|
|
4875
|
-
const router =
|
|
5772
|
+
const router = express2.Router();
|
|
4876
5773
|
inputs.forEach((input) => {
|
|
4877
5774
|
router.use(resolveRoutes(input));
|
|
4878
5775
|
});
|
|
@@ -4884,7 +5781,7 @@ var accessRouterResponseHandler = JsonRouter8.createHandler({
|
|
|
4884
5781
|
});
|
|
4885
5782
|
accessRouterResponseHandler.errorMessageProvider = function(error) {
|
|
4886
5783
|
const errorLike = error;
|
|
4887
|
-
|
|
5784
|
+
logger.error(error);
|
|
4888
5785
|
return errorLike.message || errorLike._message || String(error);
|
|
4889
5786
|
};
|
|
4890
5787
|
|
|
@@ -4911,12 +5808,15 @@ function createRuntimeApi(runtime) {
|
|
|
4911
5808
|
wtt2.createDataRouter = function(dataName, options) {
|
|
4912
5809
|
return new DataRouter(dataName, options, runtime);
|
|
4913
5810
|
};
|
|
5811
|
+
wtt2.createOpenApiRouter = function(options) {
|
|
5812
|
+
return createOpenApiRouter(runtime, options);
|
|
5813
|
+
};
|
|
4914
5814
|
wtt2.combineRoutes = combineRoutes;
|
|
4915
5815
|
wtt2.set = function(keyOrOptions, value) {
|
|
4916
5816
|
if (arguments.length === 2 && isString12(keyOrOptions)) {
|
|
4917
5817
|
return runtime.setGlobalOption(keyOrOptions, value);
|
|
4918
5818
|
}
|
|
4919
|
-
if (arguments.length === 1 &&
|
|
5819
|
+
if (arguments.length === 1 && isPlainObject14(keyOrOptions)) {
|
|
4920
5820
|
return runtime.setGlobalOptions(keyOrOptions);
|
|
4921
5821
|
}
|
|
4922
5822
|
};
|
|
@@ -4953,7 +5853,19 @@ export {
|
|
|
4953
5853
|
acl,
|
|
4954
5854
|
combineRoutes,
|
|
4955
5855
|
createAccessRuntime,
|
|
5856
|
+
createOpenApiRouter,
|
|
4956
5857
|
index_default as default,
|
|
5858
|
+
defineRequestSchema,
|
|
5859
|
+
fromAjv,
|
|
5860
|
+
fromArkType,
|
|
5861
|
+
fromIoTs,
|
|
5862
|
+
fromJoi,
|
|
5863
|
+
fromStandardSchema,
|
|
5864
|
+
fromSuperstruct,
|
|
5865
|
+
fromValibot,
|
|
5866
|
+
fromVine,
|
|
5867
|
+
fromYup,
|
|
5868
|
+
fromZod,
|
|
4957
5869
|
getDefaultModelOption,
|
|
4958
5870
|
getDefaultModelOptions,
|
|
4959
5871
|
getGlobalOption,
|