zod-nest 1.3.1 → 1.4.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 +19 -6
- package/dist/index.d.ts +19 -6
- package/dist/index.js +93 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +93 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -446,13 +446,26 @@ interface ZodResponseOptions {
|
|
|
446
446
|
passthroughOnError?: boolean;
|
|
447
447
|
}
|
|
448
448
|
/**
|
|
449
|
-
* Method-only decorator. Declares a typed response variant for the handler
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
* `
|
|
449
|
+
* Method-only decorator. Declares a typed response variant for the handler
|
|
450
|
+
* AND applies the equivalent `@ApiResponse(...)` from `@nestjs/swagger` so
|
|
451
|
+
* the OpenAPI document carries the response shape — no need for consumers
|
|
452
|
+
* to hand-write `@ApiResponse` alongside `@ZodResponse`.
|
|
453
453
|
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
454
|
+
* Stack multiple decorations to declare per-status types; runtime lookup
|
|
455
|
+
* is by `ZodSerializerInterceptor`'s two-pass matcher (exact numeric, then
|
|
456
|
+
* `'NXX'` wildcard). The wrapped Zod schema (array / tuple) is built once
|
|
457
|
+
* at decoration time — no per-request schema construction.
|
|
458
|
+
*
|
|
459
|
+
* **Decorator-ordering note (implicit `status` only).** TypeScript decorators
|
|
460
|
+
* apply bottom-up, so `@ZodResponse` (typically written above `@Get` /
|
|
461
|
+
* `@HttpCode`) executes its factory body *first* — before sibling
|
|
462
|
+
* decorators have written their `HTTP_CODE_METADATA` / `METHOD_METADATA`.
|
|
463
|
+
* When `opts.status` is explicit, the `@ApiResponse(...)` call is applied
|
|
464
|
+
* synchronously — there's nothing to wait for. When `opts.status` is
|
|
465
|
+
* implicit (resolves to `@HttpCode` or the HTTP-method default), the
|
|
466
|
+
* `@ApiResponse(...)` call is deferred via `queueMicrotask` so the sibling
|
|
467
|
+
* metadata has settled by the time we read it. See `docs/responses.md →
|
|
468
|
+
* "Decorator ordering & the microtask trick"`.
|
|
456
469
|
*/
|
|
457
470
|
declare const ZodResponse: (opts: ZodResponseOptions) => MethodDecorator;
|
|
458
471
|
|
package/dist/index.d.ts
CHANGED
|
@@ -446,13 +446,26 @@ interface ZodResponseOptions {
|
|
|
446
446
|
passthroughOnError?: boolean;
|
|
447
447
|
}
|
|
448
448
|
/**
|
|
449
|
-
* Method-only decorator. Declares a typed response variant for the handler
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
* `
|
|
449
|
+
* Method-only decorator. Declares a typed response variant for the handler
|
|
450
|
+
* AND applies the equivalent `@ApiResponse(...)` from `@nestjs/swagger` so
|
|
451
|
+
* the OpenAPI document carries the response shape — no need for consumers
|
|
452
|
+
* to hand-write `@ApiResponse` alongside `@ZodResponse`.
|
|
453
453
|
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
454
|
+
* Stack multiple decorations to declare per-status types; runtime lookup
|
|
455
|
+
* is by `ZodSerializerInterceptor`'s two-pass matcher (exact numeric, then
|
|
456
|
+
* `'NXX'` wildcard). The wrapped Zod schema (array / tuple) is built once
|
|
457
|
+
* at decoration time — no per-request schema construction.
|
|
458
|
+
*
|
|
459
|
+
* **Decorator-ordering note (implicit `status` only).** TypeScript decorators
|
|
460
|
+
* apply bottom-up, so `@ZodResponse` (typically written above `@Get` /
|
|
461
|
+
* `@HttpCode`) executes its factory body *first* — before sibling
|
|
462
|
+
* decorators have written their `HTTP_CODE_METADATA` / `METHOD_METADATA`.
|
|
463
|
+
* When `opts.status` is explicit, the `@ApiResponse(...)` call is applied
|
|
464
|
+
* synchronously — there's nothing to wait for. When `opts.status` is
|
|
465
|
+
* implicit (resolves to `@HttpCode` or the HTTP-method default), the
|
|
466
|
+
* `@ApiResponse(...)` call is deferred via `queueMicrotask` so the sibling
|
|
467
|
+
* metadata has settled by the time we read it. See `docs/responses.md →
|
|
468
|
+
* "Decorator ordering & the microtask trick"`.
|
|
456
469
|
*/
|
|
457
470
|
declare const ZodResponse: (opts: ZodResponseOptions) => MethodDecorator;
|
|
458
471
|
|
package/dist/index.js
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
var zod = require('zod');
|
|
4
4
|
var common = require('@nestjs/common');
|
|
5
|
+
var constants_js = require('@nestjs/common/constants.js');
|
|
6
|
+
var swagger = require('@nestjs/swagger');
|
|
5
7
|
var core = require('@nestjs/core');
|
|
6
8
|
var rxjs = require('rxjs');
|
|
7
9
|
var operators = require('rxjs/operators');
|
|
8
|
-
var constants_js = require('@nestjs/common/constants.js');
|
|
9
10
|
var stringify = require('fast-json-stable-stringify');
|
|
10
11
|
|
|
11
12
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -924,6 +925,25 @@ exports.ZodValidationPipe = _ts_decorate([
|
|
|
924
925
|
typeof NormalizedZodNestOptions === "undefined" ? Object : NormalizedZodNestOptions
|
|
925
926
|
])
|
|
926
927
|
], exports.ZodValidationPipe);
|
|
928
|
+
var POST_DEFAULT_STATUS = 201;
|
|
929
|
+
var GENERIC_DEFAULT_STATUS = 200;
|
|
930
|
+
var defaultStatusFor = /* @__PURE__ */ __name((handler) => {
|
|
931
|
+
const httpCode = Reflect.getMetadata(constants_js.HTTP_CODE_METADATA, handler);
|
|
932
|
+
if (typeof httpCode === "number") {
|
|
933
|
+
return httpCode;
|
|
934
|
+
}
|
|
935
|
+
const method = Reflect.getMetadata(constants_js.METHOD_METADATA, handler);
|
|
936
|
+
if (method === common.RequestMethod.POST) {
|
|
937
|
+
return POST_DEFAULT_STATUS;
|
|
938
|
+
}
|
|
939
|
+
return GENERIC_DEFAULT_STATUS;
|
|
940
|
+
}, "defaultStatusFor");
|
|
941
|
+
var resolveEffectiveStatus = /* @__PURE__ */ __name((variant, handler) => {
|
|
942
|
+
if (variant.status !== void 0) {
|
|
943
|
+
return variant.status;
|
|
944
|
+
}
|
|
945
|
+
return defaultStatusFor(handler);
|
|
946
|
+
}, "resolveEffectiveStatus");
|
|
927
947
|
|
|
928
948
|
// src/response/metadata.ts
|
|
929
949
|
var ZOD_RESPONSES_METADATA_KEY = /* @__PURE__ */ Symbol.for("zod-nest.responses");
|
|
@@ -938,6 +958,67 @@ var appendResponseVariant = /* @__PURE__ */ __name((handler, variant) => {
|
|
|
938
958
|
...existing
|
|
939
959
|
], handler);
|
|
940
960
|
}, "appendResponseVariant");
|
|
961
|
+
var extractDescriptionFields = /* @__PURE__ */ __name((desc) => {
|
|
962
|
+
if (desc === void 0) {
|
|
963
|
+
return {};
|
|
964
|
+
}
|
|
965
|
+
if (typeof desc === "string") {
|
|
966
|
+
return {
|
|
967
|
+
description: desc
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
const out = {
|
|
971
|
+
description: desc.description
|
|
972
|
+
};
|
|
973
|
+
if (desc.headers !== void 0) {
|
|
974
|
+
out.headers = desc.headers;
|
|
975
|
+
}
|
|
976
|
+
if (desc.links !== void 0) {
|
|
977
|
+
out.links = desc.links;
|
|
978
|
+
}
|
|
979
|
+
return out;
|
|
980
|
+
}, "extractDescriptionFields");
|
|
981
|
+
var asDtoFunction = /* @__PURE__ */ __name((dto) => dto, "asDtoFunction");
|
|
982
|
+
var buildApiResponseOptions = /* @__PURE__ */ __name((base, body) => {
|
|
983
|
+
return {
|
|
984
|
+
...base,
|
|
985
|
+
...body
|
|
986
|
+
};
|
|
987
|
+
}, "buildApiResponseOptions");
|
|
988
|
+
var applySwaggerResponseDecorator = /* @__PURE__ */ __name((variant, effectiveStatus, target, propertyKey, descriptor) => {
|
|
989
|
+
const base = {
|
|
990
|
+
status: effectiveStatus,
|
|
991
|
+
...extractDescriptionFields(variant.description)
|
|
992
|
+
};
|
|
993
|
+
if (variant.kind === "single") {
|
|
994
|
+
const dto = variant.dto;
|
|
995
|
+
swagger.ApiResponse(buildApiResponseOptions(base, {
|
|
996
|
+
type: asDtoFunction(dto)
|
|
997
|
+
}))(target, propertyKey, descriptor);
|
|
998
|
+
return;
|
|
999
|
+
}
|
|
1000
|
+
if (variant.kind === "array") {
|
|
1001
|
+
const dtos2 = variant.dto;
|
|
1002
|
+
const dto = dtos2[0];
|
|
1003
|
+
swagger.ApiResponse(buildApiResponseOptions(base, {
|
|
1004
|
+
type: asDtoFunction(dto),
|
|
1005
|
+
isArray: true
|
|
1006
|
+
}))(target, propertyKey, descriptor);
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
const dtos = variant.dto;
|
|
1010
|
+
swagger.ApiExtraModels(...dtos.map(asDtoFunction))(target, propertyKey, descriptor);
|
|
1011
|
+
const schema = {
|
|
1012
|
+
type: "array",
|
|
1013
|
+
prefixItems: dtos.map((d) => ({
|
|
1014
|
+
$ref: swagger.getSchemaPath(asDtoFunction(d))
|
|
1015
|
+
})),
|
|
1016
|
+
items: false
|
|
1017
|
+
};
|
|
1018
|
+
swagger.ApiResponse(buildApiResponseOptions(base, {
|
|
1019
|
+
schema
|
|
1020
|
+
}))(target, propertyKey, descriptor);
|
|
1021
|
+
}, "applySwaggerResponseDecorator");
|
|
941
1022
|
|
|
942
1023
|
// src/decorators/zod-response.decorator.ts
|
|
943
1024
|
var buildArrayKind = /* @__PURE__ */ __name((dtos) => {
|
|
@@ -991,7 +1072,8 @@ var normaliseStatus = /* @__PURE__ */ __name((status) => {
|
|
|
991
1072
|
var ZodResponse = /* @__PURE__ */ __name((opts) => {
|
|
992
1073
|
const built = buildKind(opts.type);
|
|
993
1074
|
const status = normaliseStatus(opts.status);
|
|
994
|
-
|
|
1075
|
+
const statusExplicit = status !== void 0;
|
|
1076
|
+
return (target, propertyKey, descriptor) => {
|
|
995
1077
|
const handler = descriptor.value;
|
|
996
1078
|
if (typeof handler !== "function") {
|
|
997
1079
|
throw new TypeError("[zod-nest] @ZodResponse can only be applied to methods.");
|
|
@@ -1005,29 +1087,17 @@ var ZodResponse = /* @__PURE__ */ __name((opts) => {
|
|
|
1005
1087
|
passthroughOnError: opts.passthroughOnError ?? false
|
|
1006
1088
|
};
|
|
1007
1089
|
appendResponseVariant(handler, variant);
|
|
1090
|
+
const swaggerDescriptor = descriptor;
|
|
1091
|
+
if (statusExplicit) {
|
|
1092
|
+
applySwaggerResponseDecorator(variant, status, target, propertyKey, swaggerDescriptor);
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
queueMicrotask(() => {
|
|
1096
|
+
const effective = resolveEffectiveStatus(variant, handler);
|
|
1097
|
+
applySwaggerResponseDecorator(variant, effective, target, propertyKey, swaggerDescriptor);
|
|
1098
|
+
});
|
|
1008
1099
|
};
|
|
1009
1100
|
}, "ZodResponse");
|
|
1010
|
-
var POST_DEFAULT_STATUS = 201;
|
|
1011
|
-
var GENERIC_DEFAULT_STATUS = 200;
|
|
1012
|
-
var defaultStatusFor = /* @__PURE__ */ __name((handler) => {
|
|
1013
|
-
const httpCode = Reflect.getMetadata(constants_js.HTTP_CODE_METADATA, handler);
|
|
1014
|
-
if (typeof httpCode === "number") {
|
|
1015
|
-
return httpCode;
|
|
1016
|
-
}
|
|
1017
|
-
const method = Reflect.getMetadata(constants_js.METHOD_METADATA, handler);
|
|
1018
|
-
if (method === common.RequestMethod.POST) {
|
|
1019
|
-
return POST_DEFAULT_STATUS;
|
|
1020
|
-
}
|
|
1021
|
-
return GENERIC_DEFAULT_STATUS;
|
|
1022
|
-
}, "defaultStatusFor");
|
|
1023
|
-
var resolveEffectiveStatus = /* @__PURE__ */ __name((variant, handler) => {
|
|
1024
|
-
if (variant.status !== void 0) {
|
|
1025
|
-
return variant.status;
|
|
1026
|
-
}
|
|
1027
|
-
return defaultStatusFor(handler);
|
|
1028
|
-
}, "resolveEffectiveStatus");
|
|
1029
|
-
|
|
1030
|
-
// src/interceptors/serializer.interceptor.ts
|
|
1031
1101
|
function _ts_decorate2(decorators, target, key, desc) {
|
|
1032
1102
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1033
1103
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|