diff --git a/.changeset/funny-penguins-speak.md b/.changeset/funny-penguins-speak.md new file mode 100644 index 000000000..83005a03e --- /dev/null +++ b/.changeset/funny-penguins-speak.md @@ -0,0 +1,5 @@ +--- +'@hey-api/openapi-ts': minor +--- + +fix(plugins/zod): fix support for string type in binary format diff --git a/packages/openapi-ts/src/plugins/zod/plugin.ts b/packages/openapi-ts/src/plugins/zod/plugin.ts index 9c5321ee2..1624dad65 100644 --- a/packages/openapi-ts/src/plugins/zod/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/plugin.ts @@ -35,6 +35,7 @@ const optionalIdentifier = compiler.identifier({ text: 'optional' }); const readonlyIdentifier = compiler.identifier({ text: 'readonly' }); const regexIdentifier = compiler.identifier({ text: 'regex' }); const unionIdentifier = compiler.identifier({ text: 'union' }); +const instanceofIdentifier = compiler.identifier({ text: 'instanceof' }); const zIdentifier = compiler.identifier({ text: 'z' }); const nameTransformer = (name: string) => `z-${name}`; @@ -493,6 +494,26 @@ const stringTypeToZodSchema = ({ }), }); break; + case 'binary': + stringExpression = compiler.callExpression({ + functionName: compiler.propertyAccessExpression({ + expression: zIdentifier, + name: unionIdentifier, + }), + parameters: [ + compiler.arrayLiteralExpression({ + elements: ['File', 'Blob'].map((typeIdent) => + compiler.callExpression({ + functionName: compiler.propertyAccessExpression({ + expression: zIdentifier, + name: instanceofIdentifier, + }), + parameters: [compiler.identifier({ text: typeIdent })], + }), + ), + }), + ], + }); } } diff --git a/packages/openapi-ts/test/__snapshots__/2.0.x/plugins/zod/default/zod.gen.ts b/packages/openapi-ts/test/__snapshots__/2.0.x/plugins/zod/default/zod.gen.ts index 64f8926c5..8c0eeed34 100644 --- a/packages/openapi-ts/test/__snapshots__/2.0.x/plugins/zod/default/zod.gen.ts +++ b/packages/openapi-ts/test/__snapshots__/2.0.x/plugins/zod/default/zod.gen.ts @@ -24,7 +24,10 @@ export const zSimpleString = z.string(); export const zNonAsciiStringæøåÆøÅöôêÊ字符串 = z.string(); -export const zSimpleFile = z.string(); +export const zSimpleFile = z.union([ + z.instanceof(File), + z.instanceof(Blob) +]); export const zSimpleReference = z.object({ prop: z.string().optional() @@ -156,7 +159,10 @@ export const zModelWithReference = z.object({ export const zModelWithArray = z.object({ prop: z.array(zModelWithString).optional(), - propWithFile: z.array(z.string()).optional(), + propWithFile: z.array(z.union([ + z.instanceof(File), + z.instanceof(Blob) + ])).optional(), propWithNumber: z.array(z.number()).optional() }); @@ -286,4 +292,4 @@ export const zComplexTypesResponse = z.array(zModelWithString); export const zNonAsciiæøåÆøÅöôêÊ字符串Response = zNonAsciiStringæøåÆøÅöôêÊ字符串; -export const zPostApiVbyApiVersionBodyResponse = zResponsePostActivityResponse; \ No newline at end of file +export const zPostApiVbyApiVersionBodyResponse = zResponsePostActivityResponse; diff --git a/packages/openapi-ts/test/__snapshots__/3.0.x/plugins/zod/default/zod.gen.ts b/packages/openapi-ts/test/__snapshots__/3.0.x/plugins/zod/default/zod.gen.ts index a7d288b50..35c1c9261 100644 --- a/packages/openapi-ts/test/__snapshots__/3.0.x/plugins/zod/default/zod.gen.ts +++ b/packages/openapi-ts/test/__snapshots__/3.0.x/plugins/zod/default/zod.gen.ts @@ -28,7 +28,10 @@ export const zSimpleString = z.string(); export const zNonAsciiStringæøåÆøÅöôêÊ字符串 = z.string(); -export const zSimpleFile = z.string(); +export const zSimpleFile = z.union([ + z.instanceof(File), + z.instanceof(Blob) +]); export const zSimpleReference = z.object({ prop: z.string().optional() @@ -221,13 +224,19 @@ export const zModelWithArrayReadOnlyAndWriteOnly = z.object({ bar: z.string().readonly(), baz: z.string() })).optional(), - propWithFile: z.array(z.string()).optional(), + propWithFile: z.array(z.union([ + z.instanceof(File), + z.instanceof(Blob) + ])).optional(), propWithNumber: z.array(z.number()).optional() }); export const zModelWithArray = z.object({ prop: z.array(zModelWithString).optional(), - propWithFile: z.array(z.string()).optional(), + propWithFile: z.array(z.union([ + z.instanceof(File), + z.instanceof(Blob) + ])).optional(), propWithNumber: z.array(z.number()).optional() }); @@ -791,12 +800,18 @@ export const zTypesResponse = z.union([ export const zUploadFileResponse = z.boolean(); -export const zFileResponseResponse = z.string(); +export const zFileResponseResponse = z.union([ + z.instanceof(File), + z.instanceof(Blob) +]); export const zComplexTypesResponse = z.array(zModelWithString); export const zMultipartResponseResponse = z.object({ - file: z.string().optional(), + file: z.union([ + z.instanceof(File), + z.instanceof(Blob) + ]).optional(), metadata: z.object({ foo: z.string().optional(), bar: z.string().optional() @@ -805,4 +820,4 @@ export const zMultipartResponseResponse = z.object({ export const zComplexParamsResponse = zModelWithString; -export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); \ No newline at end of file +export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); diff --git a/packages/openapi-ts/test/__snapshots__/3.1.x/plugins/zod/default/zod.gen.ts b/packages/openapi-ts/test/__snapshots__/3.1.x/plugins/zod/default/zod.gen.ts index 789aa4254..e616ff028 100644 --- a/packages/openapi-ts/test/__snapshots__/3.1.x/plugins/zod/default/zod.gen.ts +++ b/packages/openapi-ts/test/__snapshots__/3.1.x/plugins/zod/default/zod.gen.ts @@ -28,7 +28,10 @@ export const zSimpleString = z.string(); export const zNonAsciiStringæøåÆøÅöôêÊ字符串 = z.string(); -export const zSimpleFile = z.string(); +export const zSimpleFile = z.union([ + z.instanceof(File), + z.instanceof(Blob) +]); export const zSimpleReference = z.object({ prop: z.string().optional() @@ -224,13 +227,19 @@ export const zModelWithArrayReadOnlyAndWriteOnly = z.object({ bar: z.string().readonly(), baz: z.string() })).optional(), - propWithFile: z.array(z.string()).optional(), + propWithFile: z.array(z.union([ + z.instanceof(File), + z.instanceof(Blob) + ])).optional(), propWithNumber: z.array(z.number()).optional() }); export const zModelWithArray = z.object({ prop: z.array(zModelWithString).optional(), - propWithFile: z.array(z.string()).optional(), + propWithFile: z.array(z.union([ + z.instanceof(File), + z.instanceof(Blob) + ])).optional(), propWithNumber: z.array(z.number()).optional() }); @@ -782,12 +791,18 @@ export const zTypesResponse = z.union([ export const zUploadFileResponse = z.boolean(); -export const zFileResponseResponse = z.string(); +export const zFileResponseResponse = z.union([ + z.instanceof(File), + z.instanceof(Blob) +]); export const zComplexTypesResponse = z.array(zModelWithString); export const zMultipartResponseResponse = z.object({ - file: z.string().optional(), + file: z.union([ + z.instanceof(File), + z.instanceof(Blob) + ]).optional(), metadata: z.object({ foo: z.string().optional(), bar: z.string().optional() @@ -796,4 +811,4 @@ export const zMultipartResponseResponse = z.object({ export const zComplexParamsResponse = zModelWithString; -export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); \ No newline at end of file +export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串);