zod-nest 1.1.1 → 1.3.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/dist/index.d.mts +17 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.js +344 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +344 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -38,6 +38,9 @@ interface ZodNestRegistry {
|
|
|
38
38
|
* underlying Zod registry is `z.globalRegistry`, which may hold third-party
|
|
39
39
|
* entries — bulk emission filters its output against this snapshot to keep
|
|
40
40
|
* only zod-nest-known ids.
|
|
41
|
+
*
|
|
42
|
+
* Includes ids discovered transitively via `.meta({ id })` on descendants
|
|
43
|
+
* of explicitly-registered schemas.
|
|
41
44
|
*/
|
|
42
45
|
ids(): readonly string[];
|
|
43
46
|
}
|
|
@@ -540,10 +543,18 @@ interface ApplyZodNestOptions {
|
|
|
540
543
|
* - Every `components.schemas[<DtoClassName>]` placeholder with an
|
|
541
544
|
* `x-zod-nest-dto` marker is replaced by the Zod-derived JSON Schema body,
|
|
542
545
|
* keyed by the marker's `dtoId` (renaming as needed).
|
|
546
|
+
* - Every `@Query()` / `@Param()` / `@Headers()` / `@Cookie()` marker
|
|
547
|
+
* parameter is expanded into one parameter per top-level property of the
|
|
548
|
+
* DTO's schema (`expandParamMarkers`). The synthetic `components.schemas.Object`
|
|
549
|
+
* that `@nestjs/swagger` materialises for the marker placeholder is pruned
|
|
550
|
+
* when it has no remaining referrers.
|
|
543
551
|
* - The I/O suffix truth table is applied — equal input/output bodies collapse
|
|
544
552
|
* to one `components.schemas[id]`; divergent bodies split as
|
|
545
553
|
* `id` (input) + `idOutput` (output), with response-side refs rewritten.
|
|
546
554
|
* - Every `$ref` whose target is missing throws `ZodNestDocumentError(DANGLING_REF)`.
|
|
555
|
+
* - `doc.openapi` is set to `'3.1.0'` — zod-nest emits OpenAPI 3.1 only; this
|
|
556
|
+
* guarantees the version string matches the emitted body regardless of the
|
|
557
|
+
* `DocumentBuilder` configuration on the caller side.
|
|
547
558
|
*
|
|
548
559
|
* Composable with other doc-transform passes — apply other mutations before
|
|
549
560
|
* or after this function. The `app` argument is required because the
|
|
@@ -552,7 +563,7 @@ interface ApplyZodNestOptions {
|
|
|
552
563
|
*/
|
|
553
564
|
declare const applyZodNest: (doc: OpenAPIObject, opts: ApplyZodNestOptions) => OpenAPIObject;
|
|
554
565
|
|
|
555
|
-
type ZodNestDocumentErrorCode = 'AMBIGUOUS_RENAME' | 'DANGLING_REF';
|
|
566
|
+
type ZodNestDocumentErrorCode = 'AMBIGUOUS_RENAME' | 'DANGLING_REF' | 'UNEXPANDABLE_PARAM_DTO';
|
|
556
567
|
/**
|
|
557
568
|
* Thrown by `applyZodNest` when the doc cannot be processed cleanly. Surfaces
|
|
558
569
|
* at doc-build time so typos / mis-registrations fail in CI, not at runtime.
|
|
@@ -565,6 +576,11 @@ type ZodNestDocumentErrorCode = 'AMBIGUOUS_RENAME' | 'DANGLING_REF';
|
|
|
565
576
|
* that no longer exists after `applyZodNest`. Usually means a marker was
|
|
566
577
|
* stripped but its rename target wasn't populated, or a user-supplied pre-pass
|
|
567
578
|
* left a stale ref.
|
|
579
|
+
*
|
|
580
|
+
* `UNEXPANDABLE_PARAM_DTO`: a `@Query()` / `@Param()` / `@Headers()` /
|
|
581
|
+
* `@Cookie()` handler argument resolved to a `createZodDto` whose schema is
|
|
582
|
+
* not an object — the marker parameter can't be expanded into individual
|
|
583
|
+
* parameters because there's no top-level `properties` record to iterate.
|
|
568
584
|
*/
|
|
569
585
|
declare class ZodNestDocumentError extends ZodNestError {
|
|
570
586
|
readonly code: ZodNestDocumentErrorCode;
|
package/dist/index.d.ts
CHANGED
|
@@ -38,6 +38,9 @@ interface ZodNestRegistry {
|
|
|
38
38
|
* underlying Zod registry is `z.globalRegistry`, which may hold third-party
|
|
39
39
|
* entries — bulk emission filters its output against this snapshot to keep
|
|
40
40
|
* only zod-nest-known ids.
|
|
41
|
+
*
|
|
42
|
+
* Includes ids discovered transitively via `.meta({ id })` on descendants
|
|
43
|
+
* of explicitly-registered schemas.
|
|
41
44
|
*/
|
|
42
45
|
ids(): readonly string[];
|
|
43
46
|
}
|
|
@@ -540,10 +543,18 @@ interface ApplyZodNestOptions {
|
|
|
540
543
|
* - Every `components.schemas[<DtoClassName>]` placeholder with an
|
|
541
544
|
* `x-zod-nest-dto` marker is replaced by the Zod-derived JSON Schema body,
|
|
542
545
|
* keyed by the marker's `dtoId` (renaming as needed).
|
|
546
|
+
* - Every `@Query()` / `@Param()` / `@Headers()` / `@Cookie()` marker
|
|
547
|
+
* parameter is expanded into one parameter per top-level property of the
|
|
548
|
+
* DTO's schema (`expandParamMarkers`). The synthetic `components.schemas.Object`
|
|
549
|
+
* that `@nestjs/swagger` materialises for the marker placeholder is pruned
|
|
550
|
+
* when it has no remaining referrers.
|
|
543
551
|
* - The I/O suffix truth table is applied — equal input/output bodies collapse
|
|
544
552
|
* to one `components.schemas[id]`; divergent bodies split as
|
|
545
553
|
* `id` (input) + `idOutput` (output), with response-side refs rewritten.
|
|
546
554
|
* - Every `$ref` whose target is missing throws `ZodNestDocumentError(DANGLING_REF)`.
|
|
555
|
+
* - `doc.openapi` is set to `'3.1.0'` — zod-nest emits OpenAPI 3.1 only; this
|
|
556
|
+
* guarantees the version string matches the emitted body regardless of the
|
|
557
|
+
* `DocumentBuilder` configuration on the caller side.
|
|
547
558
|
*
|
|
548
559
|
* Composable with other doc-transform passes — apply other mutations before
|
|
549
560
|
* or after this function. The `app` argument is required because the
|
|
@@ -552,7 +563,7 @@ interface ApplyZodNestOptions {
|
|
|
552
563
|
*/
|
|
553
564
|
declare const applyZodNest: (doc: OpenAPIObject, opts: ApplyZodNestOptions) => OpenAPIObject;
|
|
554
565
|
|
|
555
|
-
type ZodNestDocumentErrorCode = 'AMBIGUOUS_RENAME' | 'DANGLING_REF';
|
|
566
|
+
type ZodNestDocumentErrorCode = 'AMBIGUOUS_RENAME' | 'DANGLING_REF' | 'UNEXPANDABLE_PARAM_DTO';
|
|
556
567
|
/**
|
|
557
568
|
* Thrown by `applyZodNest` when the doc cannot be processed cleanly. Surfaces
|
|
558
569
|
* at doc-build time so typos / mis-registrations fail in CI, not at runtime.
|
|
@@ -565,6 +576,11 @@ type ZodNestDocumentErrorCode = 'AMBIGUOUS_RENAME' | 'DANGLING_REF';
|
|
|
565
576
|
* that no longer exists after `applyZodNest`. Usually means a marker was
|
|
566
577
|
* stripped but its rename target wasn't populated, or a user-supplied pre-pass
|
|
567
578
|
* left a stale ref.
|
|
579
|
+
*
|
|
580
|
+
* `UNEXPANDABLE_PARAM_DTO`: a `@Query()` / `@Param()` / `@Headers()` /
|
|
581
|
+
* `@Cookie()` handler argument resolved to a `createZodDto` whose schema is
|
|
582
|
+
* not an object — the marker parameter can't be expanded into individual
|
|
583
|
+
* parameters because there's no top-level `properties` record to iterate.
|
|
568
584
|
*/
|
|
569
585
|
declare class ZodNestDocumentError extends ZodNestError {
|
|
570
586
|
readonly code: ZodNestDocumentErrorCode;
|
package/dist/index.js
CHANGED
|
@@ -345,20 +345,146 @@ var toOpenApi = /* @__PURE__ */ __name((schema, opts) => {
|
|
|
345
345
|
}
|
|
346
346
|
return result;
|
|
347
347
|
}, "toOpenApi");
|
|
348
|
+
var INNER_TYPE_WRAPPERS = /* @__PURE__ */ new Set([
|
|
349
|
+
"optional",
|
|
350
|
+
"nullable",
|
|
351
|
+
"default",
|
|
352
|
+
"prefault",
|
|
353
|
+
"catch",
|
|
354
|
+
"nonoptional",
|
|
355
|
+
"success",
|
|
356
|
+
"readonly",
|
|
357
|
+
"promise"
|
|
358
|
+
]);
|
|
359
|
+
var readId = /* @__PURE__ */ __name((schema) => {
|
|
360
|
+
const meta = zod.z.globalRegistry.get(schema);
|
|
361
|
+
if (meta === void 0) {
|
|
362
|
+
return void 0;
|
|
363
|
+
}
|
|
364
|
+
const id = meta.id;
|
|
365
|
+
return typeof id === "string" ? id : void 0;
|
|
366
|
+
}, "readId");
|
|
367
|
+
var collectChildren = /* @__PURE__ */ __name((schema) => {
|
|
368
|
+
const def = schema._zod.def;
|
|
369
|
+
if (def.type === "object") {
|
|
370
|
+
const out = [];
|
|
371
|
+
const shape = def.shape;
|
|
372
|
+
if (shape !== void 0) {
|
|
373
|
+
for (const value of Object.values(shape)) {
|
|
374
|
+
out.push(value);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
if (def.catchall !== void 0) {
|
|
378
|
+
out.push(def.catchall);
|
|
379
|
+
}
|
|
380
|
+
return out;
|
|
381
|
+
}
|
|
382
|
+
if (def.type === "array") {
|
|
383
|
+
return [
|
|
384
|
+
def.element
|
|
385
|
+
];
|
|
386
|
+
}
|
|
387
|
+
if (def.type === "union") {
|
|
388
|
+
return def.options.map((opt) => opt);
|
|
389
|
+
}
|
|
390
|
+
if (def.type === "intersection") {
|
|
391
|
+
return [
|
|
392
|
+
def.left,
|
|
393
|
+
def.right
|
|
394
|
+
];
|
|
395
|
+
}
|
|
396
|
+
if (def.type === "tuple") {
|
|
397
|
+
const out = def.items.map((it) => it);
|
|
398
|
+
if (def.rest !== null) {
|
|
399
|
+
out.push(def.rest);
|
|
400
|
+
}
|
|
401
|
+
return out;
|
|
402
|
+
}
|
|
403
|
+
if (def.type === "record" || def.type === "map") {
|
|
404
|
+
return [
|
|
405
|
+
def.keyType,
|
|
406
|
+
def.valueType
|
|
407
|
+
];
|
|
408
|
+
}
|
|
409
|
+
if (def.type === "set") {
|
|
410
|
+
return [
|
|
411
|
+
def.valueType
|
|
412
|
+
];
|
|
413
|
+
}
|
|
414
|
+
if (def.type === "pipe") {
|
|
415
|
+
return [
|
|
416
|
+
def.in,
|
|
417
|
+
def.out
|
|
418
|
+
];
|
|
419
|
+
}
|
|
420
|
+
if (def.type === "lazy") {
|
|
421
|
+
return [
|
|
422
|
+
def.getter()
|
|
423
|
+
];
|
|
424
|
+
}
|
|
425
|
+
if (INNER_TYPE_WRAPPERS.has(def.type)) {
|
|
426
|
+
return [
|
|
427
|
+
def.innerType
|
|
428
|
+
];
|
|
429
|
+
}
|
|
430
|
+
return [];
|
|
431
|
+
}, "collectChildren");
|
|
432
|
+
var discoverDependents = /* @__PURE__ */ __name((schema) => {
|
|
433
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
434
|
+
const out = [];
|
|
435
|
+
const stack = [
|
|
436
|
+
schema
|
|
437
|
+
];
|
|
438
|
+
while (stack.length > 0) {
|
|
439
|
+
const current = stack.pop();
|
|
440
|
+
if (visited.has(current)) {
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
visited.add(current);
|
|
444
|
+
for (const child of collectChildren(current)) {
|
|
445
|
+
if (visited.has(child)) {
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
const id = readId(child);
|
|
449
|
+
if (id !== void 0) {
|
|
450
|
+
out.push([
|
|
451
|
+
child,
|
|
452
|
+
id
|
|
453
|
+
]);
|
|
454
|
+
}
|
|
455
|
+
stack.push(child);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return out;
|
|
459
|
+
}, "discoverDependents");
|
|
460
|
+
|
|
461
|
+
// src/schema/registry.ts
|
|
348
462
|
var createRegistry = /* @__PURE__ */ __name(() => {
|
|
349
463
|
const seen = /* @__PURE__ */ new Map();
|
|
464
|
+
const recordOnce = /* @__PURE__ */ __name((schema, id) => {
|
|
465
|
+
let set = seen.get(id);
|
|
466
|
+
if (set === void 0) {
|
|
467
|
+
set = /* @__PURE__ */ new Set();
|
|
468
|
+
seen.set(id, set);
|
|
469
|
+
}
|
|
470
|
+
if (set.has(schema)) {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
set.add(schema);
|
|
474
|
+
return true;
|
|
475
|
+
}, "recordOnce");
|
|
350
476
|
return {
|
|
351
477
|
zodRegistry: zod.z.globalRegistry,
|
|
352
478
|
register: /* @__PURE__ */ __name((schema, id) => {
|
|
353
479
|
zod.z.globalRegistry.add(schema, {
|
|
354
480
|
id
|
|
355
481
|
});
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
482
|
+
if (!recordOnce(schema, id)) {
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
for (const [child, childId] of discoverDependents(schema)) {
|
|
486
|
+
recordOnce(child, childId);
|
|
360
487
|
}
|
|
361
|
-
set.add(schema);
|
|
362
488
|
}, "register"),
|
|
363
489
|
hasCollision: /* @__PURE__ */ __name((id) => {
|
|
364
490
|
const set = seen.get(id);
|
|
@@ -1147,9 +1273,20 @@ var collectRefsFromOperation = /* @__PURE__ */ __name((operation, classToDtoId,
|
|
|
1147
1273
|
continue;
|
|
1148
1274
|
}
|
|
1149
1275
|
collectRefFromSchema(param.schema, classToDtoId, ids);
|
|
1276
|
+
collectIdFromMarkerParam(param, ids);
|
|
1150
1277
|
}
|
|
1151
1278
|
}
|
|
1152
1279
|
}, "collectRefsFromOperation");
|
|
1280
|
+
var collectIdFromMarkerParam = /* @__PURE__ */ __name((param, ids) => {
|
|
1281
|
+
if (param.__zodNestDto !== true) {
|
|
1282
|
+
return;
|
|
1283
|
+
}
|
|
1284
|
+
const dtoId = param.dtoId;
|
|
1285
|
+
if (typeof dtoId !== "string" || dtoId === "") {
|
|
1286
|
+
return;
|
|
1287
|
+
}
|
|
1288
|
+
ids.add(dtoId);
|
|
1289
|
+
}, "collectIdFromMarkerParam");
|
|
1153
1290
|
var collectRefsFromContent = /* @__PURE__ */ __name((content, classToDtoId, ids) => {
|
|
1154
1291
|
if (!isPlainRecord2(content)) {
|
|
1155
1292
|
return;
|
|
@@ -1300,6 +1437,164 @@ var hintFor = /* @__PURE__ */ __name((ref, collected) => {
|
|
|
1300
1437
|
return "no DTO with this id was registered \u2014 check for a meta.id typo or a DTO used without createZodDto";
|
|
1301
1438
|
}, "hintFor");
|
|
1302
1439
|
|
|
1440
|
+
// src/document/expand-param-markers.ts
|
|
1441
|
+
var isPlainRecord3 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value), "isPlainRecord");
|
|
1442
|
+
var expandParamMarkers = /* @__PURE__ */ __name((params) => {
|
|
1443
|
+
const { doc, inputSchemas, outputSchemas } = params;
|
|
1444
|
+
const paths = doc.paths;
|
|
1445
|
+
if (!isPlainRecord3(paths)) {
|
|
1446
|
+
return;
|
|
1447
|
+
}
|
|
1448
|
+
for (const pathItem of Object.values(paths)) {
|
|
1449
|
+
if (!isPlainRecord3(pathItem)) {
|
|
1450
|
+
continue;
|
|
1451
|
+
}
|
|
1452
|
+
for (const method of HTTP_METHODS) {
|
|
1453
|
+
const op = pathItem[method];
|
|
1454
|
+
if (!isPlainRecord3(op)) {
|
|
1455
|
+
continue;
|
|
1456
|
+
}
|
|
1457
|
+
const parameters = op.parameters;
|
|
1458
|
+
if (!Array.isArray(parameters)) {
|
|
1459
|
+
continue;
|
|
1460
|
+
}
|
|
1461
|
+
op.parameters = expandParameterList(parameters, inputSchemas, outputSchemas);
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
pruneOrphanObjectSchema(doc);
|
|
1465
|
+
}, "expandParamMarkers");
|
|
1466
|
+
var expandParameterList = /* @__PURE__ */ __name((parameters, inputSchemas, outputSchemas) => {
|
|
1467
|
+
const result = [];
|
|
1468
|
+
for (const param of parameters) {
|
|
1469
|
+
const marker = readMarker2(param);
|
|
1470
|
+
if (marker === void 0) {
|
|
1471
|
+
result.push(param);
|
|
1472
|
+
continue;
|
|
1473
|
+
}
|
|
1474
|
+
const map = marker.io === "output" ? outputSchemas : inputSchemas;
|
|
1475
|
+
const body = map.get(marker.dtoId);
|
|
1476
|
+
result.push(...expandOne(marker, body));
|
|
1477
|
+
}
|
|
1478
|
+
return result;
|
|
1479
|
+
}, "expandParameterList");
|
|
1480
|
+
var readMarker2 = /* @__PURE__ */ __name((value) => {
|
|
1481
|
+
if (!isPlainRecord3(value)) {
|
|
1482
|
+
return void 0;
|
|
1483
|
+
}
|
|
1484
|
+
if (value.__zodNestDto !== true) {
|
|
1485
|
+
return void 0;
|
|
1486
|
+
}
|
|
1487
|
+
if (typeof value.dtoId !== "string" || value.dtoId === "") {
|
|
1488
|
+
return void 0;
|
|
1489
|
+
}
|
|
1490
|
+
if (value.io !== "input" && value.io !== "output") {
|
|
1491
|
+
return void 0;
|
|
1492
|
+
}
|
|
1493
|
+
if (typeof value.in !== "string" || value.in === "") {
|
|
1494
|
+
return void 0;
|
|
1495
|
+
}
|
|
1496
|
+
return value;
|
|
1497
|
+
}, "readMarker");
|
|
1498
|
+
var expandOne = /* @__PURE__ */ __name((marker, body) => {
|
|
1499
|
+
if (!isPlainRecord3(body) || !isPlainRecord3(body.properties)) {
|
|
1500
|
+
throw new ZodNestDocumentError("UNEXPANDABLE_PARAM_DTO", `Cannot expand \`@${capitalize(marker.in)}() x: ${marker.dtoId}\` \u2014 the DTO's schema is not an object with \`properties\`. Non-body parameter DTOs must be object schemas; arrays, unions, primitives, etc. cannot be split into individual parameters. Use \`@Body()\` for non-object DTOs, or restructure the schema as an object whose fields become the params.`, {
|
|
1501
|
+
dtoId: marker.dtoId,
|
|
1502
|
+
in: marker.in,
|
|
1503
|
+
io: marker.io
|
|
1504
|
+
});
|
|
1505
|
+
}
|
|
1506
|
+
const properties = body.properties;
|
|
1507
|
+
const requiredSet = collectRequired(body.required);
|
|
1508
|
+
const out = [];
|
|
1509
|
+
for (const [propName, propSchemaRaw] of Object.entries(properties)) {
|
|
1510
|
+
if (!isPlainRecord3(propSchemaRaw)) {
|
|
1511
|
+
continue;
|
|
1512
|
+
}
|
|
1513
|
+
out.push(buildParameter(marker, propName, propSchemaRaw, requiredSet.has(propName)));
|
|
1514
|
+
}
|
|
1515
|
+
return out;
|
|
1516
|
+
}, "expandOne");
|
|
1517
|
+
var collectRequired = /* @__PURE__ */ __name((value) => {
|
|
1518
|
+
if (!Array.isArray(value)) {
|
|
1519
|
+
return /* @__PURE__ */ new Set();
|
|
1520
|
+
}
|
|
1521
|
+
const out = /* @__PURE__ */ new Set();
|
|
1522
|
+
for (const item of value) {
|
|
1523
|
+
if (typeof item === "string") {
|
|
1524
|
+
out.add(item);
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
return out;
|
|
1528
|
+
}, "collectRequired");
|
|
1529
|
+
var buildParameter = /* @__PURE__ */ __name((marker, name, schema, required) => {
|
|
1530
|
+
let effectiveRequired = required;
|
|
1531
|
+
if (marker.in === "path" && !effectiveRequired) {
|
|
1532
|
+
console.warn(`[zod-nest] Path parameter \`${name}\` on DTO \`${marker.dtoId}\` is marked optional in the Zod schema; OpenAPI 3.1 requires path parameters to be required. Coercing \`required: true\` so the emitted document is spec-valid. Fix by removing \`.optional()\` / \`.nullish()\` from the field, or by switching the decorator to @Query() / @Headers() if the field is genuinely optional.`);
|
|
1533
|
+
effectiveRequired = true;
|
|
1534
|
+
}
|
|
1535
|
+
const entry = {
|
|
1536
|
+
name,
|
|
1537
|
+
in: marker.in,
|
|
1538
|
+
required: effectiveRequired,
|
|
1539
|
+
schema
|
|
1540
|
+
};
|
|
1541
|
+
if (typeof schema.description === "string") {
|
|
1542
|
+
entry.description = schema.description;
|
|
1543
|
+
}
|
|
1544
|
+
return entry;
|
|
1545
|
+
}, "buildParameter");
|
|
1546
|
+
var capitalize = /* @__PURE__ */ __name((value) => value.charAt(0).toUpperCase() + value.slice(1), "capitalize");
|
|
1547
|
+
var pruneOrphanObjectSchema = /* @__PURE__ */ __name((doc) => {
|
|
1548
|
+
const schemas = doc.components?.schemas;
|
|
1549
|
+
if (schemas === void 0 || !Object.prototype.hasOwnProperty.call(schemas, "Object")) {
|
|
1550
|
+
return;
|
|
1551
|
+
}
|
|
1552
|
+
let referenced = false;
|
|
1553
|
+
const targetRef = `${COMPONENTS_SCHEMAS_PREFIX}Object`;
|
|
1554
|
+
walkRefs(doc, (ref) => {
|
|
1555
|
+
if (ref === targetRef) {
|
|
1556
|
+
referenced = true;
|
|
1557
|
+
}
|
|
1558
|
+
return void 0;
|
|
1559
|
+
});
|
|
1560
|
+
if (!referenced) {
|
|
1561
|
+
delete schemas.Object;
|
|
1562
|
+
}
|
|
1563
|
+
}, "pruneOrphanObjectSchema");
|
|
1564
|
+
|
|
1565
|
+
// src/document/expose-closure.ts
|
|
1566
|
+
var extendExposureViaRefs = /* @__PURE__ */ __name((collected, inputSchemas, outputSchemas) => ({
|
|
1567
|
+
...collected,
|
|
1568
|
+
inputExposedIds: closeOverRefs(collected.inputExposedIds, inputSchemas),
|
|
1569
|
+
outputExposedIds: closeOverRefs(collected.outputExposedIds, outputSchemas)
|
|
1570
|
+
}), "extendExposureViaRefs");
|
|
1571
|
+
var closeOverRefs = /* @__PURE__ */ __name((seed, bodies) => {
|
|
1572
|
+
const out = new Set(seed);
|
|
1573
|
+
const queue = [
|
|
1574
|
+
...seed
|
|
1575
|
+
];
|
|
1576
|
+
while (queue.length > 0) {
|
|
1577
|
+
const id = queue.shift();
|
|
1578
|
+
const body = bodies.get(id);
|
|
1579
|
+
if (body === void 0) {
|
|
1580
|
+
continue;
|
|
1581
|
+
}
|
|
1582
|
+
walkRefs(body, (ref) => {
|
|
1583
|
+
if (!ref.startsWith(COMPONENTS_SCHEMAS_PREFIX)) {
|
|
1584
|
+
return void 0;
|
|
1585
|
+
}
|
|
1586
|
+
const target = ref.slice(COMPONENTS_SCHEMAS_PREFIX.length);
|
|
1587
|
+
if (out.has(target)) {
|
|
1588
|
+
return void 0;
|
|
1589
|
+
}
|
|
1590
|
+
out.add(target);
|
|
1591
|
+
queue.push(target);
|
|
1592
|
+
return void 0;
|
|
1593
|
+
});
|
|
1594
|
+
}
|
|
1595
|
+
return out;
|
|
1596
|
+
}, "closeOverRefs");
|
|
1597
|
+
|
|
1303
1598
|
// src/document/constants.ts
|
|
1304
1599
|
var OUTPUT_SUFFIX = "Output";
|
|
1305
1600
|
|
|
@@ -1457,13 +1752,43 @@ var rewriteResponseSubtree = /* @__PURE__ */ __name((pathItem, divergentOutputId
|
|
|
1457
1752
|
// src/document/strip-markers.ts
|
|
1458
1753
|
var stripMarkers = /* @__PURE__ */ __name((doc) => {
|
|
1459
1754
|
const schemas = doc.components?.schemas;
|
|
1460
|
-
if (schemas
|
|
1755
|
+
if (schemas !== void 0) {
|
|
1756
|
+
for (const schema of Object.values(schemas)) {
|
|
1757
|
+
stripMarkerFromSchema(schema);
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
stripMarkerParameters(doc);
|
|
1761
|
+
}, "stripMarkers");
|
|
1762
|
+
var stripMarkerParameters = /* @__PURE__ */ __name((doc) => {
|
|
1763
|
+
const paths = doc.paths;
|
|
1764
|
+
if (paths === null || typeof paths !== "object") {
|
|
1461
1765
|
return;
|
|
1462
1766
|
}
|
|
1463
|
-
for (const
|
|
1464
|
-
|
|
1767
|
+
for (const pathItem of Object.values(paths)) {
|
|
1768
|
+
if (pathItem === null || typeof pathItem !== "object") {
|
|
1769
|
+
continue;
|
|
1770
|
+
}
|
|
1771
|
+
const pathRecord = pathItem;
|
|
1772
|
+
for (const method of HTTP_METHODS) {
|
|
1773
|
+
const op = pathRecord[method];
|
|
1774
|
+
if (op === null || typeof op !== "object") {
|
|
1775
|
+
continue;
|
|
1776
|
+
}
|
|
1777
|
+
const opRecord = op;
|
|
1778
|
+
const parameters = opRecord.parameters;
|
|
1779
|
+
if (!Array.isArray(parameters)) {
|
|
1780
|
+
continue;
|
|
1781
|
+
}
|
|
1782
|
+
opRecord.parameters = parameters.filter((param) => !isMarkerParam(param));
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
}, "stripMarkerParameters");
|
|
1786
|
+
var isMarkerParam = /* @__PURE__ */ __name((value) => {
|
|
1787
|
+
if (value === null || typeof value !== "object") {
|
|
1788
|
+
return false;
|
|
1465
1789
|
}
|
|
1466
|
-
|
|
1790
|
+
return value.__zodNestDto === true;
|
|
1791
|
+
}, "isMarkerParam");
|
|
1467
1792
|
var stripMarkerFromSchema = /* @__PURE__ */ __name((schema) => {
|
|
1468
1793
|
if (schema === null || typeof schema !== "object") {
|
|
1469
1794
|
return;
|
|
@@ -1483,6 +1808,7 @@ var stripMarkerFromSchema = /* @__PURE__ */ __name((schema) => {
|
|
|
1483
1808
|
}, "stripMarkerFromSchema");
|
|
1484
1809
|
|
|
1485
1810
|
// src/document/apply-zod-nest.ts
|
|
1811
|
+
var OPENAPI_VERSION = "3.1.0";
|
|
1486
1812
|
var applyZodNest = /* @__PURE__ */ __name((doc, opts) => {
|
|
1487
1813
|
const registry = opts.registry ?? defaultRegistry;
|
|
1488
1814
|
const collected = collectUsage(doc, opts.app);
|
|
@@ -1491,13 +1817,19 @@ var applyZodNest = /* @__PURE__ */ __name((doc, opts) => {
|
|
|
1491
1817
|
override: opts.override,
|
|
1492
1818
|
strict: opts.strict
|
|
1493
1819
|
});
|
|
1820
|
+
const extended = extendExposureViaRefs(collected, inputSchemas, outputSchemas);
|
|
1494
1821
|
const { divergentOutputIds, renames } = mergeSchemas({
|
|
1495
1822
|
doc,
|
|
1496
1823
|
inputSchemas,
|
|
1497
1824
|
outputSchemas,
|
|
1498
|
-
collected,
|
|
1825
|
+
collected: extended,
|
|
1499
1826
|
collisions: registry.getCollisions()
|
|
1500
1827
|
});
|
|
1828
|
+
expandParamMarkers({
|
|
1829
|
+
doc,
|
|
1830
|
+
inputSchemas,
|
|
1831
|
+
outputSchemas
|
|
1832
|
+
});
|
|
1501
1833
|
rewriteRefs2({
|
|
1502
1834
|
doc,
|
|
1503
1835
|
renames,
|
|
@@ -1506,8 +1838,9 @@ var applyZodNest = /* @__PURE__ */ __name((doc, opts) => {
|
|
|
1506
1838
|
stripMarkers(doc);
|
|
1507
1839
|
assertNoDanglingRefs({
|
|
1508
1840
|
doc,
|
|
1509
|
-
collected
|
|
1841
|
+
collected: extended
|
|
1510
1842
|
});
|
|
1843
|
+
doc.openapi = OPENAPI_VERSION;
|
|
1511
1844
|
return doc;
|
|
1512
1845
|
}, "applyZodNest");
|
|
1513
1846
|
|