zod-nest 3.1.0 → 3.2.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/express/index.d.mts +5 -5
- package/dist/express/index.d.ts +5 -5
- package/dist/express/index.js +195 -26
- package/dist/express/index.js.map +1 -1
- package/dist/express/index.mjs +195 -26
- package/dist/express/index.mjs.map +1 -1
- package/dist/fastify/index.d.mts +5 -5
- package/dist/fastify/index.d.ts +5 -5
- package/dist/fastify/index.js +195 -26
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/index.mjs +195 -26
- package/dist/fastify/index.mjs.map +1 -1
- package/dist/{zod-multipart.decorator-CjiQkmkR.d.ts → param-decorators-CX1cUqfY.d.ts} +52 -33
- package/dist/{zod-multipart.decorator-CxS2KuSv.d.mts → param-decorators-DbgygRVn.d.mts} +52 -33
- package/package.json +1 -1
package/dist/fastify/index.mjs
CHANGED
|
@@ -103,15 +103,18 @@ var sizeCheck = /* @__PURE__ */ __name((readSize, options) => {
|
|
|
103
103
|
// src/multipart/file-marker.ts
|
|
104
104
|
var fileSchemas = /* @__PURE__ */ new WeakSet();
|
|
105
105
|
var isZodType = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && "_zod" in value, "isZodType");
|
|
106
|
-
var
|
|
107
|
-
const def = schema._zod.def;
|
|
106
|
+
var innerOf = /* @__PURE__ */ __name((def) => {
|
|
108
107
|
if ("innerType" in def) {
|
|
109
|
-
return
|
|
108
|
+
return def.innerType;
|
|
110
109
|
}
|
|
111
110
|
if ("element" in def) {
|
|
112
|
-
return
|
|
111
|
+
return def.element;
|
|
113
112
|
}
|
|
114
113
|
return void 0;
|
|
114
|
+
}, "innerOf");
|
|
115
|
+
var unwrapOnce = /* @__PURE__ */ __name((schema) => {
|
|
116
|
+
const inner = innerOf(schema._zod.def);
|
|
117
|
+
return isZodType(inner) ? inner : void 0;
|
|
115
118
|
}, "unwrapOnce");
|
|
116
119
|
var markFileSchema = /* @__PURE__ */ __name((schema) => {
|
|
117
120
|
fileSchemas.add(schema);
|
|
@@ -787,12 +790,172 @@ var toOpenApi = /* @__PURE__ */ __name((schema, opts) => {
|
|
|
787
790
|
return result;
|
|
788
791
|
}, "toOpenApi");
|
|
789
792
|
|
|
793
|
+
// src/schema/anon-id.ts
|
|
794
|
+
var ANON_BODY_PREFIX = "_AnonBodySchema_";
|
|
795
|
+
var anonIdCache = /* @__PURE__ */ new WeakMap();
|
|
796
|
+
var counter = 0;
|
|
797
|
+
var resolveAnonId = /* @__PURE__ */ __name((schema, prefix) => {
|
|
798
|
+
const cached = anonIdCache.get(schema);
|
|
799
|
+
if (cached !== void 0) {
|
|
800
|
+
return cached;
|
|
801
|
+
}
|
|
802
|
+
counter += 1;
|
|
803
|
+
const id = `${prefix}${counter}`;
|
|
804
|
+
anonIdCache.set(schema, id);
|
|
805
|
+
return id;
|
|
806
|
+
}, "resolveAnonId");
|
|
807
|
+
|
|
808
|
+
// src/decorators/internal/zod-schema-ref.ts
|
|
809
|
+
function resolveSchemaRef(schema, options) {
|
|
810
|
+
const registry = options?.registry ?? defaultRegistry;
|
|
811
|
+
const id = registerSchema(schema, registry, {
|
|
812
|
+
id: options?.id
|
|
813
|
+
});
|
|
814
|
+
if (id !== void 0) {
|
|
815
|
+
return {
|
|
816
|
+
kind: "ref",
|
|
817
|
+
ref: {
|
|
818
|
+
$ref: `${COMPONENTS_SCHEMAS_PREFIX}${id}`
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
if (options?.deferAnonInline === true) {
|
|
823
|
+
const anonId = resolveAnonId(schema, ANON_BODY_PREFIX);
|
|
824
|
+
registerSchema(schema, registry, {
|
|
825
|
+
id: anonId,
|
|
826
|
+
anonymous: true
|
|
827
|
+
});
|
|
828
|
+
return {
|
|
829
|
+
kind: "ref",
|
|
830
|
+
ref: {
|
|
831
|
+
$ref: `${COMPONENTS_SCHEMAS_PREFIX}${anonId}`
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
for (const [child, childId] of discoverDependents(schema)) {
|
|
836
|
+
registry.register(child, childId);
|
|
837
|
+
}
|
|
838
|
+
const { schema: body } = toOpenApi(schema, {
|
|
839
|
+
io: "input",
|
|
840
|
+
registry
|
|
841
|
+
});
|
|
842
|
+
return {
|
|
843
|
+
kind: "inline",
|
|
844
|
+
schema: body
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
__name(resolveSchemaRef, "resolveSchemaRef");
|
|
848
|
+
|
|
849
|
+
// src/decorators/internal/zod-param-expand.ts
|
|
850
|
+
var isZodObject = /* @__PURE__ */ __name((schema) => schema._zod.def.type === "object", "isZodObject");
|
|
851
|
+
|
|
852
|
+
// src/decorators/internal/flatten-intersection.ts
|
|
853
|
+
var intersectionArms = /* @__PURE__ */ __name((schema) => {
|
|
854
|
+
if (schema._zod.def.type !== "intersection") {
|
|
855
|
+
return null;
|
|
856
|
+
}
|
|
857
|
+
const def = schema._zod.def;
|
|
858
|
+
return {
|
|
859
|
+
left: def.left,
|
|
860
|
+
right: def.right
|
|
861
|
+
};
|
|
862
|
+
}, "intersectionArms");
|
|
863
|
+
var unionOptions = /* @__PURE__ */ __name((schema) => {
|
|
864
|
+
if (schema._zod.def.type !== "union") {
|
|
865
|
+
return null;
|
|
866
|
+
}
|
|
867
|
+
const def = schema._zod.def;
|
|
868
|
+
return def.options;
|
|
869
|
+
}, "unionOptions");
|
|
870
|
+
var collectObjectShapes = /* @__PURE__ */ __name((schema) => {
|
|
871
|
+
if (isZodObject(schema)) {
|
|
872
|
+
return {
|
|
873
|
+
shapes: [
|
|
874
|
+
schema.shape
|
|
875
|
+
],
|
|
876
|
+
unionCrossed: false
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
const options = unionOptions(schema);
|
|
880
|
+
if (options !== null) {
|
|
881
|
+
const allShapes = [];
|
|
882
|
+
for (const variant of options) {
|
|
883
|
+
const variantResult = collectObjectShapes(variant);
|
|
884
|
+
if (variantResult === null) {
|
|
885
|
+
return null;
|
|
886
|
+
}
|
|
887
|
+
allShapes.push(...variantResult.shapes);
|
|
888
|
+
}
|
|
889
|
+
return {
|
|
890
|
+
shapes: allShapes,
|
|
891
|
+
unionCrossed: true
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
const arms = intersectionArms(schema);
|
|
895
|
+
if (arms === null) {
|
|
896
|
+
return null;
|
|
897
|
+
}
|
|
898
|
+
const left = collectObjectShapes(arms.left);
|
|
899
|
+
if (left === null) {
|
|
900
|
+
return null;
|
|
901
|
+
}
|
|
902
|
+
const right = collectObjectShapes(arms.right);
|
|
903
|
+
if (right === null) {
|
|
904
|
+
return null;
|
|
905
|
+
}
|
|
906
|
+
return {
|
|
907
|
+
shapes: [
|
|
908
|
+
...left.shapes,
|
|
909
|
+
...right.shapes
|
|
910
|
+
],
|
|
911
|
+
unionCrossed: left.unionCrossed || right.unionCrossed
|
|
912
|
+
};
|
|
913
|
+
}, "collectObjectShapes");
|
|
914
|
+
var flattenObjectIntersection = /* @__PURE__ */ __name((schema, registry, decoratorName) => {
|
|
915
|
+
const collected = collectObjectShapes(schema);
|
|
916
|
+
if (collected === null) {
|
|
917
|
+
throw new ZodNestError(`${decoratorName} \`flatten: true\` requires every leaf of the schema to be a \`z.object({...})\` \u2014 intersections and unions of objects are supported, but primitives, tuples, transforms, and other non-object leaves are not. Drop \`flatten: true\` to emit the original schema with its composition intact.`);
|
|
918
|
+
}
|
|
919
|
+
const mergedShape = {};
|
|
920
|
+
for (const shape of collected.shapes) {
|
|
921
|
+
Object.assign(mergedShape, shape);
|
|
922
|
+
}
|
|
923
|
+
if (collected.unionCrossed) {
|
|
924
|
+
for (const key of Object.keys(mergedShape)) {
|
|
925
|
+
const value = mergedShape[key];
|
|
926
|
+
if (value !== void 0) {
|
|
927
|
+
mergedShape[key] = value.optional();
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
const merged = z.object(mergedShape);
|
|
932
|
+
registerSchema(schema, registry);
|
|
933
|
+
for (const [child, childId] of discoverDependents(schema)) {
|
|
934
|
+
registry.register(child, childId);
|
|
935
|
+
}
|
|
936
|
+
const { schema: body } = toOpenApi(merged, {
|
|
937
|
+
io: "input",
|
|
938
|
+
registry
|
|
939
|
+
});
|
|
940
|
+
return body;
|
|
941
|
+
}, "flattenObjectIntersection");
|
|
942
|
+
var isZodSchema = /* @__PURE__ */ __name((value) => value instanceof z.ZodType, "isZodSchema");
|
|
943
|
+
|
|
790
944
|
// src/multipart/zod-multipart.decorator.ts
|
|
791
945
|
var MULTIPART_CONTENT_TYPE = "multipart/form-data";
|
|
946
|
+
var toSchema = /* @__PURE__ */ __name((body) => isZodSchema(body) ? body : z.object({
|
|
947
|
+
...body
|
|
948
|
+
}), "toSchema");
|
|
949
|
+
var toShape = /* @__PURE__ */ __name((body) => {
|
|
950
|
+
if (!isZodSchema(body)) {
|
|
951
|
+
return body;
|
|
952
|
+
}
|
|
953
|
+
return isZodObject(body) ? body.shape : void 0;
|
|
954
|
+
}, "toShape");
|
|
792
955
|
var partitionKeys = /* @__PURE__ */ __name((shape) => {
|
|
793
956
|
const fileKeys = [];
|
|
794
957
|
const textKeys = [];
|
|
795
|
-
for (const [key, schema] of Object.entries(shape)) {
|
|
958
|
+
for (const [key, schema] of Object.entries(shape ?? {})) {
|
|
796
959
|
if (isFileSchema(schema)) {
|
|
797
960
|
fileKeys.push(key);
|
|
798
961
|
continue;
|
|
@@ -804,30 +967,28 @@ var partitionKeys = /* @__PURE__ */ __name((shape) => {
|
|
|
804
967
|
textKeys
|
|
805
968
|
};
|
|
806
969
|
}, "partitionKeys");
|
|
807
|
-
var
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
});
|
|
811
|
-
for (const [child, childId] of discoverDependents(object)) {
|
|
812
|
-
registry.register(child, childId);
|
|
970
|
+
var resolveBody = /* @__PURE__ */ __name((schema, options, registry) => {
|
|
971
|
+
if (options?.flatten === true) {
|
|
972
|
+
return flattenObjectIntersection(schema, registry, "@ZodMultipart");
|
|
813
973
|
}
|
|
814
|
-
const
|
|
815
|
-
|
|
974
|
+
const resolved = resolveSchemaRef(schema, {
|
|
975
|
+
...options?.id !== void 0 ? {
|
|
976
|
+
id: options.id
|
|
977
|
+
} : {},
|
|
816
978
|
registry
|
|
817
979
|
});
|
|
818
|
-
return schema;
|
|
819
|
-
}, "
|
|
980
|
+
return resolved.kind === "ref" ? resolved.ref : resolved.schema;
|
|
981
|
+
}, "resolveBody");
|
|
820
982
|
var createZodMultipart = /* @__PURE__ */ __name((defaultFilesIn) => {
|
|
821
|
-
return (
|
|
983
|
+
return (body, options) => {
|
|
822
984
|
const registry = options?.registry ?? defaultRegistry;
|
|
823
|
-
const
|
|
985
|
+
const shape = toShape(body);
|
|
824
986
|
const metadata = {
|
|
825
987
|
shape,
|
|
826
|
-
|
|
827
|
-
textKeys,
|
|
988
|
+
...partitionKeys(shape),
|
|
828
989
|
filesIn: options?.filesIn ?? defaultFilesIn
|
|
829
990
|
};
|
|
830
|
-
const
|
|
991
|
+
const schema = resolveBody(toSchema(body), options, registry);
|
|
831
992
|
return (target, propertyKey, descriptor) => {
|
|
832
993
|
const handler = descriptor.value;
|
|
833
994
|
if (typeof handler !== "function") {
|
|
@@ -837,7 +998,7 @@ var createZodMultipart = /* @__PURE__ */ __name((defaultFilesIn) => {
|
|
|
837
998
|
const swaggerDescriptor = descriptor;
|
|
838
999
|
ApiConsumes(MULTIPART_CONTENT_TYPE)(target, propertyKey, swaggerDescriptor);
|
|
839
1000
|
ApiBody({
|
|
840
|
-
schema
|
|
1001
|
+
schema,
|
|
841
1002
|
...options?.description !== void 0 ? {
|
|
842
1003
|
description: options.description
|
|
843
1004
|
} : {},
|
|
@@ -874,10 +1035,17 @@ var readMetadata = /* @__PURE__ */ __name((ctx, decorator) => {
|
|
|
874
1035
|
return metadata;
|
|
875
1036
|
}, "readMetadata");
|
|
876
1037
|
var isMultipartMetadata = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && "shape" in value && "filesIn" in value, "isMultipartMetadata");
|
|
1038
|
+
var requireShape = /* @__PURE__ */ __name((metadata, decorator) => {
|
|
1039
|
+
if (metadata.shape !== void 0) {
|
|
1040
|
+
return metadata.shape;
|
|
1041
|
+
}
|
|
1042
|
+
throw new Error(`[zod-nest] ${decorator} needs a flat body shape, but @ZodMultipart was given a composite schema (an intersection or union). Validate it with @Body(new ZodValidationPipe(schema)) instead.`);
|
|
1043
|
+
}, "requireShape");
|
|
877
1044
|
var schemaFor = /* @__PURE__ */ __name((metadata, name, decorator) => {
|
|
878
|
-
const
|
|
1045
|
+
const shape = requireShape(metadata, decorator);
|
|
1046
|
+
const schema = shape[name];
|
|
879
1047
|
if (schema === void 0) {
|
|
880
|
-
throw new Error(`[zod-nest] ${decorator}('${name}') has no matching property in the @ZodMultipart shape. Declared: ${Object.keys(
|
|
1048
|
+
throw new Error(`[zod-nest] ${decorator}('${name}') has no matching property in the @ZodMultipart shape. Declared: ${Object.keys(shape).join(", ")}.`);
|
|
881
1049
|
}
|
|
882
1050
|
return schema;
|
|
883
1051
|
}, "schemaFor");
|
|
@@ -918,14 +1086,15 @@ var resolveUploadedFiles = /* @__PURE__ */ __name(async (name, ctx) => {
|
|
|
918
1086
|
const metadata = readMetadata(ctx, "@ZodUploadedFiles");
|
|
919
1087
|
assertFilesOnRequest(metadata, "@ZodUploadedFiles");
|
|
920
1088
|
const request = ctx.switchToHttp().getRequest();
|
|
921
|
-
const schema = name === void 0 ? pick(metadata
|
|
1089
|
+
const schema = name === void 0 ? pick(requireShape(metadata, "@ZodUploadedFiles"), metadata.fileKeys) : schemaFor(metadata, name, "@ZodUploadedFiles");
|
|
922
1090
|
return validate(schema, request.files, "custom");
|
|
923
1091
|
}, "resolveUploadedFiles");
|
|
924
1092
|
var resolveMultipartBody = /* @__PURE__ */ __name(async (_data, ctx) => {
|
|
925
1093
|
const metadata = readMetadata(ctx, "@ZodMultipartBody");
|
|
1094
|
+
const shape = requireShape(metadata, "@ZodMultipartBody");
|
|
926
1095
|
const request = ctx.switchToHttp().getRequest();
|
|
927
|
-
const keys = metadata.filesIn === MultipartFilesIn.Body ? Object.keys(
|
|
928
|
-
return validate(pick(
|
|
1096
|
+
const keys = metadata.filesIn === MultipartFilesIn.Body ? Object.keys(shape) : metadata.textKeys;
|
|
1097
|
+
return validate(pick(shape, keys), request.body, "body");
|
|
929
1098
|
}, "resolveMultipartBody");
|
|
930
1099
|
createParamDecorator(resolveUploadedFile);
|
|
931
1100
|
createParamDecorator(resolveUploadedFiles);
|