@web-ts-toolkit/access-router 0.44.0 → 0.46.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 +323 -2
- package/advanced.d.mts +655 -19
- package/advanced.d.ts +655 -19
- package/advanced.js +362 -22
- package/advanced.mjs +364 -23
- package/index.d.mts +5 -186
- package/index.d.ts +5 -186
- package/index.js +1783 -263
- package/index.mjs +1702 -178
- package/llms.txt +83 -2
- package/package.json +3 -3
- package/{parsers-B5dbVmjm.d.mts → parsers-BKF7VX2-.d.mts} +417 -13
- package/{parsers-B5dbVmjm.d.ts → parsers-BKF7VX2-.d.ts} +417 -13
- package/processors.d.mts +151 -1
- package/processors.d.ts +151 -1
- package/processors.js +170 -6
- package/processors.mjs +165 -6
package/advanced.js
CHANGED
|
@@ -134,6 +134,12 @@ var import_utils8 = require("@web-ts-toolkit/utils");
|
|
|
134
134
|
var import_utils = require("@web-ts-toolkit/utils");
|
|
135
135
|
var DEFAULT_LIST_HARD_LIMIT = 1e3;
|
|
136
136
|
|
|
137
|
+
// src/helpers/sort-policy.ts
|
|
138
|
+
var fieldPathPattern = /^[A-Za-z_][A-Za-z0-9_$]*(\.[A-Za-z_][A-Za-z0-9_$]*)*$/;
|
|
139
|
+
function isValidFieldPath(field) {
|
|
140
|
+
return typeof field === "string" && fieldPathPattern.test(field);
|
|
141
|
+
}
|
|
142
|
+
|
|
137
143
|
// src/helpers/index.ts
|
|
138
144
|
var import_utils3 = require("@web-ts-toolkit/utils");
|
|
139
145
|
|
|
@@ -716,7 +722,9 @@ var defaultRequestComplexity = {
|
|
|
716
722
|
maxIncludeCount: 10,
|
|
717
723
|
maxSubQueryCount: 10,
|
|
718
724
|
maxBulkConcurrency: 10,
|
|
719
|
-
maxHookConcurrency: 10
|
|
725
|
+
maxHookConcurrency: 10,
|
|
726
|
+
maxCorrelatedQueries: 100,
|
|
727
|
+
maxCorrelatedDepth: 5
|
|
720
728
|
};
|
|
721
729
|
var normalizePositiveInteger = (value, fallback) => {
|
|
722
730
|
return Number.isSafeInteger(value) && Number(value) > 0 ? Number(value) : fallback;
|
|
@@ -736,6 +744,14 @@ var resolveRequestComplexity = (options) => ({
|
|
|
736
744
|
maxHookConcurrency: normalizePositiveInteger(
|
|
737
745
|
options?.maxHookConcurrency,
|
|
738
746
|
defaultRequestComplexity.maxHookConcurrency
|
|
747
|
+
),
|
|
748
|
+
maxCorrelatedQueries: normalizePositiveInteger(
|
|
749
|
+
options?.maxCorrelatedQueries,
|
|
750
|
+
defaultRequestComplexity.maxCorrelatedQueries
|
|
751
|
+
),
|
|
752
|
+
maxCorrelatedDepth: normalizePositiveInteger(
|
|
753
|
+
options?.maxCorrelatedDepth,
|
|
754
|
+
defaultRequestComplexity.maxCorrelatedDepth
|
|
739
755
|
)
|
|
740
756
|
});
|
|
741
757
|
function validateRequestComplexity(value, options, scope = "request") {
|
|
@@ -928,6 +944,7 @@ var AccessRuntime = class {
|
|
|
928
944
|
this.modelAtts = {};
|
|
929
945
|
this.modelInstances = {};
|
|
930
946
|
this.openApiRegistry = new OpenApiRegistry();
|
|
947
|
+
this.openApiPathPrefix = "";
|
|
931
948
|
this.allowGlobalModelLookup = options.allowGlobalModelLookup ?? false;
|
|
932
949
|
ensureMongooseJsonSchemaInitialized();
|
|
933
950
|
}
|
|
@@ -956,7 +973,24 @@ var AccessRuntime = class {
|
|
|
956
973
|
return global;
|
|
957
974
|
}
|
|
958
975
|
registerOpenApiRoute(route) {
|
|
959
|
-
this.openApiRegistry.register(
|
|
976
|
+
this.openApiRegistry.register(
|
|
977
|
+
this.openApiPathPrefix ? { ...route, path: (0, import_utils8.normalizeUrlPath)(`${this.openApiPathPrefix}/${route.path}`) } : route
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
981
|
+
* Compose OpenAPI paths while synchronously constructing mounted routers.
|
|
982
|
+
* Prefixes apply before collision checks; prior descriptors and Express paths
|
|
983
|
+
* are unchanged. Nested calls compose and the prior scope is restored even on
|
|
984
|
+
* failure. The callback must finish registration synchronously (no async work).
|
|
985
|
+
*/
|
|
986
|
+
withOpenApiPathPrefix(prefix, build) {
|
|
987
|
+
const previous = this.openApiPathPrefix;
|
|
988
|
+
this.openApiPathPrefix = (0, import_utils8.normalizeUrlPath)(`${previous}/${prefix}`);
|
|
989
|
+
try {
|
|
990
|
+
return build();
|
|
991
|
+
} finally {
|
|
992
|
+
this.openApiPathPrefix = previous;
|
|
993
|
+
}
|
|
960
994
|
}
|
|
961
995
|
/**
|
|
962
996
|
* Enable strict OpenAPI collision detection for the remainder of this
|
|
@@ -1244,6 +1278,175 @@ var getGlobalOption = (key, defaultValue) => {
|
|
|
1244
1278
|
|
|
1245
1279
|
// src/validation/common.ts
|
|
1246
1280
|
var import_zod2 = require("zod");
|
|
1281
|
+
var import_utils10 = require("@web-ts-toolkit/utils");
|
|
1282
|
+
|
|
1283
|
+
// src/correlated-includes.ts
|
|
1284
|
+
var import_utils9 = require("@web-ts-toolkit/utils");
|
|
1285
|
+
var PARENT_MARKER_KEY = "$parent";
|
|
1286
|
+
var ESCAPE_WRAPPER_KEY = "$escape";
|
|
1287
|
+
var SUBQUERY_PAYLOAD_KEYS = /* @__PURE__ */ new Set(["$$sq", "$$date"]);
|
|
1288
|
+
var MARKER_FORBIDDEN_OPERATOR_KEYS = /* @__PURE__ */ new Set(["$text", "$where", "$comment"]);
|
|
1289
|
+
var LOGICAL_CLAUSE_KEYS = /* @__PURE__ */ new Set(["$and", "$or", "$nor"]);
|
|
1290
|
+
var DANGEROUS_PATH_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
1291
|
+
var FIELD_SEGMENT_PATTERN = /^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
1292
|
+
var ARRAY_INDEX_SEGMENT_PATTERN = /^(0|[1-9]\d*)$/;
|
|
1293
|
+
var ownKeys = (value) => Object.keys(value);
|
|
1294
|
+
function isParentRefMarker(value) {
|
|
1295
|
+
return (0, import_utils9.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === PARENT_MARKER_KEY;
|
|
1296
|
+
}
|
|
1297
|
+
function isEscapedParentRef(value) {
|
|
1298
|
+
return (0, import_utils9.isPlainObject)(value) && ownKeys(value).length === 1 && ownKeys(value)[0] === ESCAPE_WRAPPER_KEY;
|
|
1299
|
+
}
|
|
1300
|
+
function hasMarkerKey(value) {
|
|
1301
|
+
return ownKeys(value).includes(PARENT_MARKER_KEY) || ownKeys(value).includes(ESCAPE_WRAPPER_KEY);
|
|
1302
|
+
}
|
|
1303
|
+
function isValidParentRefPath(path) {
|
|
1304
|
+
if (typeof path !== "string" || path.length === 0) return false;
|
|
1305
|
+
const segments = path.split(".");
|
|
1306
|
+
return segments.every(
|
|
1307
|
+
(segment) => (FIELD_SEGMENT_PATTERN.test(segment) || ARRAY_INDEX_SEGMENT_PATTERN.test(segment)) && !DANGEROUS_PATH_SEGMENTS.has(segment)
|
|
1308
|
+
);
|
|
1309
|
+
}
|
|
1310
|
+
function isValidCorrelatedOutputPath(path) {
|
|
1311
|
+
return typeof path === "string" && path.length > 0 && isValidFieldPath(path) && path !== "_id" && !path.startsWith("$");
|
|
1312
|
+
}
|
|
1313
|
+
function containsParentMarkerShape(value) {
|
|
1314
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1315
|
+
const visit = (current) => {
|
|
1316
|
+
if (isParentRefMarker(current) || isEscapedParentRef(current)) return true;
|
|
1317
|
+
if ((0, import_utils9.isArray)(current)) {
|
|
1318
|
+
if (seen.has(current)) return false;
|
|
1319
|
+
seen.add(current);
|
|
1320
|
+
return current.some(visit);
|
|
1321
|
+
}
|
|
1322
|
+
if ((0, import_utils9.isPlainObject)(current)) {
|
|
1323
|
+
if (seen.has(current)) return false;
|
|
1324
|
+
seen.add(current);
|
|
1325
|
+
if (hasMarkerKey(current)) return true;
|
|
1326
|
+
return Object.values(current).some(visit);
|
|
1327
|
+
}
|
|
1328
|
+
return false;
|
|
1329
|
+
};
|
|
1330
|
+
return visit(value);
|
|
1331
|
+
}
|
|
1332
|
+
function scanTemplateValueNode(value, path, issues) {
|
|
1333
|
+
if (isEscapedParentRef(value)) {
|
|
1334
|
+
const inner = value.$escape;
|
|
1335
|
+
if (!isParentRefMarker(inner) || typeof inner.$parent !== "string" || (inner.$parent?.length ?? 0) === 0) {
|
|
1336
|
+
issues.push({
|
|
1337
|
+
message: 'Invalid $escape payload: expected { "$escape": { "$parent": "<field>" } }',
|
|
1338
|
+
path
|
|
1339
|
+
});
|
|
1340
|
+
}
|
|
1341
|
+
return;
|
|
1342
|
+
}
|
|
1343
|
+
if (isParentRefMarker(value)) {
|
|
1344
|
+
if (!isValidParentRefPath(value.$parent)) {
|
|
1345
|
+
issues.push({
|
|
1346
|
+
message: `Invalid $parent reference path at ${path.length === 0 ? "#" : path.join(".")}`,
|
|
1347
|
+
path
|
|
1348
|
+
});
|
|
1349
|
+
}
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
if ((0, import_utils9.isPlainObject)(value)) {
|
|
1353
|
+
if (hasMarkerKey(value)) {
|
|
1354
|
+
issues.push({
|
|
1355
|
+
message: 'Malformed $parent reference: objects carrying $parent must be exactly { "$parent": "<field>" }',
|
|
1356
|
+
path
|
|
1357
|
+
});
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1360
|
+
scanTemplateObjectEntries(value, path, issues);
|
|
1361
|
+
return;
|
|
1362
|
+
}
|
|
1363
|
+
if ((0, import_utils9.isArray)(value)) {
|
|
1364
|
+
value.forEach((item, index) => scanTemplateValueNode(item, [...path, index], issues));
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
function scanTemplateObjectEntries(obj, basePath, issues) {
|
|
1368
|
+
for (const [key, child] of Object.entries(obj)) {
|
|
1369
|
+
const childPath = [...basePath, key];
|
|
1370
|
+
if (key === PARENT_MARKER_KEY) {
|
|
1371
|
+
issues.push({ message: "$parent is never a field name in correlated templates", path: childPath });
|
|
1372
|
+
continue;
|
|
1373
|
+
}
|
|
1374
|
+
if (SUBQUERY_PAYLOAD_KEYS.has(key)) {
|
|
1375
|
+
if (containsParentMarkerShape(child)) {
|
|
1376
|
+
issues.push({
|
|
1377
|
+
message: `Unsupported $parent reference inside ${key}: markers are not resolved in subquery payloads`,
|
|
1378
|
+
path: childPath
|
|
1379
|
+
});
|
|
1380
|
+
}
|
|
1381
|
+
continue;
|
|
1382
|
+
}
|
|
1383
|
+
if (MARKER_FORBIDDEN_OPERATOR_KEYS.has(key)) {
|
|
1384
|
+
if (containsParentMarkerShape(child)) {
|
|
1385
|
+
issues.push({
|
|
1386
|
+
message: `Unsupported $parent reference inside ${key}: markers are not resolved in ${key} values`,
|
|
1387
|
+
path: childPath
|
|
1388
|
+
});
|
|
1389
|
+
}
|
|
1390
|
+
continue;
|
|
1391
|
+
}
|
|
1392
|
+
if (key === "$elemMatch") {
|
|
1393
|
+
if (isParentRefMarker(child) || isEscapedParentRef(child)) {
|
|
1394
|
+
issues.push({
|
|
1395
|
+
message: "Unsupported $parent reference as a direct $elemMatch value",
|
|
1396
|
+
path: childPath
|
|
1397
|
+
});
|
|
1398
|
+
continue;
|
|
1399
|
+
}
|
|
1400
|
+
scanTemplateValueNode(child, childPath, issues);
|
|
1401
|
+
continue;
|
|
1402
|
+
}
|
|
1403
|
+
if (LOGICAL_CLAUSE_KEYS.has(key)) {
|
|
1404
|
+
if (!(0, import_utils9.isArray)(child)) {
|
|
1405
|
+
scanTemplateValueNode(child, childPath, issues);
|
|
1406
|
+
continue;
|
|
1407
|
+
}
|
|
1408
|
+
child.forEach((clause, index) => {
|
|
1409
|
+
const clausePath = [...childPath, index];
|
|
1410
|
+
if (isParentRefMarker(clause) || isEscapedParentRef(clause)) {
|
|
1411
|
+
issues.push({
|
|
1412
|
+
message: `Unsupported $parent reference as a direct ${key} clause: clauses must be filter objects`,
|
|
1413
|
+
path: clausePath
|
|
1414
|
+
});
|
|
1415
|
+
return;
|
|
1416
|
+
}
|
|
1417
|
+
if ((0, import_utils9.isPlainObject)(clause)) {
|
|
1418
|
+
scanTemplateObjectEntries(clause, clausePath, issues);
|
|
1419
|
+
}
|
|
1420
|
+
});
|
|
1421
|
+
continue;
|
|
1422
|
+
}
|
|
1423
|
+
scanTemplateValueNode(child, childPath, issues);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
function validateCorrelatedFilterTemplate(filter) {
|
|
1427
|
+
const issues = [];
|
|
1428
|
+
if (!(0, import_utils9.isPlainObject)(filter)) {
|
|
1429
|
+
issues.push({ message: "Correlated include filter must be an object", path: [] });
|
|
1430
|
+
return issues;
|
|
1431
|
+
}
|
|
1432
|
+
if (isParentRefMarker(filter) || isEscapedParentRef(filter)) {
|
|
1433
|
+
issues.push({ message: "Correlated include filter must not itself be a $parent reference", path: [] });
|
|
1434
|
+
return issues;
|
|
1435
|
+
}
|
|
1436
|
+
scanTemplateObjectEntries(filter, [], issues);
|
|
1437
|
+
return issues;
|
|
1438
|
+
}
|
|
1439
|
+
function findArgsMarkerIssue(value, where) {
|
|
1440
|
+
if (value !== void 0 && containsParentMarkerShape(value)) {
|
|
1441
|
+
return {
|
|
1442
|
+
message: `Unsupported $parent reference in ${where}: references are only supported in filter and id positions`,
|
|
1443
|
+
path: []
|
|
1444
|
+
};
|
|
1445
|
+
}
|
|
1446
|
+
return null;
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
// src/validation/common.ts
|
|
1247
1450
|
var stringOrStringArray = import_zod2.z.union([import_zod2.z.string(), import_zod2.z.array(import_zod2.z.string())]);
|
|
1248
1451
|
var safeIntegerString = (min, message) => import_zod2.z.string().regex(/^\d+$/, message).refine((value) => Number.isSafeInteger(Number(value)), "Expected a safe integer").refine((value) => Number(value) >= min, message);
|
|
1249
1452
|
var queryBooleanString = import_zod2.z.enum(["true", "false"]);
|
|
@@ -1304,7 +1507,8 @@ var subPopulateSchema = import_zod2.z.union([
|
|
|
1304
1507
|
select: projectionSchema.optional()
|
|
1305
1508
|
}).passthrough()
|
|
1306
1509
|
]);
|
|
1307
|
-
var
|
|
1510
|
+
var legacyIncludeItemSchema = import_zod2.z.object({
|
|
1511
|
+
mode: import_zod2.z.enum(["legacy"]).optional(),
|
|
1308
1512
|
model: import_zod2.z.string().min(1),
|
|
1309
1513
|
op: import_zod2.z.enum(["list", "read", "count"]),
|
|
1310
1514
|
path: import_zod2.z.string().min(1),
|
|
@@ -1313,8 +1517,139 @@ var includeItemSchema = import_zod2.z.object({
|
|
|
1313
1517
|
foreignField: import_zod2.z.string().min(1),
|
|
1314
1518
|
args: import_zod2.z.unknown().optional().describe("Forwarded to list/read includes. Count includes ignore pagination fields so counts remain exact."),
|
|
1315
1519
|
options: import_zod2.z.unknown().optional()
|
|
1316
|
-
}).passthrough()
|
|
1317
|
-
|
|
1520
|
+
}).passthrough().superRefine((entry, ctx) => {
|
|
1521
|
+
if (entry.filter !== void 0 && containsParentMarkerShape(entry.filter)) {
|
|
1522
|
+
ctx.addIssue({
|
|
1523
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
1524
|
+
message: 'Legacy includes must not contain $parent markers; use a correlated include (mode: "correlated")',
|
|
1525
|
+
path: ["filter"]
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
});
|
|
1529
|
+
var parentRefSchema = import_zod2.z.object({ $parent: import_zod2.z.string().min(1) }).strict().superRefine((value, ctx) => {
|
|
1530
|
+
if (!isValidParentRefPath(value.$parent)) {
|
|
1531
|
+
ctx.addIssue({
|
|
1532
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
1533
|
+
message: `Invalid $parent reference path: ${value.$parent}`,
|
|
1534
|
+
path: ["$parent"]
|
|
1535
|
+
});
|
|
1536
|
+
}
|
|
1537
|
+
});
|
|
1538
|
+
var correlatedIdSchema = import_zod2.z.union([import_zod2.z.string().min(1), parentRefSchema]);
|
|
1539
|
+
var correlatedFilterSchema = import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()).superRefine((filter, ctx) => {
|
|
1540
|
+
for (const issue of validateCorrelatedFilterTemplate(filter)) {
|
|
1541
|
+
ctx.addIssue({
|
|
1542
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
1543
|
+
message: issue.message,
|
|
1544
|
+
path: issue.path.map(String)
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
});
|
|
1548
|
+
var correlatedEmptyOptionsSchema = import_zod2.z.unknown().refine(
|
|
1549
|
+
(value) => value === void 0 || (0, import_utils10.isPlainObject)(value) && Object.keys(value).length === 0,
|
|
1550
|
+
"Correlated include options must be absent or empty"
|
|
1551
|
+
).optional();
|
|
1552
|
+
var correlatedPathSchema = import_zod2.z.string().min(1).superRefine((path, ctx) => {
|
|
1553
|
+
if (!isValidCorrelatedOutputPath(path)) {
|
|
1554
|
+
ctx.addIssue({
|
|
1555
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
1556
|
+
message: `Invalid correlated include output path: ${path}`,
|
|
1557
|
+
path: []
|
|
1558
|
+
});
|
|
1559
|
+
}
|
|
1560
|
+
});
|
|
1561
|
+
var checkArgsMarkers = (select, sort, ctx) => {
|
|
1562
|
+
const selectIssue = findArgsMarkerIssue(select, "args.select");
|
|
1563
|
+
if (selectIssue) {
|
|
1564
|
+
ctx.addIssue({ code: import_zod2.z.ZodIssueCode.custom, message: selectIssue.message, path: ["select"] });
|
|
1565
|
+
}
|
|
1566
|
+
const sortIssue = findArgsMarkerIssue(sort, "args.sort");
|
|
1567
|
+
if (sortIssue) {
|
|
1568
|
+
ctx.addIssue({ code: import_zod2.z.ZodIssueCode.custom, message: sortIssue.message, path: ["sort"] });
|
|
1569
|
+
}
|
|
1570
|
+
};
|
|
1571
|
+
var correlatedReadArgsSchema = import_zod2.z.object({
|
|
1572
|
+
select: projectionSchema.optional(),
|
|
1573
|
+
sort: sortSchema.optional(),
|
|
1574
|
+
include: import_zod2.z.lazy(() => correlatedNestedIncludeSchema).optional()
|
|
1575
|
+
}).strict().superRefine((args, ctx) => checkArgsMarkers(args.select, args.sort, ctx));
|
|
1576
|
+
var correlatedListArgsSchema = import_zod2.z.object({
|
|
1577
|
+
select: projectionSchema.optional(),
|
|
1578
|
+
sort: sortSchema.optional(),
|
|
1579
|
+
skip: import_zod2.z.union([nonNegativeIntegerSchema, nonNegativeIntegerString]).optional(),
|
|
1580
|
+
limit: import_zod2.z.union([positiveIntegerSchema, positiveIntegerString]).optional(),
|
|
1581
|
+
page: import_zod2.z.union([nonNegativeIntegerSchema, nonNegativeIntegerString]).optional(),
|
|
1582
|
+
pageSize: import_zod2.z.union([positiveIntegerSchema, positiveIntegerString]).optional(),
|
|
1583
|
+
include: import_zod2.z.lazy(() => correlatedNestedIncludeSchema).optional()
|
|
1584
|
+
}).strict().superRefine((args, ctx) => checkArgsMarkers(args.select, args.sort, ctx));
|
|
1585
|
+
var correlatedCountArgsSchema = import_zod2.z.unknown().refine(
|
|
1586
|
+
(value) => value === void 0 || (0, import_utils10.isPlainObject)(value) && Object.keys(value).length === 0,
|
|
1587
|
+
"Count includes accept no args"
|
|
1588
|
+
).optional();
|
|
1589
|
+
var correlatedReadByIdSchema = import_zod2.z.object({
|
|
1590
|
+
mode: import_zod2.z.literal("correlated"),
|
|
1591
|
+
model: import_zod2.z.string().min(1),
|
|
1592
|
+
op: import_zod2.z.literal("read"),
|
|
1593
|
+
path: correlatedPathSchema,
|
|
1594
|
+
id: correlatedIdSchema,
|
|
1595
|
+
args: correlatedReadArgsSchema.optional(),
|
|
1596
|
+
options: correlatedEmptyOptionsSchema
|
|
1597
|
+
}).strict();
|
|
1598
|
+
var correlatedReadByFilterSchema = import_zod2.z.object({
|
|
1599
|
+
mode: import_zod2.z.literal("correlated"),
|
|
1600
|
+
model: import_zod2.z.string().min(1),
|
|
1601
|
+
op: import_zod2.z.literal("read"),
|
|
1602
|
+
path: correlatedPathSchema,
|
|
1603
|
+
filter: correlatedFilterSchema,
|
|
1604
|
+
args: correlatedReadArgsSchema.optional(),
|
|
1605
|
+
options: correlatedEmptyOptionsSchema
|
|
1606
|
+
}).strict();
|
|
1607
|
+
var correlatedListSchema = import_zod2.z.object({
|
|
1608
|
+
mode: import_zod2.z.literal("correlated"),
|
|
1609
|
+
model: import_zod2.z.string().min(1),
|
|
1610
|
+
op: import_zod2.z.literal("list"),
|
|
1611
|
+
path: correlatedPathSchema,
|
|
1612
|
+
filter: correlatedFilterSchema,
|
|
1613
|
+
args: correlatedListArgsSchema.optional(),
|
|
1614
|
+
options: correlatedEmptyOptionsSchema
|
|
1615
|
+
}).strict();
|
|
1616
|
+
var correlatedCountSchema = import_zod2.z.object({
|
|
1617
|
+
mode: import_zod2.z.literal("correlated"),
|
|
1618
|
+
model: import_zod2.z.string().min(1),
|
|
1619
|
+
op: import_zod2.z.literal("count"),
|
|
1620
|
+
path: correlatedPathSchema,
|
|
1621
|
+
filter: correlatedFilterSchema,
|
|
1622
|
+
args: correlatedCountArgsSchema,
|
|
1623
|
+
options: correlatedEmptyOptionsSchema
|
|
1624
|
+
}).strict();
|
|
1625
|
+
var includeItemSchema = import_zod2.z.union([
|
|
1626
|
+
legacyIncludeItemSchema,
|
|
1627
|
+
correlatedReadByIdSchema,
|
|
1628
|
+
correlatedReadByFilterSchema,
|
|
1629
|
+
correlatedListSchema,
|
|
1630
|
+
correlatedCountSchema
|
|
1631
|
+
]);
|
|
1632
|
+
var correlatedNestedIncludeSchema = import_zod2.z.union([includeItemSchema, import_zod2.z.array(includeItemSchema)]);
|
|
1633
|
+
var rejectDuplicateCorrelatedPaths = (items, ctx) => {
|
|
1634
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1635
|
+
items.forEach((item, index) => {
|
|
1636
|
+
if ((0, import_utils10.isPlainObject)(item) && item.mode === "correlated" && typeof item.path === "string") {
|
|
1637
|
+
if (seen.has(item.path)) {
|
|
1638
|
+
ctx.addIssue({
|
|
1639
|
+
code: import_zod2.z.ZodIssueCode.custom,
|
|
1640
|
+
message: `Duplicate correlated include output path: ${item.path}`,
|
|
1641
|
+
path: [index, "path"]
|
|
1642
|
+
});
|
|
1643
|
+
} else {
|
|
1644
|
+
seen.add(item.path);
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
});
|
|
1648
|
+
};
|
|
1649
|
+
var includeSchema = import_zod2.z.union([
|
|
1650
|
+
includeItemSchema,
|
|
1651
|
+
import_zod2.z.array(includeItemSchema).superRefine(rejectDuplicateCorrelatedPaths)
|
|
1652
|
+
]);
|
|
1318
1653
|
var fieldsSchema = import_zod2.z.array(import_zod2.z.string().min(1));
|
|
1319
1654
|
var taskSchema = import_zod2.z.object({
|
|
1320
1655
|
type: import_zod2.z.string().min(1),
|
|
@@ -1497,19 +1832,12 @@ function fromJoi(schema) {
|
|
|
1497
1832
|
}
|
|
1498
1833
|
function fromAjv(validator) {
|
|
1499
1834
|
return async (value) => {
|
|
1500
|
-
|
|
1501
|
-
if (isThenable(outcome)) {
|
|
1835
|
+
if (validator.$async === true) {
|
|
1502
1836
|
try {
|
|
1503
|
-
const data = await
|
|
1504
|
-
if (data === false) {
|
|
1505
|
-
return {
|
|
1506
|
-
success: false,
|
|
1507
|
-
issues: normalizeAjvIssues(validator.errors ?? [])
|
|
1508
|
-
};
|
|
1509
|
-
}
|
|
1837
|
+
const data = await validator(value);
|
|
1510
1838
|
return {
|
|
1511
1839
|
success: true,
|
|
1512
|
-
data
|
|
1840
|
+
data
|
|
1513
1841
|
};
|
|
1514
1842
|
} catch (error) {
|
|
1515
1843
|
if (!isAjvValidationError(error)) {
|
|
@@ -1517,11 +1845,21 @@ function fromAjv(validator) {
|
|
|
1517
1845
|
}
|
|
1518
1846
|
return {
|
|
1519
1847
|
success: false,
|
|
1520
|
-
issues: normalizeAjvIssues(error.errors
|
|
1848
|
+
issues: normalizeAjvIssues(error.errors)
|
|
1521
1849
|
};
|
|
1522
1850
|
}
|
|
1523
1851
|
}
|
|
1524
|
-
const
|
|
1852
|
+
const outcome = validator(value);
|
|
1853
|
+
if (isThenable(outcome)) {
|
|
1854
|
+
void Promise.resolve(outcome).catch(() => {
|
|
1855
|
+
});
|
|
1856
|
+
throw new TypeError(
|
|
1857
|
+
"fromAjv: promise/thenable validators must declare $async: true and resolve with validated data"
|
|
1858
|
+
);
|
|
1859
|
+
}
|
|
1860
|
+
if (typeof outcome !== "boolean") {
|
|
1861
|
+
throw new TypeError("fromAjv: synchronous validators must return a boolean verdict");
|
|
1862
|
+
}
|
|
1525
1863
|
if (outcome) {
|
|
1526
1864
|
return {
|
|
1527
1865
|
success: true,
|
|
@@ -1530,7 +1868,9 @@ function fromAjv(validator) {
|
|
|
1530
1868
|
}
|
|
1531
1869
|
return {
|
|
1532
1870
|
success: false,
|
|
1533
|
-
|
|
1871
|
+
// Normalize immediately, copying message/path before another call can
|
|
1872
|
+
// replace the errors array or mutate its entries.
|
|
1873
|
+
issues: normalizeAjvIssues(validator.errors ?? [])
|
|
1534
1874
|
};
|
|
1535
1875
|
};
|
|
1536
1876
|
}
|
|
@@ -1760,14 +2100,14 @@ function isArkTypeErrors(value) {
|
|
|
1760
2100
|
return record.arkKind === "errors" || record[" arkKind"] === "errors";
|
|
1761
2101
|
}
|
|
1762
2102
|
function isThenable(value) {
|
|
1763
|
-
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
2103
|
+
return (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
|
|
1764
2104
|
}
|
|
1765
2105
|
function isAjvValidationError(error) {
|
|
1766
2106
|
if (typeof error !== "object" || error === null || !("errors" in error)) {
|
|
1767
2107
|
return false;
|
|
1768
2108
|
}
|
|
1769
|
-
const
|
|
1770
|
-
return
|
|
2109
|
+
const candidate = error;
|
|
2110
|
+
return candidate.ajv === true && candidate.validation === true && Array.isArray(candidate.errors);
|
|
1771
2111
|
}
|
|
1772
2112
|
function isVineValidationError(error) {
|
|
1773
2113
|
if (typeof error !== "object" || error === null || !("messages" in error)) {
|
|
@@ -1851,7 +2191,7 @@ var listBodySchema = import_zod3.z.object({
|
|
|
1851
2191
|
}).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query"]));
|
|
1852
2192
|
var countBodySchema = import_zod3.z.object({
|
|
1853
2193
|
filter: objectOrArraySchema.optional()
|
|
1854
|
-
}).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query", "access", "options"]));
|
|
2194
|
+
}).passthrough().superRefine((body, ctx) => rejectKeys(body, ctx, ["query", "access", "options", "include"]));
|
|
1855
2195
|
var readFilterBodySchema = import_zod3.z.object({
|
|
1856
2196
|
filter: objectOrArraySchema.optional(),
|
|
1857
2197
|
select: projectionSchema.optional(),
|