Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ createDocument({

##### Zod Effects

`.transform()`, `.default()` and `.pipe()` are complicated because they technically comprise of two types (input & output). This means that we need to understand which type you are creating. In particular with transform it is very difficult to infer the output type. This library will automatically select which _type_ to use by checking how the schema is used based on the following rules:
`.transform()`, `.catch()`, `.default()` and `.pipe()` are complicated because they technically comprise of two types (input & output). This means that we need to understand which type you are creating. In particular with transform it is very difficult to infer the output type. This library will automatically select which _type_ to use by checking how the schema is used based on the following rules:

_Input_: Request Bodies, Request Parameters, Headers

Expand Down Expand Up @@ -694,6 +694,7 @@ For example in `z.string().nullable()` will be rendered differently
- ZodBoolean
- ZodBranded
- ZodCatch
- Treated as ZodDefault
- ZodDate
- `type` is mapped as `string` by default
- ZodDefault
Expand Down
4 changes: 2 additions & 2 deletions src/create/parameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import type {
ZodOpenApiParameters,
} from './document';
import { type SchemaState, createSchema } from './schema';
import { isOptionalSchema } from './schema/parsers/optional';

export const createComponentParamRef = (ref: string) =>
`#/components/parameters/${ref}`;
Expand All @@ -30,7 +29,8 @@ export const createBaseParameter = (
documentOptions,
};
const schemaObject = createSchema(schema, state, [...subpath, 'schema']);
const required = !isOptionalSchema(schema, state)?.optional;
const required = !schema.isOptional();

const description =
schema._def.openapi?.description ?? schema._def.description;

Expand Down
5 changes: 3 additions & 2 deletions src/create/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import type {
ZodOpenApiResponsesObject,
} from './document';
import { type SchemaState, createSchema } from './schema';
import { isOptionalSchema } from './schema/parsers/optional';
import { isISpecificationExtension } from './specificationExtension';

export const createResponseHeaders = (
Expand Down Expand Up @@ -90,7 +89,9 @@ export const createBaseHeader = (
documentOptions,
};
const schemaObject = createSchema(schema, state, ['header']);
const required = !isOptionalSchema(schema, state)?.optional;
const optionalResult = schema.safeParse(undefined);

const required = !optionalResult.success || optionalResult !== undefined;
return {
...rest,
...(schema && { schema: schemaObject }),
Expand Down
1 change: 1 addition & 0 deletions src/create/schema/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ const expectedZodUnion: Schema['schema'] = {
const zodCatch = z.string().catch('bob');
const expectedZodCatch: Schema['schema'] = {
type: 'string',
default: 'bob',
};

const zodPipeline = z
Expand Down
3 changes: 2 additions & 1 deletion src/create/schema/parsers/catch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import { createOutputState } from '../../../testing/state';
import { createCatchSchema } from './catch';

describe('createCatchSchema', () => {
it('creates a simple string schema for a string with a catch', () => {
it('creates a default string schema for a string with a catch', () => {
const expected: Schema = {
type: 'schema',
schema: {
type: 'string',
default: 'bob',
},
};
const schema = z.string().catch('bob');
Expand Down
21 changes: 20 additions & 1 deletion src/create/schema/parsers/catch.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
import type { ZodCatch, ZodTypeAny } from 'zod';

import type { oas31 } from '../../../../dist';
import {
type Schema,
type SchemaState,
createSchemaObject,
} from '../../schema';
import { enhanceWithMetadata } from '../metadata';

export const createCatchSchema = <T extends ZodTypeAny>(
zodCatch: ZodCatch<T>,
state: SchemaState,
): Schema => createSchemaObject(zodCatch._def.innerType, state, ['catch']);
): Schema => {
const schemaObject = createSchemaObject(zodCatch._def.innerType, state, [
'default',
]);

const catchResult = zodCatch.safeParse(undefined);

const maybeDefaultValue: Pick<oas31.SchemaObject, 'default'> | undefined =
catchResult.success
? {
default: catchResult.data,
}
: undefined;

return enhanceWithMetadata(schemaObject, {
...maybeDefaultValue,
});
};
42 changes: 24 additions & 18 deletions src/create/schema/parsers/discriminatedUnion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,22 @@ describe('createDiscriminatedUnionSchema', () => {
});

it('handles a discriminated union with a catch type', () => {
const expected: Schema = {
const schema = z.discriminatedUnion('type', [
z
.object({
type: z.literal('a').catch('a'),
})
.openapi({ ref: 'a' }),
z
.object({
type: z.literal('b'),
})
.openapi({ ref: 'b' }),
]);

const result = createDiscriminatedUnionSchema(schema, createOutputState());

expect(result).toEqual<Schema>({
type: 'schema',
schema: {
discriminator: {
Expand All @@ -462,22 +477,13 @@ describe('createDiscriminatedUnionSchema', () => {
},
],
},
};
const schema = z.discriminatedUnion('type', [
z
.object({
type: z.literal('a').catch('a'),
})
.openapi({ ref: 'a' }),
z
.object({
type: z.literal('b'),
})
.openapi({ ref: 'b' }),
]);

const result = createDiscriminatedUnionSchema(schema, createOutputState());

expect(result).toEqual(expected);
effects: [
{
type: 'component',
path: ['discriminated union option 0'],
zodType: schema.options[0],
},
],
});
});
});
Loading
Loading