zod-nest 3.3.0 → 3.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/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { isZodDto, ZodNestError, ZodValidationException, defaultRegistry, ZOD_DTO_SYMBOL, ZOD_NEST_DTO_EXTENSION, flattenObjectIntersection, resolveSchemaRef, isZodObject, registerSchema, expandObjectSchema, paramSchemaBody, COMPONENTS_SCHEMAS_PREFIX, isZodSchema, buildToJsonSchemaOptions, resolveAnonId, ANON_RESPONSE_PREFIX, ZOD_NEST_ERROR_DUPLICATE_ID, ZOD_NEST_ERROR_EXTENSION } from './chunk-YRTGPVSJ.mjs';
2
- export { COMPONENTS_SCHEMAS_PREFIX, ZOD_DTO_SYMBOL, ZOD_NEST_DTO_EXTENSION, ZOD_NEST_ERROR_DUPLICATE_ID, ZOD_NEST_ERROR_EXTENSION, ZodNestError, ZodNestUnrepresentableError, ZodValidationException, createRegistry, defaultRegistry, extend, getLineage, isZodDto, isZodSchema, registerSchema, toOpenApi } from './chunk-YRTGPVSJ.mjs';
1
+ import { isZodDto, ZodNestError, ZodValidationException, defaultRegistry, ZOD_DTO_SYMBOL, ZOD_NEST_DTO_EXTENSION, flattenObjectIntersection, resolveSchemaRef, isZodObject, registerSchema, expandObjectSchema, paramSchemaBody, COMPONENTS_SCHEMAS_PREFIX, isZodSchema, buildToJsonSchemaOptions, resolveAnonId, ANON_RESPONSE_PREFIX, ZOD_NEST_ERROR_DUPLICATE_ID, ZOD_NEST_ERROR_EXTENSION, ZOD_NEST_ITEM_STREAM_EXTENSION } from './chunk-6HU5TMFO.mjs';
2
+ export { COMPONENTS_SCHEMAS_PREFIX, ZOD_DTO_SYMBOL, ZOD_NEST_DTO_EXTENSION, ZOD_NEST_ERROR_DUPLICATE_ID, ZOD_NEST_ERROR_EXTENSION, ZodNestError, ZodNestUnrepresentableError, ZodValidationException, createRegistry, defaultRegistry, extend, getLineage, isZodDto, isZodSchema, registerSchema, toOpenApi } from './chunk-6HU5TMFO.mjs';
3
3
  import { singleton, __name } from './chunk-MPNAA53V.mjs';
4
4
  export { overrideJSONSchema } from './chunk-MPNAA53V.mjs';
5
5
  import { InternalServerErrorException, HttpStatus, Injectable, Optional, Inject, Logger, RequestMethod, applyDecorators } from '@nestjs/common';
@@ -243,15 +243,28 @@ var createValidationLogger = /* @__PURE__ */ __name((opts) => {
243
243
  };
244
244
  }, "createValidationLogger");
245
245
  var DEFAULT_CONTENT_TYPE = "application/json";
246
- var DEFAULT_STREAM_CONTENT_TYPES = [
246
+ var SEQUENTIAL_DEFAULT_MEDIA_TYPES = [
247
247
  "text/event-stream",
248
- "application/x-ndjson",
248
+ "application/x-ndjson"
249
+ ];
250
+ var SEQUENTIAL_MEDIA_TYPES = [
251
+ ...SEQUENTIAL_DEFAULT_MEDIA_TYPES,
252
+ "application/jsonl",
253
+ "application/json-seq",
254
+ "application/geo+json-seq",
255
+ "multipart/mixed"
256
+ ];
257
+ var OPAQUE_STREAM_MEDIA_TYPES = [
249
258
  "application/octet-stream",
250
259
  "application/pdf",
251
260
  "image/*",
252
261
  "audio/*",
253
262
  "video/*"
254
263
  ];
264
+ var DEFAULT_STREAM_CONTENT_TYPES = [
265
+ ...SEQUENTIAL_DEFAULT_MEDIA_TYPES,
266
+ ...OPAQUE_STREAM_MEDIA_TYPES
267
+ ];
255
268
  var PREFIX_WILDCARD_SUFFIX = "/*";
256
269
  var normalizeContentType = /* @__PURE__ */ __name((contentType) => {
257
270
  const semicolonIndex = contentType.indexOf(";");
@@ -291,6 +304,18 @@ var matchesStream = /* @__PURE__ */ __name((contentType, matcher) => {
291
304
  }
292
305
  return false;
293
306
  }, "matchesStream");
307
+ var SEQUENTIAL_MATCHER = normalizeStreamMatcher(SEQUENTIAL_MEDIA_TYPES);
308
+ var OPAQUE_MATCHER = normalizeStreamMatcher(OPAQUE_STREAM_MEDIA_TYPES);
309
+ var isSequentialMediaType = /* @__PURE__ */ __name((contentType) => matchesStream(contentType, SEQUENTIAL_MATCHER), "isSequentialMediaType");
310
+ var isItemStreamVariant = /* @__PURE__ */ __name((variant, contentType) => {
311
+ if (variant.stream !== true) {
312
+ return false;
313
+ }
314
+ if (isSequentialMediaType(contentType)) {
315
+ return false;
316
+ }
317
+ return !matchesStream(contentType, OPAQUE_MATCHER);
318
+ }, "isItemStreamVariant");
294
319
  var isHeaderEntry = /* @__PURE__ */ __name((value) => {
295
320
  if (value === null || typeof value !== "object") {
296
321
  return false;
@@ -617,24 +642,29 @@ var buildTupleSchema = /* @__PURE__ */ __name((dtos) => ({
617
642
  })),
618
643
  items: false
619
644
  }), "buildTupleSchema");
620
- var buildContentResponseOptions = /* @__PURE__ */ __name((base, contentType, schema) => {
645
+ var buildContentResponseOptions = /* @__PURE__ */ __name((base, contentType, schema, markItemStream) => {
646
+ const mediaType = markItemStream ? {
647
+ schema,
648
+ [ZOD_NEST_ITEM_STREAM_EXTENSION]: true
649
+ } : {
650
+ schema
651
+ };
621
652
  return {
622
653
  ...base,
623
654
  content: {
624
- [contentType]: {
625
- schema
626
- }
655
+ [contentType]: mediaType
627
656
  }
628
657
  };
629
658
  }, "buildContentResponseOptions");
630
659
  var applyCustomContentResponse = /* @__PURE__ */ __name((variant, base, contentType, target, propertyKey, descriptor) => {
660
+ const markItemStream = isItemStreamVariant(variant, contentType);
631
661
  if (variant.kind === "single") {
632
662
  const dto = variant.dto;
633
663
  ApiExtraModels(asDtoFunction(dto))(target, propertyKey, descriptor);
634
664
  const schema = {
635
665
  $ref: getSchemaPath(asDtoFunction(dto))
636
666
  };
637
- ApiResponse(buildContentResponseOptions(base, contentType, schema))(target, propertyKey, descriptor);
667
+ ApiResponse(buildContentResponseOptions(base, contentType, schema, markItemStream))(target, propertyKey, descriptor);
638
668
  return;
639
669
  }
640
670
  const dtos = variant.dto;
@@ -647,10 +677,10 @@ var applyCustomContentResponse = /* @__PURE__ */ __name((variant, base, contentT
647
677
  $ref: getSchemaPath(asDtoFunction(dto))
648
678
  }
649
679
  };
650
- ApiResponse(buildContentResponseOptions(base, contentType, schema))(target, propertyKey, descriptor);
680
+ ApiResponse(buildContentResponseOptions(base, contentType, schema, markItemStream))(target, propertyKey, descriptor);
651
681
  return;
652
682
  }
653
- ApiResponse(buildContentResponseOptions(base, contentType, buildTupleSchema(dtos)))(target, propertyKey, descriptor);
683
+ ApiResponse(buildContentResponseOptions(base, contentType, buildTupleSchema(dtos), markItemStream))(target, propertyKey, descriptor);
654
684
  }, "applyCustomContentResponse");
655
685
  var applySwaggerResponseDecorator = /* @__PURE__ */ __name((variant, effectiveStatus, effectiveContentType, target, propertyKey, descriptor) => {
656
686
  const base = {
@@ -1037,6 +1067,101 @@ var ZodNestModule = class _ZodNestModule {
1037
1067
  };
1038
1068
  }
1039
1069
  };
1070
+
1071
+ // src/document/http-methods.ts
1072
+ var OPENAPI_OPERATION_KEYS = [
1073
+ "get",
1074
+ "put",
1075
+ "post",
1076
+ "delete",
1077
+ "options",
1078
+ "head",
1079
+ "patch",
1080
+ "trace",
1081
+ "query"
1082
+ ];
1083
+ var EXTENSION_OPERATION_KEYS = [
1084
+ "search",
1085
+ "propfind",
1086
+ "proppatch",
1087
+ "mkcol",
1088
+ "copy",
1089
+ "move",
1090
+ "lock",
1091
+ "unlock"
1092
+ ];
1093
+ var HTTP_METHODS = [
1094
+ ...OPENAPI_OPERATION_KEYS,
1095
+ ...EXTENSION_OPERATION_KEYS
1096
+ ];
1097
+ var ADDITIONAL_OPERATIONS_KEY = "additionalOperations";
1098
+ var isRecord = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object", "isRecord");
1099
+ var operationsOfPathItem = /* @__PURE__ */ __name((pathItem) => {
1100
+ const operations = [];
1101
+ for (const method of HTTP_METHODS) {
1102
+ const operation = pathItem[method];
1103
+ if (isRecord(operation)) {
1104
+ operations.push(operation);
1105
+ }
1106
+ }
1107
+ const additional = pathItem[ADDITIONAL_OPERATIONS_KEY];
1108
+ if (isRecord(additional)) {
1109
+ for (const operation of Object.values(additional)) {
1110
+ if (isRecord(operation)) {
1111
+ operations.push(operation);
1112
+ }
1113
+ }
1114
+ }
1115
+ return operations;
1116
+ }, "operationsOfPathItem");
1117
+ var forEachOperation = /* @__PURE__ */ __name((doc, fn) => {
1118
+ const paths = doc.paths;
1119
+ if (!isRecord(paths)) {
1120
+ return;
1121
+ }
1122
+ for (const pathItem of Object.values(paths)) {
1123
+ if (!isRecord(pathItem)) {
1124
+ continue;
1125
+ }
1126
+ for (const operation of operationsOfPathItem(pathItem)) {
1127
+ fn(operation);
1128
+ }
1129
+ }
1130
+ }, "forEachOperation");
1131
+
1132
+ // src/document/additional-operations.ts
1133
+ var isRecord2 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object", "isRecord");
1134
+ var relocateExtensionOperations = /* @__PURE__ */ __name((doc) => {
1135
+ const paths = doc.paths;
1136
+ if (!isRecord2(paths)) {
1137
+ return;
1138
+ }
1139
+ for (const pathItem of Object.values(paths)) {
1140
+ if (!isRecord2(pathItem)) {
1141
+ continue;
1142
+ }
1143
+ relocateInPathItem(pathItem);
1144
+ }
1145
+ }, "relocateExtensionOperations");
1146
+ var relocateInPathItem = /* @__PURE__ */ __name((pathItem) => {
1147
+ const relocated = {};
1148
+ for (const method of EXTENSION_OPERATION_KEYS) {
1149
+ const operation = pathItem[method];
1150
+ if (!isRecord2(operation)) {
1151
+ continue;
1152
+ }
1153
+ relocated[method.toUpperCase()] = operation;
1154
+ delete pathItem[method];
1155
+ }
1156
+ if (Object.keys(relocated).length === 0) {
1157
+ return;
1158
+ }
1159
+ const existing = pathItem[ADDITIONAL_OPERATIONS_KEY];
1160
+ pathItem[ADDITIONAL_OPERATIONS_KEY] = isRecord2(existing) ? {
1161
+ ...relocated,
1162
+ ...existing
1163
+ } : relocated;
1164
+ }, "relocateInPathItem");
1040
1165
  var URI = /* @__PURE__ */ __name((id) => `#/components/schemas/${id}`, "URI");
1041
1166
  var bulkEmit = /* @__PURE__ */ __name((opts) => {
1042
1167
  const knownIds = new Set(opts.registry.ids());
@@ -1076,46 +1201,6 @@ var runPass = /* @__PURE__ */ __name((opts, io, knownIds) => {
1076
1201
  return filtered;
1077
1202
  }, "runPass");
1078
1203
 
1079
- // src/document/http-methods.ts
1080
- var HTTP_METHODS = [
1081
- "get",
1082
- "put",
1083
- "post",
1084
- "delete",
1085
- "options",
1086
- "head",
1087
- "patch",
1088
- "trace",
1089
- "query",
1090
- "search",
1091
- "propfind",
1092
- "proppatch",
1093
- "mkcol",
1094
- "copy",
1095
- "move",
1096
- "lock",
1097
- "unlock"
1098
- ];
1099
- var forEachOperation = /* @__PURE__ */ __name((doc, fn) => {
1100
- const paths = doc.paths;
1101
- if (paths === null || typeof paths !== "object") {
1102
- return;
1103
- }
1104
- for (const pathItem of Object.values(paths)) {
1105
- if (pathItem === null || typeof pathItem !== "object") {
1106
- continue;
1107
- }
1108
- const pathRecord = pathItem;
1109
- for (const method of HTTP_METHODS) {
1110
- const op = pathRecord[method];
1111
- if (op === null || typeof op !== "object") {
1112
- continue;
1113
- }
1114
- fn(op);
1115
- }
1116
- }
1117
- }, "forEachOperation");
1118
-
1119
1204
  // src/document/walk-refs.ts
1120
1205
  var walkRefs = /* @__PURE__ */ __name((node, visit) => {
1121
1206
  if (node === null || typeof node !== "object") {
@@ -1188,22 +1273,12 @@ var collectInputExposedIds = /* @__PURE__ */ __name((doc, classToDtoId, knownIds
1188
1273
  if (!isPlainRecord2(pathItem)) {
1189
1274
  continue;
1190
1275
  }
1191
- for (const operation of operationsOf(pathItem)) {
1276
+ for (const operation of operationsOfPathItem(pathItem)) {
1192
1277
  collectRefsFromOperation(operation, classToDtoId, knownIds, ids);
1193
1278
  }
1194
1279
  }
1195
1280
  return ids;
1196
1281
  }, "collectInputExposedIds");
1197
- var operationsOf = /* @__PURE__ */ __name((pathItem) => {
1198
- const out = [];
1199
- for (const method of HTTP_METHODS) {
1200
- const op = pathItem[method];
1201
- if (isPlainRecord2(op)) {
1202
- out.push(op);
1203
- }
1204
- }
1205
- return out;
1206
- }, "operationsOf");
1207
1282
  var collectRefsFromOperation = /* @__PURE__ */ __name((operation, classToDtoId, knownIds, ids) => {
1208
1283
  if (isPlainRecord2(operation.requestBody)) {
1209
1284
  collectRefsFromContent(operation.requestBody.content, classToDtoId, knownIds, ids);
@@ -1265,7 +1340,7 @@ var collectOutputExposedIds = /* @__PURE__ */ __name((doc, classToDtoId, knownId
1265
1340
  if (!isPlainRecord2(pathItem)) {
1266
1341
  continue;
1267
1342
  }
1268
- for (const operation of operationsOf(pathItem)) {
1343
+ for (const operation of operationsOfPathItem(pathItem)) {
1269
1344
  collectRefsFromResponses(operation.responses, classToDtoId, knownIds, ids);
1270
1345
  }
1271
1346
  }
@@ -1595,6 +1670,64 @@ var inlineRefs = /* @__PURE__ */ __name((node, bodyByRef) => {
1595
1670
  inlineRefs(value, bodyByRef);
1596
1671
  }
1597
1672
  }, "inlineRefs");
1673
+
1674
+ // src/document/item-schema.ts
1675
+ var isRecord3 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object", "isRecord");
1676
+ var applyItemSchema = /* @__PURE__ */ __name((doc, opts) => {
1677
+ forEachOperation(doc, (operation) => {
1678
+ visitContentHolder(operation.requestBody, opts.emit);
1679
+ const responses = operation.responses;
1680
+ if (!isRecord3(responses)) {
1681
+ return;
1682
+ }
1683
+ for (const response of Object.values(responses)) {
1684
+ visitContentHolder(response, opts.emit);
1685
+ }
1686
+ });
1687
+ }, "applyItemSchema");
1688
+ var visitContentHolder = /* @__PURE__ */ __name((holder, emit) => {
1689
+ if (!isRecord3(holder)) {
1690
+ return;
1691
+ }
1692
+ const content = holder.content;
1693
+ if (!isRecord3(content)) {
1694
+ return;
1695
+ }
1696
+ for (const [mediaTypeKey, mediaType] of Object.entries(content)) {
1697
+ if (!isRecord3(mediaType)) {
1698
+ continue;
1699
+ }
1700
+ rewriteMediaType(mediaTypeKey, mediaType, emit);
1701
+ }
1702
+ }, "visitContentHolder");
1703
+ var rewriteMediaType = /* @__PURE__ */ __name((mediaTypeKey, mediaType, emit) => {
1704
+ const marked = mediaType[ZOD_NEST_ITEM_STREAM_EXTENSION] === true;
1705
+ delete mediaType[ZOD_NEST_ITEM_STREAM_EXTENSION];
1706
+ if (!emit) {
1707
+ return;
1708
+ }
1709
+ if (!marked && !isSequentialMediaType(mediaTypeKey)) {
1710
+ return;
1711
+ }
1712
+ const itemSchema = itemSchemaOf(mediaType.schema);
1713
+ if (itemSchema === void 0) {
1714
+ return;
1715
+ }
1716
+ mediaType.itemSchema = itemSchema;
1717
+ delete mediaType.schema;
1718
+ }, "rewriteMediaType");
1719
+ var itemSchemaOf = /* @__PURE__ */ __name((schema) => {
1720
+ if (!isRecord3(schema)) {
1721
+ return void 0;
1722
+ }
1723
+ if (schema.type !== "array") {
1724
+ return schema;
1725
+ }
1726
+ if (Object.keys(schema).length !== 2 || !("items" in schema)) {
1727
+ return void 0;
1728
+ }
1729
+ return isRecord3(schema.items) ? schema.items : void 0;
1730
+ }, "itemSchemaOf");
1598
1731
  var mergeSchemas = /* @__PURE__ */ __name((params) => {
1599
1732
  const { doc, inputSchemas, outputSchemas, collected, collisions } = params;
1600
1733
  const schemas = ensureComponentsSchemas(doc);
@@ -1812,11 +1945,7 @@ var rewriteRefs = /* @__PURE__ */ __name((params) => {
1812
1945
  }
1813
1946
  }, "rewriteRefs");
1814
1947
  var rewriteResponseSubtree = /* @__PURE__ */ __name((pathItem, divergentOutputIds) => {
1815
- for (const method of HTTP_METHODS) {
1816
- const op = pathItem[method];
1817
- if (op === null || typeof op !== "object") {
1818
- continue;
1819
- }
1948
+ for (const op of operationsOfPathItem(pathItem)) {
1820
1949
  const responses = op.responses;
1821
1950
  if (responses === null || typeof responses !== "object") {
1822
1951
  continue;
@@ -1935,10 +2064,17 @@ var applyZodNest = /* @__PURE__ */ __name((doc, opts = {}) => {
1935
2064
  doc,
1936
2065
  collected: extended
1937
2066
  });
1938
- doc.openapi = resolveOpenApiVersion(doc);
2067
+ const openApiVersion = resolveOpenApiVersion(doc);
2068
+ if (openApiVersion.startsWith("3.2.")) {
2069
+ relocateExtensionOperations(doc);
2070
+ }
2071
+ applyItemSchema(doc, {
2072
+ emit: openApiVersion.startsWith("3.2.")
2073
+ });
2074
+ doc.openapi = openApiVersion;
1939
2075
  return doc;
1940
2076
  }, "applyZodNest");
1941
2077
 
1942
- export { DEFAULT_MAX_LOGGED_VALUE_BYTES, DEFAULT_REDACT_KEYS, DEFAULT_STREAM_CONTENT_TYPES, ZOD_NEST_OPTIONS, ZOD_RESPONSES_METADATA_KEY, ZodBody, ZodCookies, ZodHeaders, ZodNestDocumentError, ZodNestModule, ZodQuery, ZodResponse, ZodSerializationException, ZodSerializerInterceptor, ZodValidationPipe, applyZodNest, createZodDto, defaultStatusFor, isZodDtoMarker, makeZodDtoMarker, resolveEffectiveStatus };
2078
+ export { DEFAULT_MAX_LOGGED_VALUE_BYTES, DEFAULT_REDACT_KEYS, DEFAULT_STREAM_CONTENT_TYPES, SEQUENTIAL_MEDIA_TYPES, ZOD_NEST_OPTIONS, ZOD_RESPONSES_METADATA_KEY, ZodBody, ZodCookies, ZodHeaders, ZodNestDocumentError, ZodNestModule, ZodQuery, ZodResponse, ZodSerializationException, ZodSerializerInterceptor, ZodValidationPipe, applyZodNest, createZodDto, defaultStatusFor, isZodDtoMarker, makeZodDtoMarker, resolveEffectiveStatus };
1943
2079
  //# sourceMappingURL=index.mjs.map
1944
2080
  //# sourceMappingURL=index.mjs.map