Skip to content

Commit

Permalink
fix(zod): date format now respects useDates override (#1406)
Browse files Browse the repository at this point in the history
* fix(zod): date format now respects useDates override

* chore(zod): get tests passing, fix coercion issue and incorperate feedback
  • Loading branch information
TommoLeedsy authored May 29, 2024
1 parent 3dd831b commit 36ebf4f
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 13 deletions.
40 changes: 34 additions & 6 deletions packages/zod/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ const COERCEABLE_TYPES = ['string', 'number', 'boolean', 'bigint', 'date'];

export const generateZodValidationSchemaDefinition = (
schema: SchemaObject | undefined,
context: ContextSpecs,
_required: boolean | undefined,
name: string,
strict: boolean,
Expand Down Expand Up @@ -118,6 +119,7 @@ export const generateZodValidationSchemaDefinition = (
'array',
generateZodValidationSchemaDefinition(
items,
context,
true,
camel(`${name}-item`),
strict,
Expand All @@ -129,13 +131,21 @@ export const generateZodValidationSchemaDefinition = (
break;
}

if (schema.format === 'date') {
if (
context.output.override.useDates &&
(schema.format === 'date' || schema.format === 'date-time')
) {
functions.push(['date', undefined]);
break;
}

functions.push([type as string, undefined]);

if (schema.format === 'date') {
functions.push(['date', undefined]);
break;
}

if (schema.format === 'date-time') {
functions.push(['datetime', undefined]);
break;
Expand Down Expand Up @@ -177,6 +187,7 @@ export const generateZodValidationSchemaDefinition = (
schemas.map((schema) =>
generateZodValidationSchemaDefinition(
schema as SchemaObject,
context,
true,
camel(name),
strict,
Expand All @@ -193,6 +204,7 @@ export const generateZodValidationSchemaDefinition = (
.map((key) => ({
[key]: generateZodValidationSchemaDefinition(
schema.properties?.[key] as any,
context,
schema.required?.includes(key),
camel(`${name}-${key}`),
strict,
Expand All @@ -215,6 +227,7 @@ export const generateZodValidationSchemaDefinition = (
? schema.additionalProperties
: generateZodValidationSchemaDefinition(
schema.additionalProperties as SchemaObject,
context,
true,
name,
strict,
Expand Down Expand Up @@ -285,6 +298,7 @@ export type ZodValidationSchemaDefinitionInput = {

export const parseZodValidationSchemaDefinition = (
input: ZodValidationSchemaDefinitionInput,
contex: ContextSpecs,
coerceTypes: boolean | ZodCoerceType[] = false,
preprocessResponse?: GeneratorMutator,
): { zod: string; consts: string } => {
Expand Down Expand Up @@ -368,11 +382,15 @@ ${Object.entries(args)
return '.strict()';
}

if (
const shouldCoerceType =
coerceTypes &&
(Array.isArray(coerceTypes)
? coerceTypes.includes(fn as ZodCoerceType)
: COERCEABLE_TYPES.includes(fn))
: COERCEABLE_TYPES.includes(fn));

if (
(fn !== 'date' && shouldCoerceType) ||
(fn === 'date' && shouldCoerceType && contex.output.override.useDates)
) {
return `.coerce.${fn}(${args})`;
}
Expand Down Expand Up @@ -474,6 +492,7 @@ const parseBodyAndResponse = ({
return {
input: generateZodValidationSchemaDefinition(
resolvedJsonSchema.items as SchemaObject,
context,
true,
name,
strict,
Expand All @@ -485,6 +504,7 @@ const parseBodyAndResponse = ({
return {
input: generateZodValidationSchemaDefinition(
resolvedJsonSchema,
context,
true,
name,
strict,
Expand Down Expand Up @@ -549,6 +569,7 @@ const parseParameters = ({

const definition = generateZodValidationSchemaDefinition(
schema,
context,
parameter.required,
camel(`${operationName}-${parameter.in}-${parameter.name}`),
mapStrict[parameter.in as 'path' | 'query' | 'header'] ?? false,
Expand Down Expand Up @@ -641,6 +662,8 @@ const generateZodRoute = async (
| PathItemObject
| undefined;

override.useDates;

const parameters = spec?.[verb]?.parameters;
const requestBody = spec?.[verb]?.requestBody;
const response = spec?.[verb]?.responses?.['200'] as
Expand All @@ -654,7 +677,7 @@ const generateZodRoute = async (
strict: override.zod.strict.response,
});

const parsedPody = parseBodyAndResponse({
const parsedBody = parseBodyAndResponse({
data: requestBody,
context,
name: camel(`${operationName}-body`),
Expand All @@ -670,6 +693,7 @@ const generateZodRoute = async (

const inputParams = parseZodValidationSchemaDefinition(
parsedParameters.params,
context,
override.zod.coerce.param,
);

Expand All @@ -681,15 +705,18 @@ const generateZodRoute = async (

const inputQueryParams = parseZodValidationSchemaDefinition(
parsedParameters.queryParams,
context,
override.zod.coerce.query ?? override.coerceTypes,
);
const inputHeaders = parseZodValidationSchemaDefinition(
parsedParameters.headers,
context,
override.zod.coerce.header,
);

const inputBody = parseZodValidationSchemaDefinition(
parsedPody.input,
parsedBody.input,
context,
override.zod.coerce.body,
);

Expand All @@ -705,6 +732,7 @@ const generateZodRoute = async (

const inputResponse = parseZodValidationSchemaDefinition(
parsedResponse.input,
context,
override.zod.coerce.response,
preprocessResponse,
);
Expand Down Expand Up @@ -739,7 +767,7 @@ const generateZodRoute = async (
...(inputBody.consts ? [inputBody.consts] : []),
...(inputBody.zod
? [
parsedPody.isArray
parsedBody.isArray
? `export const ${operationName}BodyItem = ${inputBody.zod}
export const ${operationName}Body = zod.array(${operationName}BodyItem)`
: `export const ${operationName}Body = ${inputBody.zod}`,
Expand Down
34 changes: 33 additions & 1 deletion packages/zod/src/zod.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
generateZodValidationSchemaDefinition,
} from '.';
import { SchemaObject } from 'openapi3-ts/oas30';
import { ContextSpecs } from '@orval/core';

const queryParams: ZodValidationSchemaDefinitionInput = {
functions: [
Expand Down Expand Up @@ -46,6 +47,13 @@ describe('parseZodValidationSchemaDefinition', () => {
it('does not emit coerced zod property schemas', () => {
const parseResult = parseZodValidationSchemaDefinition(
queryParams,
{
output: {
override: {
useDates: false,
},
},
} as ContextSpecs,
false,
);

Expand All @@ -57,7 +65,17 @@ describe('parseZodValidationSchemaDefinition', () => {

describe('with `override.coerceTypes = true`', () => {
it('emits coerced zod property schemas', () => {
const parseResult = parseZodValidationSchemaDefinition(queryParams, true);
const parseResult = parseZodValidationSchemaDefinition(
queryParams,
{
output: {
override: {
useDates: false,
},
},
} as ContextSpecs,
true,
);

expect(parseResult.zod).toBe(
'zod.object({\n "limit": zod.coerce.number().optional().null(),\n "q": zod.array(zod.coerce.string()).optional()\n})',
Expand Down Expand Up @@ -105,6 +123,13 @@ describe('generateZodValidationSchemaDefinition`', () => {
it('required', () => {
const result = generateZodValidationSchemaDefinition(
deepRequiredSchema,
{
output: {
override: {
useDates: false,
},
},
} as ContextSpecs,
true,
'strict',
true,
Expand Down Expand Up @@ -149,6 +174,13 @@ describe('generateZodValidationSchemaDefinition`', () => {
it('generates a strict zod schema', () => {
const result = generateZodValidationSchemaDefinition(
objectIntoObjectSchema,
{
output: {
override: {
useDates: false,
},
},
} as ContextSpecs,
true,
'strict',
true,
Expand Down
2 changes: 1 addition & 1 deletion samples/hono/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"dependencies": {
"@hono/zod-validator": "^0.2.0",
"hono": "^4.0.4",
"zod": "^3.22.4"
"zod": "^3.23.8"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20240208.0",
Expand Down
2 changes: 1 addition & 1 deletion tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@
"react": "^18.3.1",
"swr": "^2.2.4",
"vue": "^3.3.4",
"zod": "^3.21.4"
"zod": "^3.23.8"
}
}
8 changes: 4 additions & 4 deletions tests/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1411,7 +1411,7 @@ yargs@^17.3.1:
y18n "^5.0.5"
yargs-parser "^21.1.1"

zod@^3.21.4:
version "3.21.4"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.21.4.tgz#10882231d992519f0a10b5dd58a38c9dabbb64db"
integrity sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==
zod@^3.23.8:
version "3.23.8"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d"
integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==

0 comments on commit 36ebf4f

Please sign in to comment.