From dbb61e5e08a904ffa217dd736d100cfdb48f66e9 Mon Sep 17 00:00:00 2001 From: Ned <7358345+nedpals@users.noreply.github.com> Date: Thu, 23 Jan 2025 15:57:20 +0800 Subject: [PATCH 1/4] feat(plugins/zod): add support for string types in binary format --- packages/openapi-ts/src/plugins/zod/plugin.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/openapi-ts/src/plugins/zod/plugin.ts b/packages/openapi-ts/src/plugins/zod/plugin.ts index 9c5321ee24..ba604839e5 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 })] + }) + )), + }), + ], + }) } } From 95b0d6b414215a24246fee68f00f1ad632dfa3be Mon Sep 17 00:00:00 2001 From: Ned Palacios Date: Thu, 23 Jan 2025 16:14:39 +0800 Subject: [PATCH 2/4] fix: add changeset --- .changeset/funny-penguins-speak.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/funny-penguins-speak.md diff --git a/.changeset/funny-penguins-speak.md b/.changeset/funny-penguins-speak.md new file mode 100644 index 0000000000..83005a03e8 --- /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 From d6da03c50ef8d496dada45fd5bcf26356fa7165f Mon Sep 17 00:00:00 2001 From: Ned Palacios Date: Thu, 23 Jan 2025 16:14:52 +0800 Subject: [PATCH 3/4] fix: style and lint --- packages/openapi-ts/src/plugins/zod/plugin.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/openapi-ts/src/plugins/zod/plugin.ts b/packages/openapi-ts/src/plugins/zod/plugin.ts index ba604839e5..1624dad65b 100644 --- a/packages/openapi-ts/src/plugins/zod/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/plugin.ts @@ -502,18 +502,18 @@ const stringTypeToZodSchema = ({ }), parameters: [ compiler.arrayLiteralExpression({ - elements: ['File', 'Blob'].map(typeIdent => ( + elements: ['File', 'Blob'].map((typeIdent) => compiler.callExpression({ functionName: compiler.propertyAccessExpression({ expression: zIdentifier, name: instanceofIdentifier, }), - parameters: [compiler.identifier({ text: typeIdent })] - }) - )), + parameters: [compiler.identifier({ text: typeIdent })], + }), + ), }), ], - }) + }); } } From f84102871a933a2dfcf50abb39dac9ecab18375b Mon Sep 17 00:00:00 2001 From: Ned Palacios Date: Fri, 24 Jan 2025 22:34:48 +0800 Subject: [PATCH 4/4] fix: tests --- .../2.0.x/plugins/zod/default/zod.gen.ts | 12 ++++++--- .../3.0.x/plugins/zod/default/zod.gen.ts | 27 ++++++++++++++----- .../3.1.x/plugins/zod/default/zod.gen.ts | 27 ++++++++++++++----- 3 files changed, 51 insertions(+), 15 deletions(-) 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 64f8926c5f..8c0eeed34d 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 a7d288b50b..35c1c92612 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 789aa42548..e616ff028b 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æøåÆøÅöôêÊ字符串);