diff --git a/.changeset/ninety-towns-act.md b/.changeset/ninety-towns-act.md new file mode 100644 index 000000000..418e1e46a --- /dev/null +++ b/.changeset/ninety-towns-act.md @@ -0,0 +1,9 @@ +--- +"@hey-api/openapi-ts": minor +--- + +**plugin(zod)**: remove `enum.nodes.nullable` resolver node + +### Removed resolver node + +Zod plugin no longer exposes the `enum.nodes.nullable` node. It was refactored so that nullable values are handled outside of resolvers. diff --git a/.changeset/proud-trains-lay.md b/.changeset/proud-trains-lay.md new file mode 100644 index 000000000..93ae535ca --- /dev/null +++ b/.changeset/proud-trains-lay.md @@ -0,0 +1,5 @@ +--- +"@hey-api/openapi-ts": patch +--- + +**plugin(zod)**: use `.nullable()` and `.nullish()` methods diff --git a/dev/inputs.ts b/dev/inputs.ts index 5ba6b7aae..0b341220e 100644 --- a/dev/inputs.ts +++ b/dev/inputs.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import { getSpecsPath } from '../packages/openapi-ts-tests/utils'; export const inputs = { - circular: path.resolve(getSpecsPath(), '3.1.x', 'circular.yaml'), + circular: path.resolve(getSpecsPath(), '3.0.x', 'circular.yaml'), full: path.resolve(getSpecsPath(), '3.1.x', 'full.yaml'), local: 'http://localhost:8000/openapi.json', opencode: path.resolve(getSpecsPath(), '3.1.x', 'opencode.yaml'), diff --git a/dev/python/plugins.ts b/dev/python/plugins.ts index 50696e7ec..cd6698d7d 100644 --- a/dev/python/plugins.ts +++ b/dev/python/plugins.ts @@ -3,8 +3,8 @@ import type { UserConfig } from '@hey-api/openapi-python'; type PluginConfig = NonNullable[number]>; export function sdk( - options?: Partial, 'name'>>, -) { + options?: Omit, 'name'>, +): Extract { return { name: '@hey-api/python-sdk' as const, ...options, @@ -12,8 +12,8 @@ export function sdk( } export function pydantic( - options?: Partial, 'name'>>, -) { + options?: Omit, 'name'>, +): Extract { return { name: 'pydantic' as const, ...options, diff --git a/dev/typescript/plugins.ts b/dev/typescript/plugins.ts index 6f7df3b12..9066c5da7 100644 --- a/dev/typescript/plugins.ts +++ b/dev/typescript/plugins.ts @@ -3,8 +3,8 @@ import type { UserConfig } from '@hey-api/openapi-ts'; type PluginConfig = NonNullable[number]>; export function typescript( - options?: Partial, 'name'>>, -) { + options?: Omit, 'name'>, +): Extract { return { name: '@hey-api/typescript' as const, ...options, @@ -12,15 +12,17 @@ export function typescript( } export function sdk( - options?: Partial, 'name'>>, -) { + options?: Omit, 'name'>, +): Extract { return { name: '@hey-api/sdk' as const, ...options, }; } -export function zod(options?: Partial, 'name'>>) { +export function zod( + options?: Omit, 'name'>, +): Extract { return { name: 'zod' as const, ...options, @@ -28,8 +30,8 @@ export function zod(options?: Partial, 'name'>>, -) { + options?: Omit, 'name'>, +): Extract { return { name: 'valibot' as const, ...options, @@ -37,8 +39,8 @@ export function valibot( } export function tanstackReactQuery( - options?: Partial, 'name'>>, -) { + options?: Omit, 'name'>, +): Extract { return { name: '@tanstack/react-query' as const, ...options, @@ -46,8 +48,8 @@ export function tanstackReactQuery( } export function transformers( - options?: Partial, 'name'>>, -) { + options?: Omit, 'name'>, +): Extract { return { name: '@hey-api/transformers' as const, ...options, diff --git a/packages/openapi-python/src/plugins/pydantic/v2/toAst/string.ts b/packages/openapi-python/src/plugins/pydantic/v2/toAst/string.ts index 2ef06c2bc..2f7a3bf94 100644 --- a/packages/openapi-python/src/plugins/pydantic/v2/toAst/string.ts +++ b/packages/openapi-python/src/plugins/pydantic/v2/toAst/string.ts @@ -3,11 +3,11 @@ import type { SchemaWithType } from '@hey-api/shared'; // import { $ } from '../../../../py-dsl'; import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -export const stringToNode = ({ +export function stringToNode({ schema, }: IrSchemaToAstOptions & { schema: SchemaWithType<'string'>; -}): Ast => { +}): Ast { const constraints: Record = {}; if (schema.minLength !== undefined) { @@ -45,4 +45,4 @@ export const stringToNode = ({ // pipes: [], typeAnnotation: 'str', }; -}; +} diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format-zod/zod.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format-zod/zod.gen.ts index b4eb8a8ef..bb1956f79 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format-zod/zod.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/@hey-api/transformers/type-format-zod/zod.gen.ts @@ -3,7 +3,7 @@ import * as z from 'zod'; export const zFoo = z.object({ - bar: z.optional(z.int()), + bar: z.int().optional(), foo: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).default(BigInt(0)), id: z.string() }); @@ -13,9 +13,9 @@ export const zBar = z.object({ }); export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/@hey-api/transformers/type-format-zod/zod.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/@hey-api/transformers/type-format-zod/zod.gen.ts index b4eb8a8ef..bb1956f79 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/@hey-api/transformers/type-format-zod/zod.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/@hey-api/transformers/type-format-zod/zod.gen.ts @@ -3,7 +3,7 @@ import * as z from 'zod'; export const zFoo = z.object({ - bar: z.optional(z.int()), + bar: z.int().optional(), foo: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).default(BigInt(0)), id: z.string() }); @@ -13,9 +13,9 @@ export const zBar = z.object({ }); export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/@hey-api/transformers/type-format-zod/zod.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/@hey-api/transformers/type-format-zod/zod.gen.ts index b4eb8a8ef..bb1956f79 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/@hey-api/transformers/type-format-zod/zod.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/@hey-api/transformers/type-format-zod/zod.gen.ts @@ -3,7 +3,7 @@ import * as z from 'zod'; export const zFoo = z.object({ - bar: z.optional(z.int()), + bar: z.int().optional(), foo: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).default(BigInt(0)), id: z.string() }); @@ -13,9 +13,9 @@ export const zBar = z.object({ }); export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/string-with-format/zod.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/string-with-format/zod.gen.ts index c89666b67..e19b0d856 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/string-with-format/zod.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/string-with-format/zod.gen.ts @@ -3,5 +3,5 @@ import * as z from 'zod'; export const zFoo = z.object({ - foo: z.optional(z.array(z.union([z.string(), z.string()]))) + foo: z.array(z.union([z.string(), z.string()])).optional() }); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/webhooks/zod.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/webhooks/zod.gen.ts index f0975b045..c357da977 100644 --- a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/webhooks/zod.gen.ts +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/webhooks/zod.gen.ts @@ -3,14 +3,14 @@ import * as z from 'zod'; export const zSessionUserPhoneCalloutRingingWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.string(), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ account_id: z.string(), object: z.object({ - id: z.optional(z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' })), - uuid: z.optional(z.string()), + id: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).optional(), + uuid: z.string().optional(), session_id: z.string(), session_name: z.string(), session_key: z.string(), @@ -23,20 +23,20 @@ export const zSessionUserPhoneCalloutRingingWebhookRequest = z.object({ }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionUserRoomSystemCalloutRingingWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.string(), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ account_id: z.string(), object: z.object({ - id: z.optional(z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' })), - uuid: z.optional(z.string()), + id: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).optional(), + uuid: z.string().optional(), session_id: z.string(), session_name: z.string(), host_id: z.string(), @@ -48,13 +48,13 @@ export const zSessionUserRoomSystemCalloutRingingWebhookRequest = z.object({ }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionRecordingStartedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.recording_started']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -66,18 +66,18 @@ export const zSessionRecordingStartedWebhookRequest = z.object({ start_time: z.iso.datetime(), timezone: z.string(), recording_file: z.object({ - recording_start: z.optional(z.string()), - recording_end: z.optional(z.string()) + recording_start: z.string().optional(), + recording_end: z.string().optional() }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionRecordingResumedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.recording_resumed']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -89,18 +89,18 @@ export const zSessionRecordingResumedWebhookRequest = z.object({ start_time: z.iso.datetime(), timezone: z.string(), recording_file: z.object({ - recording_start: z.optional(z.string()), - recording_end: z.optional(z.string()) + recording_start: z.string().optional(), + recording_end: z.string().optional() }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionLiveStreamingStoppedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.live_streaming_stopped']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -109,7 +109,7 @@ export const zSessionLiveStreamingStoppedWebhookRequest = z.object({ id: z.string(), session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), start_time: z.iso.datetime(), live_streaming: z.object({ service: z.enum([ @@ -122,19 +122,19 @@ export const zSessionLiveStreamingStoppedWebhookRequest = z.object({ stream_url: z.string(), stream_key: z.string(), page_url: z.string(), - resolution: z.optional(z.string()) + resolution: z.string().optional() }), date_time: z.iso.datetime() }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionStreamIngestionStoppedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.stream_ingestion_stopped']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -142,31 +142,31 @@ export const zSessionStreamIngestionStoppedWebhookRequest = z.object({ object: z.object({ session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), stream_ingestion: z.object({ stream_id: z.string(), stream_name: z.string(), - stream_description: z.optional(z.string()), + stream_description: z.string().optional(), stream_key: z.string(), stream_url: z.string(), backup_stream_url: z.string() }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionUserRoomSystemCalloutRejectedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.string(), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ account_id: z.string(), object: z.object({ - id: z.optional(z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' })), - uuid: z.optional(z.string()), + id: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).optional(), + uuid: z.string().optional(), session_id: z.string(), session_name: z.string(), host_id: z.string(), @@ -178,13 +178,13 @@ export const zSessionUserRoomSystemCalloutRejectedWebhookRequest = z.object({ }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionAlertWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.alert']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -193,7 +193,7 @@ export const zSessionAlertWebhookRequest = z.object({ id: z.string(), session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), issues: z.array(z.enum([ 'Unstable audio quality', 'Unstable video quality', @@ -203,13 +203,13 @@ export const zSessionAlertWebhookRequest = z.object({ ])) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionSharingEndedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.sharing_ended']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -218,11 +218,11 @@ export const zSessionSharingEndedWebhookRequest = z.object({ id: z.string(), session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), user: z.object({ id: z.string(), name: z.string(), - user_key: z.optional(z.string()), + user_key: z.string().optional(), sharing_details: z.object({ content: z.enum([ 'application', @@ -235,13 +235,13 @@ export const zSessionSharingEndedWebhookRequest = z.object({ }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionRecordingPausedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.recording_paused']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -253,18 +253,18 @@ export const zSessionRecordingPausedWebhookRequest = z.object({ start_time: z.iso.datetime(), timezone: z.string(), recording_file: z.object({ - recording_start: z.optional(z.string()), - recording_end: z.optional(z.string()) + recording_start: z.string().optional(), + recording_end: z.string().optional() }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionEndedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.ended']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -273,18 +273,18 @@ export const zSessionEndedWebhookRequest = z.object({ id: z.string(), session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), start_time: z.iso.datetime(), end_time: z.iso.datetime() }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionStartedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.started']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -293,17 +293,17 @@ export const zSessionStartedWebhookRequest = z.object({ id: z.string(), session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), start_time: z.iso.datetime() }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionStreamIngestionUnbindWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.stream_ingestion_unbind']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -311,24 +311,24 @@ export const zSessionStreamIngestionUnbindWebhookRequest = z.object({ object: z.object({ session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), stream_ingestion: z.object({ stream_id: z.string(), stream_name: z.string(), - stream_description: z.optional(z.string()), + stream_description: z.string().optional(), stream_key: z.string(), stream_url: z.string(), backup_stream_url: z.string() }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionLiveStreamingStartedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.live_streaming_started']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -337,7 +337,7 @@ export const zSessionLiveStreamingStartedWebhookRequest = z.object({ id: z.string(), session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), start_time: z.iso.datetime(), live_streaming: z.object({ service: z.enum([ @@ -350,26 +350,26 @@ export const zSessionLiveStreamingStartedWebhookRequest = z.object({ stream_url: z.string(), stream_key: z.string(), page_url: z.string(), - resolution: z.optional(z.string()) + resolution: z.string().optional() }), date_time: z.iso.datetime() }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionUserRoomSystemCalloutMissedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.string(), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ account_id: z.string(), object: z.object({ - id: z.optional(z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' })), - uuid: z.optional(z.string()), + id: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).optional(), + uuid: z.string().optional(), session_id: z.string(), session_name: z.string(), host_id: z.string(), @@ -381,20 +381,20 @@ export const zSessionUserRoomSystemCalloutMissedWebhookRequest = z.object({ }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionUserPhoneCalloutAcceptedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.string(), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ account_id: z.string(), object: z.object({ - id: z.optional(z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' })), - uuid: z.optional(z.string()), + id: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).optional(), + uuid: z.string().optional(), session_id: z.string(), session_name: z.string(), session_key: z.string(), @@ -407,13 +407,13 @@ export const zSessionUserPhoneCalloutAcceptedWebhookRequest = z.object({ }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionUserLeftWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.user_left']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -422,25 +422,25 @@ export const zSessionUserLeftWebhookRequest = z.object({ id: z.string(), session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), user: z.object({ id: z.string(), name: z.string(), leave_time: z.iso.datetime(), - leave_reason: z.optional(z.string()), - user_key: z.optional(z.string()), - phone_number: z.optional(z.string()), + leave_reason: z.string().optional(), + user_key: z.string().optional(), + phone_number: z.string().optional(), participant_uuid: z.string() }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionSharingStartedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.sharing_started']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -449,11 +449,11 @@ export const zSessionSharingStartedWebhookRequest = z.object({ id: z.string(), session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), user: z.object({ id: z.string(), name: z.string(), - user_key: z.optional(z.string()), + user_key: z.string().optional(), sharing_details: z.object({ content: z.enum([ 'application', @@ -466,13 +466,13 @@ export const zSessionSharingStartedWebhookRequest = z.object({ }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionUserPhoneCalloutCanceledWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.string(), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -489,13 +489,13 @@ export const zSessionUserPhoneCalloutCanceledWebhookRequest = z.object({ }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionRecordingTranscriptCompletedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.recording_transcript_completed']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), download_token: z.string(), @@ -508,12 +508,12 @@ export const zSessionRecordingTranscriptCompletedWebhookRequest = z.object({ start_time: z.iso.datetime(), timezone: z.string(), recording_files: z.array(z.object({ - id: z.optional(z.string()), - recording_start: z.optional(z.string()), - recording_end: z.optional(z.string()), - file_name: z.optional(z.string()), - file_path: z.optional(z.string()), - file_type: z.optional(z.enum([ + id: z.string().optional(), + recording_start: z.string().optional(), + recording_end: z.string().optional(), + file_name: z.string().optional(), + file_path: z.string().optional(), + file_type: z.enum([ 'MP4', 'M4A', 'CHAT', @@ -523,9 +523,9 @@ export const zSessionRecordingTranscriptCompletedWebhookRequest = z.object({ 'TB', 'CHAT_MESSAGE', 'TIMELINE' - ])), - file_size: z.optional(z.number()), - file_extension: z.optional(z.enum([ + ]).optional(), + file_size: z.number().optional(), + file_extension: z.enum([ 'MP4', 'M4A', 'TXT', @@ -533,10 +533,10 @@ export const zSessionRecordingTranscriptCompletedWebhookRequest = z.object({ 'CSV', 'JSON', 'JPG' - ])), - download_url: z.optional(z.string()), - status: z.optional(z.enum(['completed'])), - recording_type: z.optional(z.enum([ + ]).optional(), + download_url: z.string().optional(), + status: z.enum(['completed']).optional(), + recording_type: z.enum([ 'shared_screen_with_speaker_view(CC)', 'shared_screen_with_speaker_view', 'shared_screen_with_gallery_view', @@ -554,17 +554,17 @@ export const zSessionRecordingTranscriptCompletedWebhookRequest = z.object({ 'timeline', 'thumbnail', 'chat_message' - ])) + ]).optional() })) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionRecordingDeletedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.recording_deleted']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -579,20 +579,20 @@ export const zSessionRecordingDeletedWebhookRequest = z.object({ timezone: z.string() }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionUserRoomSystemCalloutFailedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.string(), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ account_id: z.string(), object: z.object({ - id: z.optional(z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' })), - uuid: z.optional(z.string()), + id: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).optional(), + uuid: z.string().optional(), session_id: z.string(), session_name: z.string(), host_id: z.string(), @@ -619,13 +619,13 @@ export const zSessionUserRoomSystemCalloutFailedWebhookRequest = z.object({ }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionRecordingCompletedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.recording_completed']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), download_token: z.string(), @@ -638,12 +638,12 @@ export const zSessionRecordingCompletedWebhookRequest = z.object({ start_time: z.iso.datetime(), timezone: z.string(), recording_files: z.array(z.object({ - id: z.optional(z.string()), - recording_start: z.optional(z.string()), - recording_end: z.optional(z.string()), - file_name: z.optional(z.string()), - file_path: z.optional(z.string()), - file_type: z.optional(z.enum([ + id: z.string().optional(), + recording_start: z.string().optional(), + recording_end: z.string().optional(), + file_name: z.string().optional(), + file_path: z.string().optional(), + file_type: z.enum([ 'MP4', 'M4A', 'CHAT', @@ -652,9 +652,9 @@ export const zSessionRecordingCompletedWebhookRequest = z.object({ 'CC', 'TB', 'CHAT_MESSAGE' - ])), - file_size: z.optional(z.number()), - file_extension: z.optional(z.enum([ + ]).optional(), + file_size: z.number().optional(), + file_extension: z.enum([ 'MP4', 'M4A', 'TXT', @@ -662,10 +662,10 @@ export const zSessionRecordingCompletedWebhookRequest = z.object({ 'CSV', 'JSON', 'JPG' - ])), - download_url: z.optional(z.string()), - status: z.optional(z.enum(['completed'])), - recording_type: z.optional(z.enum([ + ]).optional(), + download_url: z.string().optional(), + status: z.enum(['completed']).optional(), + recording_type: z.enum([ 'shared_screen_with_speaker_view(CC)', 'shared_screen_with_speaker_view', 'shared_screen_with_gallery_view', @@ -683,15 +683,15 @@ export const zSessionRecordingCompletedWebhookRequest = z.object({ 'timeline', 'thumbnail', 'chat_message' - ])) + ]).optional() })), - participant_audio_files: z.optional(z.array(z.object({ - id: z.optional(z.string()), - recording_start: z.optional(z.string()), - recording_end: z.optional(z.string()), - file_name: z.optional(z.string()), - file_path: z.optional(z.string()), - file_type: z.optional(z.enum([ + participant_audio_files: z.array(z.object({ + id: z.string().optional(), + recording_start: z.string().optional(), + recording_end: z.string().optional(), + file_name: z.string().optional(), + file_path: z.string().optional(), + file_type: z.enum([ 'MP4', 'M4A', 'CHAT', @@ -700,9 +700,9 @@ export const zSessionRecordingCompletedWebhookRequest = z.object({ 'CC', 'TB', 'CHAT_MESSAGE' - ])), - file_size: z.optional(z.number()), - file_extension: z.optional(z.enum([ + ]).optional(), + file_size: z.number().optional(), + file_extension: z.enum([ 'MP4', 'M4A', 'TXT', @@ -710,10 +710,10 @@ export const zSessionRecordingCompletedWebhookRequest = z.object({ 'CSV', 'JSON', 'JPG' - ])), - download_url: z.optional(z.string()), - status: z.optional(z.enum(['completed'])), - recording_type: z.optional(z.enum([ + ]).optional(), + download_url: z.string().optional(), + status: z.enum(['completed']).optional(), + recording_type: z.enum([ 'shared_screen_with_speaker_view(CC)', 'shared_screen_with_speaker_view', 'shared_screen_with_gallery_view', @@ -731,34 +731,34 @@ export const zSessionRecordingCompletedWebhookRequest = z.object({ 'timeline', 'thumbnail', 'chat_message' - ])), - user_id: z.optional(z.string()), - user_key: z.optional(z.string()) - }))), - participant_video_files: z.optional(z.array(z.object({ - id: z.optional(z.string()), - recording_start: z.optional(z.string()), - recording_end: z.optional(z.string()), - file_name: z.optional(z.string()), - file_path: z.optional(z.string()), - file_type: z.optional(z.enum(['MP4'])), - file_size: z.optional(z.number()), - file_extension: z.optional(z.enum(['MP4'])), - download_url: z.optional(z.string()), - status: z.optional(z.enum(['completed'])), - recording_type: z.optional(z.enum(['individual_user', 'individual_shared_screen'])), - user_id: z.optional(z.string()), - user_key: z.optional(z.string()) - }))) - }) - }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + ]).optional(), + user_id: z.string().optional(), + user_key: z.string().optional() + })).optional(), + participant_video_files: z.array(z.object({ + id: z.string().optional(), + recording_start: z.string().optional(), + recording_end: z.string().optional(), + file_name: z.string().optional(), + file_path: z.string().optional(), + file_type: z.enum(['MP4']).optional(), + file_size: z.number().optional(), + file_extension: z.enum(['MP4']).optional(), + download_url: z.string().optional(), + status: z.enum(['completed']).optional(), + recording_type: z.enum(['individual_user', 'individual_shared_screen']).optional(), + user_id: z.string().optional(), + user_key: z.string().optional() + })).optional() + }) + }) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionRecordingTranscriptFailedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.recording_transcript_failed']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -771,13 +771,13 @@ export const zSessionRecordingTranscriptFailedWebhookRequest = z.object({ timezone: z.string() }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionRecordingTrashedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.recording_trashed']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -792,13 +792,13 @@ export const zSessionRecordingTrashedWebhookRequest = z.object({ timezone: z.string() }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionUserJoinedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.user_joined']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -807,24 +807,24 @@ export const zSessionUserJoinedWebhookRequest = z.object({ id: z.string(), session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), user: z.object({ id: z.string(), name: z.string(), join_time: z.iso.datetime(), - user_key: z.optional(z.string()), - phone_number: z.optional(z.string()), + user_key: z.string().optional(), + phone_number: z.string().optional(), participant_uuid: z.string() }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionStreamIngestionStartedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.stream_ingestion_started']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -832,24 +832,24 @@ export const zSessionStreamIngestionStartedWebhookRequest = z.object({ object: z.object({ session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), stream_ingestion: z.object({ stream_id: z.string(), stream_name: z.string(), - stream_description: z.optional(z.string()), + stream_description: z.string().optional(), stream_key: z.string(), stream_url: z.string(), backup_stream_url: z.string() }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionStreamIngestionConnectedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.stream_ingestion_connected']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -857,24 +857,24 @@ export const zSessionStreamIngestionConnectedWebhookRequest = z.object({ object: z.object({ session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), stream_ingestion: z.object({ stream_id: z.string(), stream_name: z.string(), - stream_description: z.optional(z.string()), + stream_description: z.string().optional(), stream_key: z.string(), stream_url: z.string(), backup_stream_url: z.string() }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionStreamIngestionDisconnectedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.stream_ingestion_disconnected']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -882,24 +882,24 @@ export const zSessionStreamIngestionDisconnectedWebhookRequest = z.object({ object: z.object({ session_id: z.string(), session_name: z.string(), - session_key: z.optional(z.string()), + session_key: z.string().optional(), stream_ingestion: z.object({ stream_id: z.string(), stream_name: z.string(), - stream_description: z.optional(z.string()), + stream_description: z.string().optional(), stream_key: z.string(), stream_url: z.string(), backup_stream_url: z.string() }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionRecordingRecoveredWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.recording_recovered']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -914,20 +914,20 @@ export const zSessionRecordingRecoveredWebhookRequest = z.object({ timezone: z.string() }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionUserPhoneCalloutMissedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.string(), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ account_id: z.string(), object: z.object({ - id: z.optional(z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' })), - uuid: z.optional(z.string()), + id: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).optional(), + uuid: z.string().optional(), session_id: z.string(), session_name: z.string(), session_key: z.string(), @@ -940,20 +940,20 @@ export const zSessionUserPhoneCalloutMissedWebhookRequest = z.object({ }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionUserPhoneCalloutRejectedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.string(), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ account_id: z.string(), object: z.object({ - id: z.optional(z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' })), - uuid: z.optional(z.string()), + id: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).optional(), + uuid: z.string().optional(), session_id: z.string(), session_name: z.string(), session_key: z.string(), @@ -966,20 +966,20 @@ export const zSessionUserPhoneCalloutRejectedWebhookRequest = z.object({ }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionUserRoomSystemCalloutAcceptedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.string(), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ account_id: z.string(), object: z.object({ - id: z.optional(z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' })), - uuid: z.optional(z.string()), + id: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).optional(), + uuid: z.string().optional(), session_id: z.string(), session_name: z.string(), host_id: z.string(), @@ -991,13 +991,13 @@ export const zSessionUserRoomSystemCalloutAcceptedWebhookRequest = z.object({ }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zSessionRecordingStoppedWebhookRequest = z.object({ - body: z.optional(z.object({ + body: z.object({ event: z.enum(['session.recording_stopped']), event_ts: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }), payload: z.object({ @@ -1009,12 +1009,12 @@ export const zSessionRecordingStoppedWebhookRequest = z.object({ start_time: z.iso.datetime(), timezone: z.string(), recording_file: z.object({ - recording_start: z.optional(z.string()), - recording_end: z.optional(z.string()) + recording_start: z.string().optional(), + recording_end: z.string().optional() }) }) }) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/default/zod.gen.ts index 3498fde56..b34b6cc9f 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/default/zod.gen.ts @@ -217,14 +217,8 @@ export const zModelWithStringError = z.object({ * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp: z.union([ - z.string(), - z.null() - ]) + nullableProp: z.nullish(z.string()), + nullableRequiredProp: z.nullable(z.string()) }); /** @@ -293,9 +287,7 @@ export const zModelWithDictionary = z.object({ * This is a model with one property containing a circular reference */ export const zModelWithCircularReference = z.object({ - get prop() { - return z.optional(z.lazy((): any => zModelWithCircularReference)); - } + prop: z.optional(z.lazy((): any => zModelWithCircularReference)) }); /** @@ -605,14 +597,8 @@ export const zCallToTestOrderOfParamsData = z.object({ parameterStringWithDefault: z._default(z.string(), 'Hello World!'), parameterStringWithEmptyDefault: z._default(z.string(), ''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.optional(z.union([ - z.string(), - z.null() - ])), - parameterStringNullableWithDefault: z._default(z.optional(z.union([ - z.string(), - z.null() - ])), null) + parameterStringNullableWithNoDefault: z.nullish(z.string()), + parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) }) }); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/default/zod.gen.ts index 1b73135f9..e7c596b03 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/default/zod.gen.ts @@ -217,14 +217,8 @@ export const zModelWithStringError = z.object({ * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp: z.union([ - z.string(), - z.null() - ]).optional(), - nullableRequiredProp: z.union([ - z.string(), - z.null() - ]) + nullableProp: z.string().nullish(), + nullableRequiredProp: z.string().nullable() }); /** @@ -603,14 +597,8 @@ export const zCallToTestOrderOfParamsData = z.object({ parameterStringWithDefault: z.string().default('Hello World!'), parameterStringWithEmptyDefault: z.string().default(''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.union([ - z.string(), - z.null() - ]).optional(), - parameterStringNullableWithDefault: z.union([ - z.string(), - z.null() - ]).optional().default(null) + parameterStringNullableWithNoDefault: z.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }) }); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/array-items-all-of/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/array-items-all-of/zod.gen.ts index 8ff0d5371..400acc952 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/array-items-all-of/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/array-items-all-of/zod.gen.ts @@ -3,18 +3,18 @@ import * as z from 'zod/v4'; export const zArrayWithAllOfObjects = z.array(z.object({ - id: z.optional(z.int()) + id: z.int().optional() }).and(z.object({ - name: z.optional(z.string()) + name: z.string().optional() }))); export const zArrayWithAllOfPrimitives = z.array(z.intersection(z.number(), z.string())); export const zBaseModel = z.object({ - id: z.optional(z.int()), - createdAt: z.optional(z.iso.datetime()) + id: z.int().optional(), + createdAt: z.iso.datetime().optional() }); export const zArrayWithAllOfRefs = z.array(zBaseModel.and(z.object({ - extra: z.optional(z.string()) + extra: z.string().optional() }))); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/default/zod.gen.ts index 102b4c10a..ba4b8db3c 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/default/zod.gen.ts @@ -136,8 +136,8 @@ export const zArrayWithStrings = z.array(z.string()); * This is a simple array with properties */ export const zArrayWithProperties = z.array(z.object({ - foo: z.optional(z.string()), - bar: z.optional(z.string()) + foo: z.string().optional(), + bar: z.string().optional() })); /** @@ -154,8 +154,8 @@ export const zDictionaryWithDictionary = z.record(z.string(), z.record(z.string( * This is a complex dictionary */ export const zDictionaryWithProperties = z.record(z.string(), z.object({ - foo: z.optional(z.string()), - bar: z.optional(z.string()) + foo: z.string().optional(), + bar: z.string().optional() })); /** @@ -167,21 +167,21 @@ export const zDate = z.string(); * This is a model with one number property */ export const zModelWithInteger = z.object({ - prop: z.optional(z.int()) + prop: z.int().optional() }); /** * This is a model with one boolean property */ export const zModelWithBoolean = z.object({ - prop: z.optional(z.boolean()) + prop: z.boolean().optional() }); /** * This is a model with one string property */ export const zModelWithString = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); export const zSimpleReference = zModelWithString; @@ -210,92 +210,84 @@ export const zDictionaryWithArray = z.record(z.string(), z.array(zModelWithStrin * This is a model with one string property */ export const zModelWithStringError = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp: z.union([ - z.string(), - z.null() - ]) + nullableProp: z.string().nullish(), + nullableRequiredProp: z.string().nullable() }); /** * This is a model with one enum */ export const zModelWithEnum = z.object({ - test: z.optional(z.enum([ + test: z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])), - statusCode: z.optional(z.enum([ + ]).optional(), + statusCode: z.enum([ '100', '200 FOO', '300 FOO_BAR', '400 foo-bar', '500 foo.bar', '600 foo&bar' - ])), - bool: z.optional(z.literal(true)) + ]).optional(), + bool: z.literal(true).optional() }); /** * This is a model with one enum */ export const zModelWithEnumFromDescription = z.object({ - test: z.optional(z.int()) + test: z.int().optional() }); /** * This is a model with nested enums */ export const zModelWithNestedEnums = z.object({ - dictionaryWithEnum: z.optional(z.record(z.string(), z.enum([ + dictionaryWithEnum: z.record(z.string(), z.enum([ 'Success', 'Warning', 'Error' - ]))), - dictionaryWithEnumFromDescription: z.optional(z.record(z.string(), z.int())), - arrayWithEnum: z.optional(z.array(z.enum([ + ])).optional(), + dictionaryWithEnumFromDescription: z.record(z.string(), z.int()).optional(), + arrayWithEnum: z.array(z.enum([ 'Success', 'Warning', 'Error' - ]))), - arrayWithDescription: z.optional(z.array(z.int())) + ])).optional(), + arrayWithDescription: z.array(z.int()).optional() }); /** * This is a model with one property containing an array */ export const zModelWithArray = z.object({ - prop: z.optional(z.array(zModelWithString)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithString).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); /** * This is a model with one property containing a dictionary */ export const zModelWithDictionary = z.object({ - prop: z.optional(z.record(z.string(), z.string())) + prop: z.record(z.string(), z.string()).optional() }); /** * This is a model with one property containing a circular reference */ export const zModelWithCircularReference = z.object({ - get prop() { - return z.optional(z.lazy((): any => zModelWithCircularReference)); - } + prop: z.lazy((): any => zModelWithCircularReference).optional() }); /** @@ -304,22 +296,22 @@ export const zModelWithCircularReference = z.object({ export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.string().readonly(), - string: z.optional(z.string()), - number: z.optional(z.number()), - boolean: z.optional(z.boolean()), - reference: z.optional(zModelWithString), - 'property with space': z.optional(z.string()), - default: z.optional(z.string()), - try: z.optional(z.string()), - '@namespace.string': z.optional(z.string().readonly()), - '@namespace.integer': z.optional(z.int().readonly()) + string: z.string().optional(), + number: z.number().optional(), + boolean: z.boolean().optional(), + reference: zModelWithString.optional(), + 'property with space': z.string().optional(), + default: z.string().optional(), + try: z.string().optional(), + '@namespace.string': z.string().readonly().optional(), + '@namespace.integer': z.int().readonly().optional() }); /** * This is a model with one property containing a reference */ export const zModelWithReference = z.object({ - prop: z.optional(zModelWithProperties) + prop: zModelWithProperties.optional() }); /** @@ -337,45 +329,45 @@ export const zModelWithNestedProperties = z.object({ * This is a model with duplicated properties */ export const zModelWithDuplicateProperties = z.object({ - prop: z.optional(zModelWithString) + prop: zModelWithString.optional() }); /** * This is a model with ordered properties */ export const zModelWithOrderedProperties = z.object({ - zebra: z.optional(z.string()), - apple: z.optional(z.string()), - hawaii: z.optional(z.string()) + zebra: z.string().optional(), + apple: z.string().optional(), + hawaii: z.string().optional() }); /** * This is a model with duplicated imports */ export const zModelWithDuplicateImports = z.object({ - propA: z.optional(zModelWithString), - propB: z.optional(zModelWithString), - propC: z.optional(zModelWithString) + propA: zModelWithString.optional(), + propB: zModelWithString.optional(), + propC: zModelWithString.optional() }); /** * This is a model that extends another model */ export const zModelThatExtends = zModelWithString.and(z.object({ - propExtendsA: z.optional(z.string()), - propExtendsB: z.optional(zModelWithString) + propExtendsA: z.string().optional(), + propExtendsB: zModelWithString.optional() })); /** * This is a model that extends another model */ export const zModelThatExtendsExtends = zModelWithString.and(zModelThatExtends).and(z.object({ - propExtendsC: z.optional(z.string()), - propExtendsD: z.optional(zModelWithString) + propExtendsC: z.string().optional(), + propExtendsD: zModelWithString.optional() })); export const zDefault = z.object({ - name: z.optional(z.string()) + name: z.string().optional() }); /** @@ -384,40 +376,40 @@ export const zDefault = z.object({ export const zModelWithPattern = z.object({ key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), name: z.string().max(255), - enabled: z.optional(z.boolean().readonly()), - modified: z.optional(z.iso.datetime().readonly()), - id: z.optional(z.string().regex(/^\d{2}-\d{3}-\d{4}$/)), - text: z.optional(z.string().regex(/^\w+$/)), - patternWithSingleQuotes: z.optional(z.string().regex(/^[a-zA-Z0-9']*$/)), - patternWithNewline: z.optional(z.string().regex(/aaa\nbbb/)), - patternWithBacktick: z.optional(z.string().regex(/aaa`bbb/)) + enabled: z.boolean().readonly().optional(), + modified: z.iso.datetime().readonly().optional(), + id: z.string().regex(/^\d{2}-\d{3}-\d{4}$/).optional(), + text: z.string().regex(/^\w+$/).optional(), + patternWithSingleQuotes: z.string().regex(/^[a-zA-Z0-9']*$/).optional(), + patternWithNewline: z.string().regex(/aaa\nbbb/).optional(), + patternWithBacktick: z.string().regex(/aaa`bbb/).optional() }); export const zParameterActivityParams = z.object({ - description: z.optional(z.string()), - graduate_id: z.optional(z.int()), - organization_id: z.optional(z.int()), - parent_activity: z.optional(z.int()), - post_id: z.optional(z.int()) + description: z.string().optional(), + graduate_id: z.int().optional(), + organization_id: z.int().optional(), + parent_activity: z.int().optional(), + post_id: z.int().optional() }); export const zResponsePostActivityResponse = z.object({ - description: z.optional(z.string()), - graduate_id: z.optional(z.int()), - organization_id: z.optional(z.int()), - parent_activity_id: z.optional(z.int()), - post_id: z.optional(z.int()) + description: z.string().optional(), + graduate_id: z.int().optional(), + organization_id: z.int().optional(), + parent_activity_id: z.int().optional(), + post_id: z.int().optional() }); export const zFailureFailure = z.object({ - error: z.optional(z.string()), - message: z.optional(z.string()), - reference_code: z.optional(z.string()) + error: z.string().optional(), + message: z.string().optional(), + reference_code: z.string().optional() }); export const zExternalSharedExternalSharedModel = z.object({ id: z.string(), - name: z.optional(z.string()) + name: z.string().optional() }); export const zExternalRefA = zExternalSharedExternalSharedModel; @@ -429,20 +421,20 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - string: z.optional(z.string()), - number: z.optional(z.number()), - boolean: z.optional(z.boolean()), - reference: z.optional(zModelWithString), - 'property with space': z.optional(z.string()), - default: z.optional(z.string()), - try: z.optional(z.string()) + string: z.string().optional(), + number: z.number().optional(), + boolean: z.boolean().optional(), + reference: zModelWithString.optional(), + 'property with space': z.string().optional(), + default: z.string().optional(), + try: z.string().optional() }); /** * This is a model with one property containing a reference */ export const zModelWithReferenceWritable = z.object({ - prop: z.optional(zModelWithPropertiesWritable) + prop: zModelWithPropertiesWritable.optional() }); /** @@ -451,88 +443,88 @@ export const zModelWithReferenceWritable = z.object({ export const zModelWithPatternWritable = z.object({ key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), name: z.string().max(255), - id: z.optional(z.string().regex(/^\d{2}-\d{3}-\d{4}$/)), - text: z.optional(z.string().regex(/^\w+$/)), - patternWithSingleQuotes: z.optional(z.string().regex(/^[a-zA-Z0-9']*$/)), - patternWithNewline: z.optional(z.string().regex(/aaa\nbbb/)), - patternWithBacktick: z.optional(z.string().regex(/aaa`bbb/)) + id: z.string().regex(/^\d{2}-\d{3}-\d{4}$/).optional(), + text: z.string().regex(/^\w+$/).optional(), + patternWithSingleQuotes: z.string().regex(/^[a-zA-Z0-9']*$/).optional(), + patternWithNewline: z.string().regex(/aaa\nbbb/).optional(), + patternWithBacktick: z.string().regex(/aaa`bbb/).optional() }); export const zServiceWithEmptyTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zFooWowData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithDescriptionsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterWithBreaks: z.optional(z.string()), - parameterWithBackticks: z.optional(z.string()), - parameterWithSlashes: z.optional(z.string()), - parameterWithExpressionPlaceholders: z.optional(z.string()), - parameterWithQuotes: z.optional(z.string()), - parameterWithReservedCharacters: z.optional(z.string()) - })) + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterWithBreaks: z.string().optional(), + parameterWithBackticks: z.string().optional(), + parameterWithSlashes: z.string().optional(), + parameterWithExpressionPlaceholders: z.string().optional(), + parameterWithQuotes: z.string().optional(), + parameterWithReservedCharacters: z.string().optional() + }).optional() }); export const zCallWithParametersData = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ parameterPath: z.string(), 'api-version': z.string() @@ -548,13 +540,13 @@ export const zCallWithParametersData = z.object({ export const zCallWithWeirdParameterNamesData = z.object({ body: z.string(), path: z.object({ - 'parameter.path.1': z.optional(z.string()), - 'parameter-path-2': z.optional(z.string()), - 'PARAMETER-PATH-3': z.optional(z.string()), + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), 'api-version': z.string() }), query: z.object({ - default: z.optional(z.string()), + default: z.string().optional(), 'parameter-query': z.string() }), headers: z.object({ @@ -563,8 +555,8 @@ export const zCallWithWeirdParameterNamesData = z.object({ }); export const zCallWithDefaultParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ parameterString: z.string().default('Hello World!'), parameterNumber: z.number().default(123), @@ -575,81 +567,75 @@ export const zCallWithDefaultParametersData = z.object({ 'Error' ]), parameterModel: z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }).default({ prop: 'Hello World!' }) }) }); export const zCallWithDefaultOptionalParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z.optional(z.string()).default('Hello World!'), - parameterNumber: z.optional(z.number()).default(123), - parameterBoolean: z.optional(z.boolean()).default(true), - parameterEnum: z.optional(z.enum([ + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterString: z.string().optional().default('Hello World!'), + parameterNumber: z.number().optional().default(123), + parameterBoolean: z.boolean().optional().default(true), + parameterEnum: z.enum([ 'Success', 'Warning', 'Error' - ])) - })) + ]).optional() + }).optional() }); export const zCallToTestOrderOfParamsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ - parameterOptionalStringWithDefault: z.optional(z.string()).default('Hello World!'), - parameterOptionalStringWithEmptyDefault: z.optional(z.string()).default(''), - parameterOptionalStringWithNoDefault: z.optional(z.string()), + parameterOptionalStringWithDefault: z.string().optional().default('Hello World!'), + parameterOptionalStringWithEmptyDefault: z.string().optional().default(''), + parameterOptionalStringWithNoDefault: z.string().optional(), parameterStringWithDefault: z.string().default('Hello World!'), parameterStringWithEmptyDefault: z.string().default(''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.optional(z.union([ - z.string(), - z.null() - ])), - parameterStringNullableWithDefault: z.optional(z.union([ - z.string(), - z.null() - ])).default(null) + parameterStringNullableWithNoDefault: z.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }) }); export const zDuplicateNameData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName2Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName3Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName4Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseAndNoContentResponseResponse = z.union([ @@ -658,21 +644,21 @@ export const zCallWithResponseAndNoContentResponseResponse = z.union([ ]); export const zDummyAData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDummyBData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -681,9 +667,9 @@ export const zCallWithResponseData = z.object({ export const zCallWithResponseResponse = zModelWithString; export const zCallWithDuplicateResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -692,24 +678,24 @@ export const zCallWithDuplicateResponsesData = z.object({ export const zCallWithDuplicateResponsesResponse = zModelWithString; export const zCallWithResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponsesResponse = z.union([ z.object({ - '@namespace.string': z.optional(z.string().readonly()), - '@namespace.integer': z.optional(z.int().readonly()), - value: z.optional(z.array(zModelWithString).readonly()) + '@namespace.string': z.string().readonly().optional(), + '@namespace.integer': z.int().readonly().optional(), + value: z.array(zModelWithString).readonly().optional() }), zModelThatExtends, zModelThatExtendsExtends ]); export const zCollectionFormatData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ parameterArrayCSV: z.array(z.string()), parameterArraySSV: z.array(z.string()), @@ -720,10 +706,10 @@ export const zCollectionFormatData = z.object({ }); export const zTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.object({ - id: z.optional(z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })) - })), + body: z.never().optional(), + path: z.object({ + id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional() + }).optional(), query: z.object({ parameterNumber: z.number().default(123), parameterString: z.string().default('default'), @@ -746,18 +732,18 @@ export const zTypesResponse = z.union([ ]); export const zComplexTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ parameterObject: z.object({ - first: z.optional(z.object({ - second: z.optional(z.object({ - third: z.optional(z.string()) - })) - })) + first: z.object({ + second: z.object({ + third: z.string().optional() + }).optional() + }).optional() }), parameterReference: z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }) }) }); @@ -768,22 +754,22 @@ export const zComplexTypesData = z.object({ export const zComplexTypesResponse = z.array(zModelWithString); export const zCallWithResultFromHeaderData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zTestErrorCodeData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ status: z.string() }) }); export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ nonAsciiParamæøåÆØÅöôêÊ: z.int() }) @@ -796,8 +782,8 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = zNonAsciiStringæ export const zPostApiVbyApiVersionBodyData = z.object({ body: zParameterActivityParams, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/type-format-zod/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/type-format-zod/zod.gen.ts index 796146a69..9b6647e58 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/type-format-zod/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/type-format-zod/zod.gen.ts @@ -3,7 +3,7 @@ import * as z from 'zod/v4'; export const zFoo = z.object({ - bar: z.optional(z.int()), + bar: z.int().optional(), foo: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).default(BigInt(0)), id: z.string() }); @@ -13,9 +13,9 @@ export const zBar = z.object({ }); export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/circular/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/circular/zod.gen.ts index 1563aa737..a6c351d2d 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/circular/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/circular/zod.gen.ts @@ -3,24 +3,16 @@ import * as z from 'zod/v4-mini'; export const zFoo = z.object({ - get quux() { - return z.optional(z.lazy((): any => zQuux)); - } + quux: z.optional(z.lazy((): any => zQuux)) }); export const zBar = z.object({ - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.lazy((): any => zBaz)); - } + bar: z.optional(z.lazy((): any => zBar)), + baz: z.optional(z.lazy((): any => zBaz)) }); export const zBaz = z.object({ - get quux() { - return z.optional(z.lazy((): any => zQuux)); - } + quux: z.optional(z.lazy((): any => zQuux)) }); export const zQux = z.union([ diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/default/zod.gen.ts index 8c943fbd9..ef26ce4a8 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/default/zod.gen.ts @@ -81,10 +81,7 @@ export const zSimpleFile = z.string(); /** * This is a simple string */ -export const zSimpleStringWithPattern = z.union([ - z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/)), - z.null() -]); +export const zSimpleStringWithPattern = z.nullable(z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/))); /** * This is a simple enum with strings @@ -279,22 +276,10 @@ export const zModelFromZendesk = z.string(); * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp1: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp1: z.union([ - z.string(), - z.null() - ]), - nullableProp2: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp2: z.union([ - z.string(), - z.null() - ]), + nullableProp1: z.nullish(z.string()), + nullableRequiredProp1: z.nullable(z.string()), + nullableProp2: z.nullish(z.string()), + nullableRequiredProp2: z.nullable(z.string()), 'foo_bar-enum': z.optional(z.enum([ 'Success', 'Warning', @@ -391,9 +376,7 @@ export const zDeprecatedModel = z.object({ * This is a model with one property containing a circular reference */ export const zModelWithCircularReference = z.object({ - get prop() { - return z.optional(z.lazy((): any => zModelWithCircularReference)); - } + prop: z.optional(z.lazy((): any => zModelWithCircularReference)) }); /** @@ -479,14 +462,8 @@ export const zCompositionWithAnyOfAnonymous = z.object({ */ export const zCompositionWithNestedAnyAndTypeNull = z.object({ propA: z.optional(z.union([ - z.array(z.union([ - zModelWithDictionary, - z.null() - ])), - z.array(z.union([ - zModelWithArray, - z.null() - ])) + z.array(z.nullable(zModelWithDictionary)), + z.array(z.nullable(zModelWithArray)) ])) }); @@ -498,24 +475,20 @@ export const zConstValue = z.enum(['ConstValue']); * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithNestedAnyOfAndNull = z.object({ - propA: z.optional(z.union([ - z.array(z.union([z3eNum1Период, zConstValue])), - z.null() - ])) + propA: z.nullish(z.array(z.union([z3eNum1Период, zConstValue]))) }); /** * This is a model with one property with a 'one of' relationship */ export const zCompositionWithOneOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.nullish(z.union([ z.object({ boolean: z.optional(z.boolean()) }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() + zModelWithDictionary ])) }); @@ -553,26 +526,22 @@ export const zCompositionWithOneOfAndComplexArrayDictionary = z.object({ * This is a model with one property with a 'all of' relationship */ export const zCompositionWithAllOfAndNullable = z.object({ - propA: z.optional(z.union([ - z.intersection(z.intersection(z.intersection(z.object({ - boolean: z.optional(z.boolean()) - }), zModelWithEnum), zModelWithArray), zModelWithDictionary), - z.null() - ])) + propA: z.nullish(z.intersection(z.intersection(z.intersection(z.object({ + boolean: z.optional(z.boolean()) + }), zModelWithEnum), zModelWithArray), zModelWithDictionary)) }); /** * This is a model with one property with a 'any of' relationship */ export const zCompositionWithAnyOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.nullish(z.union([ z.object({ boolean: z.optional(z.boolean()) }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() + zModelWithDictionary ])) }); @@ -599,10 +568,7 @@ export const zCompositionExtendedModel = z.intersection(zCompositionBaseModel, z export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.readonly(z.string()), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.nullable(z.string()), string: z.optional(z.string()), number: z.optional(z.number()), boolean: z.optional(z.boolean()), @@ -625,20 +591,11 @@ export const zModelWithReference = z.object({ * This is a model with one nested property */ export const zModelWithNestedProperties = z.object({ - first: z.readonly(z.union([ - z.readonly(z.object({ - second: z.readonly(z.union([ - z.readonly(z.object({ - third: z.readonly(z.union([ - z.readonly(z.string()), - z.null() - ])) - })), - z.null() - ])) - })), - z.null() - ])) + first: z.nullable(z.readonly(z.object({ + second: z.nullable(z.readonly(z.object({ + third: z.nullable(z.readonly(z.string())) + }))) + }))) }); /** @@ -745,21 +702,15 @@ export const zModelWithAdditionalPropertiesEqTrue = z.object({ }); export const zNestedAnyOfArraysNullable = z.object({ - nullableArray: z.optional(z.union([ - z.array(z.union([z.string(), z.boolean()])), - z.null() - ])) + nullableArray: z.nullish(z.array(z.union([z.string(), z.boolean()]))) }); /** * An object that can be null */ -export const zNullableObject = z._default(z.union([ - z.object({ - foo: z.optional(z.string()) - }), - z.null() -]), null); +export const zNullableObject = z._default(z.nullable(z.object({ + foo: z.optional(z.string()) +})), null); /** * Some % character @@ -846,21 +797,18 @@ export const zModelWithPrefixItemsConstantSizeArray = z.array(z.union([ ])); export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([ - z.union([ + z.nullable(z.union([ z.number(), - z.null(), z.string() - ]), - z.union([ + ])), + z.nullable(z.union([ z.number(), - z.null(), z.string() - ]), - z.union([ + ])), + z.nullable(z.union([ z.number(), - z.null(), z.string() - ]) + ])) ]); export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([z.intersection(z.number(), z.string()), z.intersection(z.number(), z.string())]); @@ -979,23 +927,14 @@ export const zAdditionalPropertiesIntegerIssue = z.object({ export const zGenericSchemaDuplicateIssue1SystemBoolean = z.object({ item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), + error: z.nullish(z.string()), hasError: z.optional(z.readonly(z.boolean())), data: z.optional(z.record(z.string(), z.never())) }); export const zGenericSchemaDuplicateIssue1SystemString = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])), + item: z.nullish(z.string()), + error: z.nullish(z.string()), hasError: z.optional(z.readonly(z.boolean())) }); @@ -1021,10 +960,7 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.nullable(z.string()), string: z.optional(z.string()), number: z.optional(z.number()), boolean: z.optional(z.boolean()), @@ -1095,22 +1031,13 @@ export const zOneOfAllOfIssueWritable = z.union([ export const zGenericSchemaDuplicateIssue1SystemBooleanWritable = z.object({ item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), + error: z.nullish(z.string()), data: z.optional(z.record(z.string(), z.never())) }); export const zGenericSchemaDuplicateIssue1SystemStringWritable = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])) + item: z.nullish(z.string()), + error: z.nullish(z.string()) }); /** @@ -1126,10 +1053,7 @@ export const zCompositionWithOneOfAndProperties = z.intersection(z.union([ bar: zNonAsciiStringæøåÆøÅöôêÊ字符串 }) ]), z.object({ - baz: z.union([ - z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' })), - z.null() - ]), + baz: z.nullable(z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }))), qux: z.int().check(z.gte(0), z.maximum(255, { error: 'Invalid value: Expected uint8 to be <= 255' })) })); @@ -1137,10 +1061,7 @@ export const zModelWithOneOfAndProperties = z.intersection(z.union([ zSimpleParameter, zNonAsciiStringæøåÆøÅöôêÊ字符串 ]), z.object({ - baz: z.union([ - z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' })), - z.null() - ]), + baz: z.nullable(z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }))), qux: z.int().check(z.gte(0), z.maximum(255, { error: 'Invalid value: Expected uint8 to be <= 255' })) })); @@ -1281,70 +1202,40 @@ export const zDeprecatedCallData = z.object({ path: z.optional(z.never()), query: z.optional(z.never()), headers: z.object({ - parameter: z.union([ - zDeprecatedModel, - z.null() - ]) + parameter: z.nullable(zDeprecatedModel) }) }); export const zCallWithParametersData = z.object({ - body: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + body: z.nullable(z.record(z.string(), z.unknown())), path: z.object({ - parameterPath: z.union([ - z.string(), - z.null() - ]), - 'api-version': z.union([ - z.string(), - z.null() - ]) + parameterPath: z.nullable(z.string()), + 'api-version': z.nullable(z.string()) }), query: z.object({ foo_ref_enum: z.optional(zModelWithNestedArrayEnumsDataFoo), foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.union([ - z.string(), - z.null() - ]) + cursor: z.nullable(z.string()) }), headers: z.object({ - parameterHeader: z.union([ - z.string(), - z.null() - ]) + parameterHeader: z.nullable(z.string()) }) }); export const zCallWithWeirdParameterNamesData = z.object({ - body: z.union([ - zModelWithString, - z.null() - ]), + body: z.nullable(zModelWithString), path: z.object({ 'parameter.path.1': z.optional(z.string()), 'parameter-path-2': z.optional(z.string()), 'PARAMETER-PATH-3': z.optional(z.string()), - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.nullable(z.string()) }), query: z.object({ default: z.optional(z.string()), - 'parameter-query': z.union([ - z.string(), - z.null() - ]) + 'parameter-query': z.nullable(z.string()) }), headers: z.object({ - 'parameter.header': z.union([ - z.string(), - z.null() - ]) + 'parameter.header': z.nullable(z.string()) }) }); @@ -1358,10 +1249,7 @@ export const zGetCallWithOptionalParamData = z.object({ export const zPostCallWithOptionalParamData = z.object({ body: z.optional(z.object({ - offset: z.optional(z.union([ - z.number(), - z.null() - ])) + offset: z.nullish(z.number()) })), path: z.optional(z.never()), query: z.object({ @@ -1394,27 +1282,15 @@ export const zCallWithDefaultParametersData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), query: z.optional(z.object({ - parameterString: z._default(z.optional(z.union([ - z._default(z.string(), 'Hello World!'), - z.null() - ])), 'Hello World!'), - parameterNumber: z._default(z.optional(z.union([ - z._default(z.number(), 123), - z.null() - ])), 123), - parameterBoolean: z._default(z.optional(z.union([ - z._default(z.boolean(), true), - z.null() - ])), true), + parameterString: z._default(z.nullish(z.string()), 'Hello World!'), + parameterNumber: z._default(z.nullish(z.number()), 123), + parameterBoolean: z._default(z.nullish(z.boolean()), true), parameterEnum: z.optional(z.enum([ 'Success', 'Warning', 'Error' ])), - parameterModel: z.optional(z.union([ - zModelWithString, - z.null() - ])) + parameterModel: z.nullish(zModelWithString) })) }); @@ -1444,14 +1320,8 @@ export const zCallToTestOrderOfParamsData = z.object({ parameterStringWithDefault: z._default(z.string(), 'Hello World!'), parameterStringWithEmptyDefault: z._default(z.string(), ''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.optional(z.union([ - z.string(), - z.null() - ])), - parameterStringNullableWithDefault: z._default(z.optional(z.union([ - z.string(), - z.null() - ])), null) + parameterStringNullableWithNoDefault: z.nullish(z.string()), + parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) }) }); @@ -1559,26 +1429,11 @@ export const zCollectionFormatData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), query: z.object({ - parameterArrayCSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArraySSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayTSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayPipes: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayMulti: z.union([ - z.array(z.string()), - z.null() - ]) + parameterArrayCSV: z.nullable(z.array(z.string())), + parameterArraySSV: z.nullable(z.array(z.string())), + parameterArrayTSV: z.nullable(z.array(z.string())), + parameterArrayPipes: z.nullable(z.array(z.string())), + parameterArrayMulti: z.nullable(z.array(z.string())) }) }); @@ -1589,26 +1444,11 @@ export const zTypesData = z.object({ })), query: z.object({ parameterNumber: z._default(z.number(), 123), - parameterString: z._default(z.union([ - z._default(z.string(), 'default'), - z.null() - ]), 'default'), - parameterBoolean: z._default(z.union([ - z._default(z.boolean(), true), - z.null() - ]), true), - parameterObject: z._default(z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), null), - parameterArray: z.union([ - z.array(z.string()), - z.null() - ]), - parameterDictionary: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + parameterString: z._default(z.nullable(z.string()), 'default'), + parameterBoolean: z._default(z.nullable(z.boolean()), true), + parameterObject: z._default(z.nullable(z.record(z.string(), z.unknown())), null), + parameterArray: z.nullable(z.array(z.string())), + parameterDictionary: z.nullable(z.record(z.string(), z.unknown())), parameterEnum: z.enum([ 'Success', 'Warning', @@ -1627,10 +1467,7 @@ export const zTypesResponse = z.union([ export const zUploadFileData = z.object({ body: z.string(), path: z.object({ - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.nullable(z.string()) }), query: z.optional(z.never()) }); @@ -1691,10 +1528,7 @@ export const zMultipartResponseResponse = z.object({ export const zMultipartRequestData = z.object({ body: z.optional(z.object({ content: z.optional(z.string()), - data: z.optional(z.union([ - zModelWithString, - z.null() - ])) + data: z.nullish(zModelWithString) })), path: z.optional(z.never()), query: z.optional(z.never()) @@ -1702,28 +1536,16 @@ export const zMultipartRequestData = z.object({ export const zComplexParamsData = z.object({ body: z.optional(z.object({ - key: z.readonly(z.union([ - z.readonly(z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/))), - z.null() - ])), - name: z.union([ - z.string().check(z.maxLength(255)), - z.null() - ]), + key: z.nullable(z.readonly(z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/)))), + name: z.nullable(z.string().check(z.maxLength(255))), enabled: z._default(z.optional(z.boolean()), true), type: z.enum([ 'Monkey', 'Horse', 'Bird' ]), - listOfModels: z.optional(z.union([ - z.array(zModelWithString), - z.null() - ])), - listOfStrings: z.optional(z.union([ - z.array(z.string()), - z.null() - ])), + listOfModels: z.nullish(z.array(zModelWithString)), + listOfStrings: z.nullish(z.array(z.string())), parameters: z.union([ zModelWithString, zModelWithEnum, @@ -1732,10 +1554,7 @@ export const zComplexParamsData = z.object({ ]), user: z.optional(z.readonly(z.object({ id: z.optional(z.readonly(z.int().check(z.minimum(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }), z.maximum(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })))), - name: z.optional(z.readonly(z.union([ - z.readonly(z.string()), - z.null() - ]))) + name: z.nullish(z.readonly(z.string())) }))) })), path: z.object({ diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/validators/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/validators/zod.gen.ts index cfa348c12..fd4b0647c 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/validators/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/validators/zod.gen.ts @@ -4,19 +4,12 @@ import * as z from 'zod/v4-mini'; export const zBaz = z._default(z.readonly(z.string().check(z.regex(/foo\nbar/))), 'baz'); -export const zFoo = z._default(z.union([ - z.object({ - foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z._default(z.optional(z.int().check(z.gt(0))), 0) - }), - z.null() -]), null); +export const zFoo = z._default(z.nullable(z.object({ + foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), + bar: z.optional(z.lazy((): any => zBar)), + baz: z.optional(z.array(z.lazy((): any => zFoo))), + qux: z._default(z.optional(z.int().check(z.gt(0))), 0) +})), null); export const zBar = z.object({ foo: z.optional(zFoo) diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/default/zod.gen.ts index f12f1b5f4..3bacc0572 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/default/zod.gen.ts @@ -81,10 +81,7 @@ export const zSimpleFile = z.string(); /** * This is a simple string */ -export const zSimpleStringWithPattern = z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), - z.null() -]); +export const zSimpleStringWithPattern = z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).nullable(); /** * This is a simple enum with strings @@ -279,22 +276,10 @@ export const zModelFromZendesk = z.string(); * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp1: z.union([ - z.string(), - z.null() - ]).optional(), - nullableRequiredProp1: z.union([ - z.string(), - z.null() - ]), - nullableProp2: z.union([ - z.string(), - z.null() - ]).optional(), - nullableRequiredProp2: z.union([ - z.string(), - z.null() - ]), + nullableProp1: z.string().nullish(), + nullableRequiredProp1: z.string().nullable(), + nullableProp2: z.string().nullish(), + nullableRequiredProp2: z.string().nullable(), 'foo_bar-enum': z.enum([ 'Success', 'Warning', @@ -477,14 +462,8 @@ export const zCompositionWithAnyOfAnonymous = z.object({ */ export const zCompositionWithNestedAnyAndTypeNull = z.object({ propA: z.union([ - z.array(z.union([ - zModelWithDictionary, - z.null() - ])), - z.array(z.union([ - zModelWithArray, - z.null() - ])) + z.array(zModelWithDictionary.nullable()), + z.array(zModelWithArray.nullable()) ]).optional() }); @@ -496,10 +475,7 @@ export const zConstValue = z.enum(['ConstValue']); * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithNestedAnyOfAndNull = z.object({ - propA: z.union([ - z.array(z.union([z3eNum1Период, zConstValue])), - z.null() - ]).optional() + propA: z.array(z.union([z3eNum1Период, zConstValue])).nullish() }); /** @@ -512,9 +488,8 @@ export const zCompositionWithOneOfAndNullable = z.object({ }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ]).optional() + zModelWithDictionary + ]).nullish() }); /** @@ -551,12 +526,9 @@ export const zCompositionWithOneOfAndComplexArrayDictionary = z.object({ * This is a model with one property with a 'all of' relationship */ export const zCompositionWithAllOfAndNullable = z.object({ - propA: z.union([ - z.object({ - boolean: z.boolean().optional() - }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary), - z.null() - ]).optional() + propA: z.object({ + boolean: z.boolean().optional() + }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary).nullish() }); /** @@ -569,9 +541,8 @@ export const zCompositionWithAnyOfAndNullable = z.object({ }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ]).optional() + zModelWithDictionary + ]).nullish() }); /** @@ -597,10 +568,7 @@ export const zCompositionExtendedModel = zCompositionBaseModel.and(z.object({ export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.string().readonly(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.string().nullable(), string: z.string().optional(), number: z.number().optional(), boolean: z.boolean().optional(), @@ -623,20 +591,11 @@ export const zModelWithReference = z.object({ * This is a model with one nested property */ export const zModelWithNestedProperties = z.object({ - first: z.union([ - z.object({ - second: z.union([ - z.object({ - third: z.union([ - z.string().readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() + first: z.object({ + second: z.object({ + third: z.string().readonly().nullable() + }).readonly().nullable() + }).readonly().nullable() }); /** @@ -743,21 +702,15 @@ export const zModelWithAdditionalPropertiesEqTrue = z.object({ }); export const zNestedAnyOfArraysNullable = z.object({ - nullableArray: z.union([ - z.array(z.union([z.string(), z.boolean()])), - z.null() - ]).optional() + nullableArray: z.array(z.union([z.string(), z.boolean()])).nullish() }); /** * An object that can be null */ -export const zNullableObject = z.union([ - z.object({ - foo: z.string().optional() - }), - z.null() -]).default(null); +export const zNullableObject = z.object({ + foo: z.string().optional() +}).nullable().default(null); /** * Some % character @@ -846,19 +799,16 @@ export const zModelWithPrefixItemsConstantSizeArray = z.array(z.union([ export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([ z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]) + ]).nullable() ]); export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([z.intersection(z.number(), z.string()), z.intersection(z.number(), z.string())]); @@ -977,23 +927,14 @@ export const zAdditionalPropertiesIntegerIssue = z.object({ export const zGenericSchemaDuplicateIssue1SystemBoolean = z.object({ item: z.boolean().optional(), - error: z.union([ - z.string(), - z.null() - ]).optional(), + error: z.string().nullish(), hasError: z.boolean().readonly().optional(), data: z.record(z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemString = z.object({ - item: z.union([ - z.string(), - z.null() - ]).optional(), - error: z.union([ - z.string(), - z.null() - ]).optional(), + item: z.string().nullish(), + error: z.string().nullish(), hasError: z.boolean().readonly().optional() }); @@ -1019,10 +960,7 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.string().nullable(), string: z.string().optional(), number: z.number().optional(), boolean: z.boolean().optional(), @@ -1093,22 +1031,13 @@ export const zOneOfAllOfIssueWritable = z.union([ export const zGenericSchemaDuplicateIssue1SystemBooleanWritable = z.object({ item: z.boolean().optional(), - error: z.union([ - z.string(), - z.null() - ]).optional(), + error: z.string().nullish(), data: z.record(z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemStringWritable = z.object({ - item: z.union([ - z.string(), - z.null() - ]).optional(), - error: z.union([ - z.string(), - z.null() - ]).optional() + item: z.string().nullish(), + error: z.string().nullish() }); /** @@ -1124,10 +1053,7 @@ export const zCompositionWithOneOfAndProperties = z.intersection(z.union([ bar: zNonAsciiStringæøåÆøÅöôêÊ字符串 }) ]), z.object({ - baz: z.union([ - z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.number().int().gte(0).max(255, { message: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1135,10 +1061,7 @@ export const zModelWithOneOfAndProperties = z.intersection(z.union([ zSimpleParameter, zNonAsciiStringæøåÆøÅöôêÊ字符串 ]), z.object({ - baz: z.union([ - z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.number().int().gte(0).max(255, { message: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1279,70 +1202,40 @@ export const zDeprecatedCallData = z.object({ path: z.never().optional(), query: z.never().optional(), headers: z.object({ - parameter: z.union([ - zDeprecatedModel, - z.null() - ]) + parameter: zDeprecatedModel.nullable() }) }); export const zCallWithParametersData = z.object({ - body: z.union([ - z.record(z.unknown()), - z.null() - ]), + body: z.record(z.unknown()).nullable(), path: z.object({ - parameterPath: z.union([ - z.string(), - z.null() - ]), - 'api-version': z.union([ - z.string(), - z.null() - ]) + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }), query: z.object({ foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.union([ - z.string(), - z.null() - ]) + cursor: z.string().nullable() }), headers: z.object({ - parameterHeader: z.union([ - z.string(), - z.null() - ]) + parameterHeader: z.string().nullable() }) }); export const zCallWithWeirdParameterNamesData = z.object({ - body: z.union([ - zModelWithString, - z.null() - ]), + body: zModelWithString.nullable(), path: z.object({ 'parameter.path.1': z.string().optional(), 'parameter-path-2': z.string().optional(), 'PARAMETER-PATH-3': z.string().optional(), - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.string().nullable() }), query: z.object({ default: z.string().optional(), - 'parameter-query': z.union([ - z.string(), - z.null() - ]) + 'parameter-query': z.string().nullable() }), headers: z.object({ - 'parameter.header': z.union([ - z.string(), - z.null() - ]) + 'parameter.header': z.string().nullable() }) }); @@ -1356,10 +1249,7 @@ export const zGetCallWithOptionalParamData = z.object({ export const zPostCallWithOptionalParamData = z.object({ body: z.object({ - offset: z.union([ - z.number(), - z.null() - ]).optional() + offset: z.number().nullish() }).optional(), path: z.never().optional(), query: z.object({ @@ -1392,27 +1282,15 @@ export const zCallWithDefaultParametersData = z.object({ body: z.never().optional(), path: z.never().optional(), query: z.object({ - parameterString: z.union([ - z.string().default('Hello World!'), - z.null() - ]).optional().default('Hello World!'), - parameterNumber: z.union([ - z.number().default(123), - z.null() - ]).optional().default(123), - parameterBoolean: z.union([ - z.boolean().default(true), - z.null() - ]).optional().default(true), + parameterString: z.string().nullish().default('Hello World!'), + parameterNumber: z.number().nullish().default(123), + parameterBoolean: z.boolean().nullish().default(true), parameterEnum: z.enum([ 'Success', 'Warning', 'Error' ]).optional(), - parameterModel: z.union([ - zModelWithString, - z.null() - ]).optional() + parameterModel: zModelWithString.nullish() }).optional() }); @@ -1442,14 +1320,8 @@ export const zCallToTestOrderOfParamsData = z.object({ parameterStringWithDefault: z.string().default('Hello World!'), parameterStringWithEmptyDefault: z.string().default(''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.union([ - z.string(), - z.null() - ]).optional(), - parameterStringNullableWithDefault: z.union([ - z.string(), - z.null() - ]).optional().default(null) + parameterStringNullableWithNoDefault: z.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }) }); @@ -1557,26 +1429,11 @@ export const zCollectionFormatData = z.object({ body: z.never().optional(), path: z.never().optional(), query: z.object({ - parameterArrayCSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArraySSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayTSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayPipes: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayMulti: z.union([ - z.array(z.string()), - z.null() - ]) + parameterArrayCSV: z.array(z.string()).nullable(), + parameterArraySSV: z.array(z.string()).nullable(), + parameterArrayTSV: z.array(z.string()).nullable(), + parameterArrayPipes: z.array(z.string()).nullable(), + parameterArrayMulti: z.array(z.string()).nullable() }) }); @@ -1587,26 +1444,11 @@ export const zTypesData = z.object({ }).optional(), query: z.object({ parameterNumber: z.number().default(123), - parameterString: z.union([ - z.string().default('default'), - z.null() - ]).default('default'), - parameterBoolean: z.union([ - z.boolean().default(true), - z.null() - ]).default(true), - parameterObject: z.union([ - z.record(z.unknown()), - z.null() - ]).default(null), - parameterArray: z.union([ - z.array(z.string()), - z.null() - ]), - parameterDictionary: z.union([ - z.record(z.unknown()), - z.null() - ]), + parameterString: z.string().nullable().default('default'), + parameterBoolean: z.boolean().nullable().default(true), + parameterObject: z.record(z.unknown()).nullable().default(null), + parameterArray: z.array(z.string()).nullable(), + parameterDictionary: z.record(z.unknown()).nullable(), parameterEnum: z.enum([ 'Success', 'Warning', @@ -1625,10 +1467,7 @@ export const zTypesResponse = z.union([ export const zUploadFileData = z.object({ body: z.string(), path: z.object({ - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.string().nullable() }), query: z.never().optional() }); @@ -1689,10 +1528,7 @@ export const zMultipartResponseResponse = z.object({ export const zMultipartRequestData = z.object({ body: z.object({ content: z.string().optional(), - data: z.union([ - zModelWithString, - z.null() - ]).optional() + data: zModelWithString.nullish() }).optional(), path: z.never().optional(), query: z.never().optional() @@ -1700,28 +1536,16 @@ export const zMultipartRequestData = z.object({ export const zComplexParamsData = z.object({ body: z.object({ - key: z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly(), - z.null() - ]).readonly(), - name: z.union([ - z.string().max(255), - z.null() - ]), + key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly().nullable(), + name: z.string().max(255).nullable(), enabled: z.boolean().optional().default(true), type: z.enum([ 'Monkey', 'Horse', 'Bird' ]), - listOfModels: z.union([ - z.array(zModelWithString), - z.null() - ]).optional(), - listOfStrings: z.union([ - z.array(z.string()), - z.null() - ]).optional(), + listOfModels: z.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), parameters: z.union([ zModelWithString, zModelWithEnum, @@ -1730,10 +1554,7 @@ export const zComplexParamsData = z.object({ ]), user: z.object({ id: z.number().int().min(-2147483648, { message: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { message: 'Invalid value: Expected int32 to be <= 2147483647' }).readonly().optional(), - name: z.union([ - z.string().readonly(), - z.null() - ]).readonly().optional() + name: z.string().readonly().nullish() }).readonly().optional() }).optional(), path: z.object({ diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/validators/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/validators/zod.gen.ts index 9d727f32d..a1fd0b756 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/validators/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/validators/zod.gen.ts @@ -4,15 +4,12 @@ import { z } from 'zod'; export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz'); -export const zFoo: z.ZodTypeAny = z.union([ - z.object({ - foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), - bar: z.lazy(() => zBar).optional(), - baz: z.array(z.lazy(() => zFoo)).optional(), - qux: z.number().int().gt(0).optional().default(0) - }), - z.null() -]).default(null); +export const zFoo: z.ZodTypeAny = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy(() => zBar).optional(), + baz: z.array(z.lazy(() => zFoo)).optional(), + qux: z.number().int().gt(0).optional().default(0) +}).nullable().default(null); export const zBar = z.object({ foo: zFoo.optional() diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/array-items-all-of/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/array-items-all-of/zod.gen.ts index 8ff0d5371..400acc952 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/array-items-all-of/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/array-items-all-of/zod.gen.ts @@ -3,18 +3,18 @@ import * as z from 'zod/v4'; export const zArrayWithAllOfObjects = z.array(z.object({ - id: z.optional(z.int()) + id: z.int().optional() }).and(z.object({ - name: z.optional(z.string()) + name: z.string().optional() }))); export const zArrayWithAllOfPrimitives = z.array(z.intersection(z.number(), z.string())); export const zBaseModel = z.object({ - id: z.optional(z.int()), - createdAt: z.optional(z.iso.datetime()) + id: z.int().optional(), + createdAt: z.iso.datetime().optional() }); export const zArrayWithAllOfRefs = z.array(zBaseModel.and(z.object({ - extra: z.optional(z.string()) + extra: z.string().optional() }))); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/array-items-one-of-length-1/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/array-items-one-of-length-1/zod.gen.ts index e1f2e86f8..92dfb2397 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/array-items-one-of-length-1/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/array-items-one-of-length-1/zod.gen.ts @@ -5,5 +5,5 @@ import * as z from 'zod/v4'; export const zBar = z.string(); export const zFoo = z.object({ - foo: z.optional(z.array(zBar).min(1).max(2147483647)) + foo: z.array(zBar).min(1).max(2147483647).optional() }); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/circular/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/circular/zod.gen.ts index 33afdca46..f17d72150 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/circular/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/circular/zod.gen.ts @@ -3,24 +3,16 @@ import * as z from 'zod/v4'; export const zFoo = z.object({ - get quux() { - return z.optional(z.lazy((): any => zQuux)); - } + quux: z.lazy((): any => zQuux).optional() }); export const zBar = z.object({ - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.lazy((): any => zBaz)); - } + bar: z.lazy((): any => zBar).optional(), + baz: z.lazy((): any => zBaz).optional() }); export const zBaz = z.object({ - get quux() { - return z.optional(z.lazy((): any => zQuux)); - } + quux: z.lazy((): any => zQuux).optional() }); export const zQux = z.union([ @@ -33,9 +25,9 @@ export const zQux = z.union([ ]); export const zQuux = z.object({ - qux: z.optional(zQux) + qux: zQux.optional() }); export const zCorge = z.object({ - baz: z.optional(z.array(zBaz)) + baz: z.array(zBaz).optional() }); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/default/zod.gen.ts index dbf7906f6..022229c77 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/default/zod.gen.ts @@ -81,10 +81,7 @@ export const zSimpleFile = z.string(); /** * This is a simple string */ -export const zSimpleStringWithPattern = z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), - z.null() -]); +export const zSimpleStringWithPattern = z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).nullable(); /** * This is a simple enum with strings @@ -166,32 +163,32 @@ export const zArrayWithStrings = z.array(z.string()).default(['test']); * This is a simple array with properties */ export const zArrayWithProperties = z.array(z.object({ - '16x16': z.optional(zCamelCaseCommentWithBreaks), - bar: z.optional(z.string()) + '16x16': zCamelCaseCommentWithBreaks.optional(), + bar: z.string().optional() })); /** * This is a simple array with any of properties */ export const zArrayWithAnyOfProperties = z.array(z.union([z.object({ - foo: z.optional(z.string()).default('test') + foo: z.string().optional().default('test') }), z.object({ - bar: z.optional(z.string()) + bar: z.string().optional() })])); export const zAnyOfAnyAndNull = z.object({ - data: z.optional(z.unknown()) + data: z.unknown().optional() }); /** * This is a simple array with any of properties */ export const zAnyOfArrays = z.object({ - results: z.optional(z.array(z.union([z.object({ - foo: z.optional(z.string()) + results: z.array(z.union([z.object({ + foo: z.string().optional() }), z.object({ - bar: z.optional(z.string()) - })]))) + bar: z.string().optional() + })])).optional() }); /** @@ -200,8 +197,8 @@ export const zAnyOfArrays = z.object({ export const zDictionaryWithString = z.record(z.string(), z.string()); export const zDictionaryWithPropertiesAndAdditionalProperties = z.object({ - foo: z.optional(z.number()), - bar: z.optional(z.boolean()) + foo: z.number().optional(), + bar: z.boolean().optional() }); /** @@ -213,29 +210,29 @@ export const zDictionaryWithDictionary = z.record(z.string(), z.record(z.string( * This is a complex dictionary */ export const zDictionaryWithProperties = z.record(z.string(), z.object({ - foo: z.optional(z.string()), - bar: z.optional(z.string()) + foo: z.string().optional(), + bar: z.string().optional() })); /** * This is a model with one number property */ export const zModelWithInteger = z.object({ - prop: z.optional(z.int()) + prop: z.int().optional() }); /** * This is a model with one boolean property */ export const zModelWithBoolean = z.object({ - prop: z.optional(z.boolean()) + prop: z.boolean().optional() }); /** * This is a model with one string property */ export const zModelWithString = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** @@ -267,7 +264,7 @@ export const zDictionaryWithArray = z.record(z.string(), z.array(zModelWithStrin * This is a model with one string property */ export const zModelWithStringError = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** @@ -279,103 +276,91 @@ export const zModelFromZendesk = z.string(); * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp1: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp1: z.union([ - z.string(), - z.null() - ]), - nullableProp2: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp2: z.union([ - z.string(), - z.null() - ]), - 'foo_bar-enum': z.optional(z.enum([ + nullableProp1: z.string().nullish(), + nullableRequiredProp1: z.string().nullable(), + nullableProp2: z.string().nullish(), + nullableRequiredProp2: z.string().nullable(), + 'foo_bar-enum': z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])) + ]).optional() }); /** * This is a model with one enum */ export const zModelWithEnum = z.object({ - 'foo_bar-enum': z.optional(z.enum([ + 'foo_bar-enum': z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])), - statusCode: z.optional(z.enum([ + ]).optional(), + statusCode: z.enum([ '100', '200 FOO', '300 FOO_BAR', '400 foo-bar', '500 foo.bar', '600 foo&bar' - ])), - bool: z.optional(z.literal(true)) + ]).optional(), + bool: z.literal(true).optional() }); /** * This is a model with one enum with escaped name */ export const zModelWithEnumWithHyphen = z.object({ - 'foo-bar-baz-qux': z.optional(z.enum(['3.0'])) + 'foo-bar-baz-qux': z.enum(['3.0']).optional() }); /** * This is a model with one enum */ export const zModelWithEnumFromDescription = z.object({ - test: z.optional(z.int()) + test: z.int().optional() }); /** * This is a model with nested enums */ export const zModelWithNestedEnums = z.object({ - dictionaryWithEnum: z.optional(z.record(z.string(), z.enum([ + dictionaryWithEnum: z.record(z.string(), z.enum([ 'Success', 'Warning', 'Error' - ]))), - dictionaryWithEnumFromDescription: z.optional(z.record(z.string(), z.int())), - arrayWithEnum: z.optional(z.array(z.enum([ + ])).optional(), + dictionaryWithEnumFromDescription: z.record(z.string(), z.int()).optional(), + arrayWithEnum: z.array(z.enum([ 'Success', 'Warning', 'Error' - ]))), - arrayWithDescription: z.optional(z.array(z.int())), - 'foo_bar-enum': z.optional(z.enum([ + ])).optional(), + arrayWithDescription: z.array(z.int()).optional(), + 'foo_bar-enum': z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])) + ]).optional() }); /** * This is a model with one property containing an array */ export const zModelWithArray = z.object({ - prop: z.optional(z.array(zModelWithString)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithString).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); /** * This is a model with one property containing a dictionary */ export const zModelWithDictionary = z.object({ - prop: z.optional(z.record(z.string(), z.string())) + prop: z.record(z.string(), z.string()).optional() }); /** @@ -384,41 +369,39 @@ export const zModelWithDictionary = z.object({ * @deprecated */ export const zDeprecatedModel = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** * This is a model with one property containing a circular reference */ export const zModelWithCircularReference = z.object({ - get prop() { - return z.optional(z.lazy((): any => zModelWithCircularReference)); - } + prop: z.lazy((): any => zModelWithCircularReference).optional() }); /** * This is a model with one property with a 'one of' relationship */ export const zCompositionWithOneOf = z.object({ - propA: z.optional(z.union([ + propA: z.union([ zModelWithString, zModelWithEnum, zModelWithArray, zModelWithDictionary - ])) + ]).optional() }); /** * This is a model with one property with a 'one of' relationship where the options are not $ref */ export const zCompositionWithOneOfAnonymous = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - propA: z.optional(z.string()) + propA: z.string().optional() }), z.string(), z.int() - ])) + ]).optional() }); /** @@ -426,7 +409,7 @@ export const zCompositionWithOneOfAnonymous = z.object({ */ export const zModelCircle = z.object({ kind: z.string(), - radius: z.optional(z.number()) + radius: z.number().optional() }); /** @@ -434,7 +417,7 @@ export const zModelCircle = z.object({ */ export const zModelSquare = z.object({ kind: z.string(), - sideLength: z.optional(z.number()) + sideLength: z.number().optional() }); /** @@ -453,41 +436,35 @@ export const zCompositionWithOneOfDiscriminator = z.union([ * This is a model with one property with a 'any of' relationship */ export const zCompositionWithAnyOf = z.object({ - propA: z.optional(z.union([ + propA: z.union([ zModelWithString, zModelWithEnum, zModelWithArray, zModelWithDictionary - ])) + ]).optional() }); /** * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithAnyOfAnonymous = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - propA: z.optional(z.string()) + propA: z.string().optional() }), z.string(), z.int() - ])) + ]).optional() }); /** * This is a model with nested 'any of' property with a type null */ export const zCompositionWithNestedAnyAndTypeNull = z.object({ - propA: z.optional(z.union([ - z.array(z.union([ - zModelWithDictionary, - z.null() - ])), - z.array(z.union([ - zModelWithArray, - z.null() - ])) - ])) + propA: z.union([ + z.array(zModelWithDictionary.nullable()), + z.array(zModelWithArray.nullable()) + ]).optional() }); export const z3eNum1Период = z.enum(['Bird', 'Dog']); @@ -498,90 +475,82 @@ export const zConstValue = z.enum(['ConstValue']); * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithNestedAnyOfAndNull = z.object({ - propA: z.optional(z.union([ - z.array(z.union([z3eNum1Период, zConstValue])), - z.null() - ])) + propA: z.array(z.union([z3eNum1Период, zConstValue])).nullish() }); /** * This is a model with one property with a 'one of' relationship */ export const zCompositionWithOneOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - boolean: z.optional(z.boolean()) + boolean: z.boolean().optional() }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ])) + zModelWithDictionary + ]).nullish() }); /** * This is a model that contains a simple dictionary within composition */ export const zCompositionWithOneOfAndSimpleDictionary = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.boolean(), z.record(z.string(), z.number()) - ])) + ]).optional() }); /** * This is a model that contains a dictionary of simple arrays within composition */ export const zCompositionWithOneOfAndSimpleArrayDictionary = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.boolean(), z.record(z.string(), z.array(z.boolean())) - ])) + ]).optional() }); /** * This is a model that contains a dictionary of complex arrays (composited) within composition */ export const zCompositionWithOneOfAndComplexArrayDictionary = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.boolean(), z.record(z.string(), z.array(z.union([z.number(), z.string()]))) - ])) + ]).optional() }); /** * This is a model with one property with a 'all of' relationship */ export const zCompositionWithAllOfAndNullable = z.object({ - propA: z.optional(z.union([ - z.object({ - boolean: z.optional(z.boolean()) - }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary), - z.null() - ])) + propA: z.object({ + boolean: z.boolean().optional() + }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary).nullish() }); /** * This is a model with one property with a 'any of' relationship */ export const zCompositionWithAnyOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - boolean: z.optional(z.boolean()) + boolean: z.boolean().optional() }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ])) + zModelWithDictionary + ]).nullish() }); /** * This is a base model with two simple optional properties */ export const zCompositionBaseModel = z.object({ - firstName: z.optional(z.string()), - lastname: z.optional(z.string()) + firstName: z.string().optional(), + lastname: z.string().optional() }); /** @@ -599,87 +568,75 @@ export const zCompositionExtendedModel = zCompositionBaseModel.and(z.object({ export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.string().readonly(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), - string: z.optional(z.string()), - number: z.optional(z.number()), - boolean: z.optional(z.boolean()), - reference: z.optional(zModelWithString), - 'property with space': z.optional(z.string()), - default: z.optional(z.string()), - try: z.optional(z.string()), - '@namespace.string': z.optional(z.string().readonly()), - '@namespace.integer': z.optional(z.int().readonly()) + requiredAndNullable: z.string().nullable(), + string: z.string().optional(), + number: z.number().optional(), + boolean: z.boolean().optional(), + reference: zModelWithString.optional(), + 'property with space': z.string().optional(), + default: z.string().optional(), + try: z.string().optional(), + '@namespace.string': z.string().readonly().optional(), + '@namespace.integer': z.int().readonly().optional() }); /** * This is a model with one property containing a reference */ export const zModelWithReference = z.object({ - prop: z.optional(zModelWithProperties) + prop: zModelWithProperties.optional() }); /** * This is a model with one nested property */ export const zModelWithNestedProperties = z.object({ - first: z.union([ - z.object({ - second: z.union([ - z.object({ - third: z.union([ - z.string().readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() + first: z.object({ + second: z.object({ + third: z.string().readonly().nullable() + }).readonly().nullable() + }).readonly().nullable() }); /** * This is a model with duplicated properties */ export const zModelWithDuplicateProperties = z.object({ - prop: z.optional(zModelWithString) + prop: zModelWithString.optional() }); /** * This is a model with ordered properties */ export const zModelWithOrderedProperties = z.object({ - zebra: z.optional(z.string()), - apple: z.optional(z.string()), - hawaii: z.optional(z.string()) + zebra: z.string().optional(), + apple: z.string().optional(), + hawaii: z.string().optional() }); /** * This is a model with duplicated imports */ export const zModelWithDuplicateImports = z.object({ - propA: z.optional(zModelWithString), - propB: z.optional(zModelWithString), - propC: z.optional(zModelWithString) + propA: zModelWithString.optional(), + propB: zModelWithString.optional(), + propC: zModelWithString.optional() }); /** * This is a model that extends another model */ export const zModelThatExtends = zModelWithString.and(z.object({ - propExtendsA: z.optional(z.string()), - propExtendsB: z.optional(zModelWithString) + propExtendsA: z.string().optional(), + propExtendsB: zModelWithString.optional() })); /** * This is a model that extends another model */ export const zModelThatExtendsExtends = zModelWithString.and(zModelThatExtends).and(z.object({ - propExtendsC: z.optional(z.string()), - propExtendsD: z.optional(zModelWithString) + propExtendsC: z.string().optional(), + propExtendsD: zModelWithString.optional() })); /** @@ -688,31 +645,31 @@ export const zModelThatExtendsExtends = zModelWithString.and(zModelThatExtends). export const zModelWithPattern = z.object({ key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), name: z.string().max(255), - enabled: z.optional(z.boolean().readonly()), - modified: z.optional(z.iso.datetime().readonly()), - id: z.optional(z.string().regex(/^\d{2}-\d{3}-\d{4}$/)), - text: z.optional(z.string().regex(/^\w+$/)), - patternWithSingleQuotes: z.optional(z.string().regex(/^[a-zA-Z0-9']*$/)), - patternWithNewline: z.optional(z.string().regex(/aaa\nbbb/)), - patternWithBacktick: z.optional(z.string().regex(/aaa`bbb/)) + enabled: z.boolean().readonly().optional(), + modified: z.iso.datetime().readonly().optional(), + id: z.string().regex(/^\d{2}-\d{3}-\d{4}$/).optional(), + text: z.string().regex(/^\w+$/).optional(), + patternWithSingleQuotes: z.string().regex(/^[a-zA-Z0-9']*$/).optional(), + patternWithNewline: z.string().regex(/aaa\nbbb/).optional(), + patternWithBacktick: z.string().regex(/aaa`bbb/).optional() }); export const zFile = z.object({ - id: z.optional(z.string().min(1).readonly()), - updated_at: z.optional(z.iso.datetime().readonly()), - created_at: z.optional(z.iso.datetime().readonly()), + id: z.string().min(1).readonly().optional(), + updated_at: z.iso.datetime().readonly().optional(), + created_at: z.iso.datetime().readonly().optional(), mime: z.string().min(1).max(24), - file: z.optional(z.url().readonly()) + file: z.url().readonly().optional() }); export const zDefault = z.object({ - name: z.optional(z.string()) + name: z.string().optional() }); export const zPageable = z.object({ - page: z.optional(z.int().gte(0).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })).default(0), - size: z.optional(z.int().gte(1).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })), - sort: z.optional(z.array(z.string())) + page: z.int().gte(0).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional().default(0), + size: z.int().gte(1).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional(), + sort: z.array(z.string()).optional() }); /** @@ -731,35 +688,29 @@ export const zFreeFormObjectWithAdditionalPropertiesEqTrue = z.record(z.string() export const zFreeFormObjectWithAdditionalPropertiesEqEmptyObject = z.record(z.string(), z.unknown()); export const zModelWithConst = z.object({ - String: z.optional(z.enum(['String'])), - number: z.optional(z.literal(0)), - null: z.optional(z.unknown()), - withType: z.optional(z.enum(['Some string'])) + String: z.enum(['String']).optional(), + number: z.literal(0).optional(), + null: z.unknown().optional(), + withType: z.enum(['Some string']).optional() }); /** * This is a model with one property and additionalProperties: true */ export const zModelWithAdditionalPropertiesEqTrue = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); export const zNestedAnyOfArraysNullable = z.object({ - nullableArray: z.optional(z.union([ - z.array(z.union([z.string(), z.boolean()])), - z.null() - ])) + nullableArray: z.array(z.union([z.string(), z.boolean()])).nullish() }); /** * An object that can be null */ -export const zNullableObject = z.union([ - z.object({ - foo: z.optional(z.string()) - }), - z.null() -]).default(null); +export const zNullableObject = z.object({ + foo: z.string().optional() +}).nullable().default(null); /** * Some % character @@ -767,7 +718,7 @@ export const zNullableObject = z.union([ export const zCharactersInDescription = z.string(); export const zModelWithNullableObject = z.object({ - data: z.optional(zNullableObject) + data: zNullableObject.optional() }); export const zModelWithOneOfEnum = z.union([ @@ -795,17 +746,17 @@ export const zModelWithNestedArrayEnumsDataFoo = z.enum(['foo', 'bar']); export const zModelWithNestedArrayEnumsDataBar = z.enum(['baz', 'qux']); export const zModelWithNestedArrayEnumsData = z.object({ - foo: z.optional(z.array(zModelWithNestedArrayEnumsDataFoo)), - bar: z.optional(z.array(zModelWithNestedArrayEnumsDataBar)) + foo: z.array(zModelWithNestedArrayEnumsDataFoo).optional(), + bar: z.array(zModelWithNestedArrayEnumsDataBar).optional() }); export const zModelWithNestedArrayEnums = z.object({ - array_strings: z.optional(z.array(z.string())), - data: z.optional(zModelWithNestedArrayEnumsData) + array_strings: z.array(z.string()).optional(), + data: zModelWithNestedArrayEnumsData.optional() }); export const zModelWithNestedCompositionEnums = z.object({ - foo: z.optional(zModelWithNestedArrayEnumsDataFoo) + foo: zModelWithNestedArrayEnumsDataFoo.optional() }); export const zModelWithReadOnlyAndWriteOnly = z.object({ @@ -817,9 +768,9 @@ export const zModelWithReadOnlyAndWriteOnly = z.object({ * This is a model with one property containing an array */ export const zModelWithArrayReadOnlyAndWriteOnly = z.object({ - prop: z.optional(z.array(zModelWithReadOnlyAndWriteOnly)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithReadOnlyAndWriteOnly).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); export const zModelWithConstantSizeArray = z.tuple([z.number(), z.number()]); @@ -848,25 +799,22 @@ export const zModelWithPrefixItemsConstantSizeArray = z.array(z.union([ export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([ z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]) + ]).nullable() ]); export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([z.intersection(z.number(), z.string()), z.intersection(z.number(), z.string())]); export const zModelWithNumericEnumUnion = z.object({ - value: z.optional(z.union([ + value: z.union([ z.literal(-10), z.literal(-1), z.literal(0), @@ -874,14 +822,14 @@ export const zModelWithNumericEnumUnion = z.object({ z.literal(3), z.literal(6), z.literal(12) - ])) + ]).optional() }); /** * Some description with `back ticks` */ export const zModelWithBackticksInDescription = z.object({ - template: z.optional(z.string()) + template: z.string().optional() }); /** @@ -923,40 +871,40 @@ export const zModelWithAnyOfConstantSizeArrayWithNSizeAndOptions = z.tuple([z.un ])]); export const zSchemaWithFormRestrictedKeys = z.object({ - description: z.optional(z.string()), - 'x-enum-descriptions': z.optional(z.string()), - 'x-enum-varnames': z.optional(z.string()), - 'x-enumNames': z.optional(z.string()), - title: z.optional(z.string()), - object: z.optional(z.object({ - description: z.optional(z.string()), - 'x-enum-descriptions': z.optional(z.string()), - 'x-enum-varnames': z.optional(z.string()), - 'x-enumNames': z.optional(z.string()), - title: z.optional(z.string()) - })), - array: z.optional(z.array(z.object({ - description: z.optional(z.string()), - 'x-enum-descriptions': z.optional(z.string()), - 'x-enum-varnames': z.optional(z.string()), - 'x-enumNames': z.optional(z.string()), - title: z.optional(z.string()) - }))) + description: z.string().optional(), + 'x-enum-descriptions': z.string().optional(), + 'x-enum-varnames': z.string().optional(), + 'x-enumNames': z.string().optional(), + title: z.string().optional(), + object: z.object({ + description: z.string().optional(), + 'x-enum-descriptions': z.string().optional(), + 'x-enum-varnames': z.string().optional(), + 'x-enumNames': z.string().optional(), + title: z.string().optional() + }).optional(), + array: z.array(z.object({ + description: z.string().optional(), + 'x-enum-descriptions': z.string().optional(), + 'x-enum-varnames': z.string().optional(), + 'x-enumNames': z.string().optional(), + title: z.string().optional() + })).optional() }); /** * This schema was giving PascalCase transformations a hard time */ export const zIoK8sApimachineryPkgApisMetaV1Preconditions = z.object({ - resourceVersion: z.optional(z.string()), - uid: z.optional(z.string()) + resourceVersion: z.string().optional(), + uid: z.string().optional() }); /** * This schema was giving PascalCase transformations a hard time */ export const zIoK8sApimachineryPkgApisMetaV1DeleteOptions = z.object({ - preconditions: z.optional(zIoK8sApimachineryPkgApisMetaV1Preconditions) + preconditions: zIoK8sApimachineryPkgApisMetaV1Preconditions.optional() }); export const zAdditionalPropertiesUnknownIssue = z.record(z.string(), z.union([ @@ -978,25 +926,16 @@ export const zAdditionalPropertiesIntegerIssue = z.object({ }); export const zGenericSchemaDuplicateIssue1SystemBoolean = z.object({ - item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), - hasError: z.optional(z.boolean().readonly()), - data: z.optional(z.record(z.string(), z.never())) + item: z.boolean().optional(), + error: z.string().nullish(), + hasError: z.boolean().readonly().optional(), + data: z.record(z.string(), z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemString = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])), - hasError: z.optional(z.boolean().readonly()) + item: z.string().nullish(), + error: z.string().nullish(), + hasError: z.boolean().readonly().optional() }); export const zOneOfAllOfIssue = z.union([ @@ -1009,7 +948,7 @@ export const zOneOfAllOfIssue = z.union([ export const zExternalSharedExternalSharedModel = z.object({ id: z.string(), - name: z.optional(z.string()) + name: z.string().optional() }); export const zExternalRefA = zExternalSharedExternalSharedModel; @@ -1021,24 +960,21 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), - string: z.optional(z.string()), - number: z.optional(z.number()), - boolean: z.optional(z.boolean()), - reference: z.optional(zModelWithString), - 'property with space': z.optional(z.string()), - default: z.optional(z.string()), - try: z.optional(z.string()) + requiredAndNullable: z.string().nullable(), + string: z.string().optional(), + number: z.number().optional(), + boolean: z.boolean().optional(), + reference: zModelWithString.optional(), + 'property with space': z.string().optional(), + default: z.string().optional(), + try: z.string().optional() }); /** * This is a model with one property containing a reference */ export const zModelWithReferenceWritable = z.object({ - prop: z.optional(zModelWithPropertiesWritable) + prop: zModelWithPropertiesWritable.optional() }); /** @@ -1047,11 +983,11 @@ export const zModelWithReferenceWritable = z.object({ export const zModelWithPatternWritable = z.object({ key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), name: z.string().max(255), - id: z.optional(z.string().regex(/^\d{2}-\d{3}-\d{4}$/)), - text: z.optional(z.string().regex(/^\w+$/)), - patternWithSingleQuotes: z.optional(z.string().regex(/^[a-zA-Z0-9']*$/)), - patternWithNewline: z.optional(z.string().regex(/aaa\nbbb/)), - patternWithBacktick: z.optional(z.string().regex(/aaa`bbb/)) + id: z.string().regex(/^\d{2}-\d{3}-\d{4}$/).optional(), + text: z.string().regex(/^\w+$/).optional(), + patternWithSingleQuotes: z.string().regex(/^[a-zA-Z0-9']*$/).optional(), + patternWithNewline: z.string().regex(/aaa\nbbb/).optional(), + patternWithBacktick: z.string().regex(/aaa`bbb/).optional() }); export const zFileWritable = z.object({ @@ -1067,9 +1003,9 @@ export const zModelWithReadOnlyAndWriteOnlyWritable = z.object({ * This is a model with one property containing an array */ export const zModelWithArrayReadOnlyAndWriteOnlyWritable = z.object({ - prop: z.optional(z.array(zModelWithReadOnlyAndWriteOnlyWritable)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithReadOnlyAndWriteOnlyWritable).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); export const zModelWithAnyOfConstantSizeArrayWithNSizeAndOptionsWritable = z.tuple([z.union([ @@ -1094,23 +1030,14 @@ export const zOneOfAllOfIssueWritable = z.union([ ]); export const zGenericSchemaDuplicateIssue1SystemBooleanWritable = z.object({ - item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), - data: z.optional(z.record(z.string(), z.never())) + item: z.boolean().optional(), + error: z.string().nullish(), + data: z.record(z.string(), z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemStringWritable = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])) + item: z.string().nullish(), + error: z.string().nullish() }); /** @@ -1126,10 +1053,7 @@ export const zCompositionWithOneOfAndProperties = z.intersection(z.union([ bar: zNonAsciiStringæøåÆøÅöôêÊ字符串 }) ]), z.object({ - baz: z.union([ - z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.int().gte(0).max(255, { error: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1137,10 +1061,7 @@ export const zModelWithOneOfAndProperties = z.intersection(z.union([ zSimpleParameter, zNonAsciiStringæøåÆøÅöôêÊ字符串 ]), z.object({ - baz: z.union([ - z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.int().gte(0).max(255, { error: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1154,15 +1075,15 @@ export const zSimpleRequestBody = zModelWithString; export const zSimpleFormData = zModelWithString; export const zExportData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zImportData = z.object({ @@ -1170,8 +1091,8 @@ export const zImportData = z.object({ zModelWithReadOnlyAndWriteOnlyWritable, zModelWithArrayReadOnlyAndWriteOnlyWritable ]), - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); export const zImportResponse = z.union([ @@ -1180,15 +1101,15 @@ export const zImportResponse = z.union([ ]); export const zFooWowData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zApiVVersionODataControllerCountData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -1197,11 +1118,11 @@ export const zApiVVersionODataControllerCountData = z.object({ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ foo_param: z.string() }), - query: z.optional(z.never()) + query: z.never().optional() }); /** @@ -1210,160 +1131,127 @@ export const zGetApiVbyApiVersionSimpleOperationData = z.object({ export const zGetApiVbyApiVersionSimpleOperationResponse = z.number(); export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDeleteFooData3 = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ foo_param: z.string(), BarParam: z.string() }), - query: z.optional(z.never()), + query: z.never().optional(), headers: z.object({ 'x-Foo-Bar': zModelWithString }) }); export const zCallWithDescriptionsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterWithBreaks: z.optional(z.string()), - parameterWithBackticks: z.optional(z.string()), - parameterWithSlashes: z.optional(z.string()), - parameterWithExpressionPlaceholders: z.optional(z.string()), - parameterWithQuotes: z.optional(z.string()), - parameterWithReservedCharacters: z.optional(z.string()) - })) + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterWithBreaks: z.string().optional(), + parameterWithBackticks: z.string().optional(), + parameterWithSlashes: z.string().optional(), + parameterWithExpressionPlaceholders: z.string().optional(), + parameterWithQuotes: z.string().optional(), + parameterWithReservedCharacters: z.string().optional() + }).optional() }); export const zDeprecatedCallData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional(), headers: z.object({ - parameter: z.union([ - zDeprecatedModel, - z.null() - ]) + parameter: zDeprecatedModel.nullable() }) }); export const zCallWithParametersData = z.object({ - body: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + body: z.record(z.string(), z.unknown()).nullable(), path: z.object({ - parameterPath: z.union([ - z.string(), - z.null() - ]), - 'api-version': z.union([ - z.string(), - z.null() - ]) + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }), query: z.object({ - foo_ref_enum: z.optional(zModelWithNestedArrayEnumsDataFoo), + foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.union([ - z.string(), - z.null() - ]) + cursor: z.string().nullable() }), headers: z.object({ - parameterHeader: z.union([ - z.string(), - z.null() - ]) + parameterHeader: z.string().nullable() }) }); export const zCallWithWeirdParameterNamesData = z.object({ - body: z.union([ - zModelWithString, - z.null() - ]), + body: zModelWithString.nullable(), path: z.object({ - 'parameter.path.1': z.optional(z.string()), - 'parameter-path-2': z.optional(z.string()), - 'PARAMETER-PATH-3': z.optional(z.string()), - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string().nullable() }), query: z.object({ - default: z.optional(z.string()), - 'parameter-query': z.union([ - z.string(), - z.null() - ]) + default: z.string().optional(), + 'parameter-query': z.string().nullable() }), headers: z.object({ - 'parameter.header': z.union([ - z.string(), - z.null() - ]) + 'parameter.header': z.string().nullable() }) }); export const zGetCallWithOptionalParamData = z.object({ body: zModelWithOneOfEnum, - path: z.optional(z.never()), - query: z.optional(z.object({ - page: z.optional(z.number()) - })) + path: z.never().optional(), + query: z.object({ + page: z.number().optional() + }).optional() }); export const zPostCallWithOptionalParamData = z.object({ - body: z.optional(z.object({ - offset: z.optional(z.union([ - z.number(), - z.null() - ])) - })), - path: z.optional(z.never()), + body: z.object({ + offset: z.number().nullish() + }).optional(), + path: z.never().optional(), query: z.object({ parameter: zPageable }) @@ -1375,114 +1263,96 @@ export const zPostCallWithOptionalParamResponse = z.union([ ]); export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: z.optional(zSimpleRequestBody), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) + body: zSimpleRequestBody.optional(), + path: z.never().optional(), + query: z.object({ + parameter: z.string().optional() + }).optional() }); export const zPostApiVbyApiVersionFormDataData = z.object({ - body: z.optional(zSimpleFormData), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) + body: zSimpleFormData.optional(), + path: z.never().optional(), + query: z.object({ + parameter: z.string().optional() + }).optional() }); export const zCallWithDefaultParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z.optional(z.union([ - z.string().default('Hello World!'), - z.null() - ])).default('Hello World!'), - parameterNumber: z.optional(z.union([ - z.number().default(123), - z.null() - ])).default(123), - parameterBoolean: z.optional(z.union([ - z.boolean().default(true), - z.null() - ])).default(true), - parameterEnum: z.optional(z.enum([ + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterString: z.string().nullish().default('Hello World!'), + parameterNumber: z.number().nullish().default(123), + parameterBoolean: z.boolean().nullish().default(true), + parameterEnum: z.enum([ 'Success', 'Warning', 'Error' - ])), - parameterModel: z.optional(z.union([ - zModelWithString, - z.null() - ])) - })) + ]).optional(), + parameterModel: zModelWithString.nullish() + }).optional() }); export const zCallWithDefaultOptionalParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z.optional(z.string()).default('Hello World!'), - parameterNumber: z.optional(z.number()).default(123), - parameterBoolean: z.optional(z.boolean()).default(true), - parameterEnum: z.optional(z.enum([ + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterString: z.string().optional().default('Hello World!'), + parameterNumber: z.number().optional().default(123), + parameterBoolean: z.boolean().optional().default(true), + parameterEnum: z.enum([ 'Success', 'Warning', 'Error' - ])), - parameterModel: z.optional(zModelWithString) - })) + ]).optional(), + parameterModel: zModelWithString.optional() + }).optional() }); export const zCallToTestOrderOfParamsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ - parameterOptionalStringWithDefault: z.optional(z.string()).default('Hello World!'), - parameterOptionalStringWithEmptyDefault: z.optional(z.string()).default(''), - parameterOptionalStringWithNoDefault: z.optional(z.string()), + parameterOptionalStringWithDefault: z.string().optional().default('Hello World!'), + parameterOptionalStringWithEmptyDefault: z.string().optional().default(''), + parameterOptionalStringWithNoDefault: z.string().optional(), parameterStringWithDefault: z.string().default('Hello World!'), parameterStringWithEmptyDefault: z.string().default(''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.optional(z.union([ - z.string(), - z.null() - ])), - parameterStringNullableWithDefault: z.optional(z.union([ - z.string(), - z.null() - ])).default(null) + parameterStringNullableWithNoDefault: z.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }) }); export const zDuplicateNameData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName2Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName3Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName4Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -1491,9 +1361,9 @@ export const zCallWithNoContentResponseData = z.object({ export const zCallWithNoContentResponseResponse = z.void(); export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseAndNoContentResponseResponse = z.union([ @@ -1502,17 +1372,17 @@ export const zCallWithResponseAndNoContentResponseResponse = z.union([ ]); export const zDummyAData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDummyAResponse = z400; export const zDummyBData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -1521,17 +1391,17 @@ export const zDummyBData = z.object({ export const zDummyBResponse = z.void(); export const zCallWithResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseResponse = zImport; export const zCallWithDuplicateResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithDuplicateResponsesResponse = z.union([ @@ -1540,75 +1410,45 @@ export const zCallWithDuplicateResponsesResponse = z.union([ ]); export const zCallWithResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponsesResponse = z.union([ z.object({ - '@namespace.string': z.optional(z.string().readonly()), - '@namespace.integer': z.optional(z.int().readonly()), - value: z.optional(z.array(zModelWithString).readonly()) + '@namespace.string': z.string().readonly().optional(), + '@namespace.integer': z.int().readonly().optional(), + value: z.array(zModelWithString).readonly().optional() }), zModelThatExtends, zModelThatExtendsExtends ]); export const zCollectionFormatData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ - parameterArrayCSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArraySSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayTSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayPipes: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayMulti: z.union([ - z.array(z.string()), - z.null() - ]) + parameterArrayCSV: z.array(z.string()).nullable(), + parameterArraySSV: z.array(z.string()).nullable(), + parameterArrayTSV: z.array(z.string()).nullable(), + parameterArrayPipes: z.array(z.string()).nullable(), + parameterArrayMulti: z.array(z.string()).nullable() }) }); export const zTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.object({ - id: z.optional(z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })) - })), + body: z.never().optional(), + path: z.object({ + id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional() + }).optional(), query: z.object({ parameterNumber: z.number().default(123), - parameterString: z.union([ - z.string().default('default'), - z.null() - ]).default('default'), - parameterBoolean: z.union([ - z.boolean().default(true), - z.null() - ]).default(true), - parameterObject: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]).default(null), - parameterArray: z.union([ - z.array(z.string()), - z.null() - ]), - parameterDictionary: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + parameterString: z.string().nullable().default('default'), + parameterBoolean: z.boolean().nullable().default(true), + parameterObject: z.record(z.string(), z.unknown()).nullable().default(null), + parameterArray: z.array(z.string()).nullable(), + parameterDictionary: z.record(z.string(), z.unknown()).nullable(), parameterEnum: z.enum([ 'Success', 'Warning', @@ -1627,23 +1467,20 @@ export const zTypesResponse = z.union([ export const zUploadFileData = z.object({ body: z.string(), path: z.object({ - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.string().nullable() }), - query: z.optional(z.never()) + query: z.never().optional() }); export const zUploadFileResponse = z.boolean(); export const zFileResponseData = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ id: z.string(), 'api-version': z.string() }), - query: z.optional(z.never()) + query: z.never().optional() }); /** @@ -1652,15 +1489,15 @@ export const zFileResponseData = z.object({ export const zFileResponseResponse = z.string(); export const zComplexTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ parameterObject: z.object({ - first: z.optional(z.object({ - second: z.optional(z.object({ - third: z.optional(z.string()) - })) - })) + first: z.object({ + second: z.object({ + third: z.string().optional() + }).optional() + }).optional() }), parameterReference: zModelWithString }) @@ -1672,77 +1509,59 @@ export const zComplexTypesData = z.object({ export const zComplexTypesResponse = z.array(zModelWithString); export const zMultipartResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** * OK */ export const zMultipartResponseResponse = z.object({ - file: z.optional(z.string()), - metadata: z.optional(z.object({ - foo: z.optional(z.string()), - bar: z.optional(z.string()) - })) + file: z.string().optional(), + metadata: z.object({ + foo: z.string().optional(), + bar: z.string().optional() + }).optional() }); export const zMultipartRequestData = z.object({ - body: z.optional(z.object({ - content: z.optional(z.string()), - data: z.optional(z.union([ - zModelWithString, - z.null() - ])) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.object({ + content: z.string().optional(), + data: zModelWithString.nullish() + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zComplexParamsData = z.object({ - body: z.optional(z.object({ - key: z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly(), - z.null() - ]).readonly(), - name: z.union([ - z.string().max(255), - z.null() - ]), - enabled: z.optional(z.boolean()).default(true), + body: z.object({ + key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly().nullable(), + name: z.string().max(255).nullable(), + enabled: z.boolean().optional().default(true), type: z.enum([ 'Monkey', 'Horse', 'Bird' ]), - listOfModels: z.optional(z.union([ - z.array(zModelWithString), - z.null() - ])), - listOfStrings: z.optional(z.union([ - z.array(z.string()), - z.null() - ])), + listOfModels: z.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), parameters: z.union([ zModelWithString, zModelWithEnum, zModelWithArray, zModelWithDictionary ]), - user: z.optional(z.object({ - id: z.optional(z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).readonly()), - name: z.optional(z.union([ - z.string().readonly(), - z.null() - ]).readonly()) - }).readonly()) - })), + user: z.object({ + id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).readonly().optional(), + name: z.string().readonly().nullish() + }).readonly().optional() + }).optional(), path: z.object({ id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }), 'api-version': z.string() }), - query: z.optional(z.never()) + query: z.never().optional() }); /** @@ -1751,22 +1570,22 @@ export const zComplexParamsData = z.object({ export const zComplexParamsResponse = zModelWithString; export const zCallWithResultFromHeaderData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zTestErrorCodeData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ status: z.int() }) }); export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ nonAsciiParamæøåÆØÅöôêÊ: z.int() }) @@ -1779,6 +1598,6 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiS export const zPutWithFormUrlEncodedData = z.object({ body: zArrayWithStrings, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/enum-null/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/enum-null/zod.gen.ts index d75ecfc9c..60e4c5a54 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/enum-null/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/enum-null/zod.gen.ts @@ -2,7 +2,7 @@ import * as z from 'zod/v4'; -export const zFoo = z.nullable(z.enum(['foo', 'bar'])); +export const zFoo = z.enum(['foo', 'bar']).nullable(); export const zBar = z.enum(['foo', 'bar']); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/type-format-zod/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/type-format-zod/zod.gen.ts index 796146a69..9b6647e58 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/type-format-zod/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/type-format-zod/zod.gen.ts @@ -3,7 +3,7 @@ import * as z from 'zod/v4'; export const zFoo = z.object({ - bar: z.optional(z.int()), + bar: z.int().optional(), foo: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).default(BigInt(0)), id: z.string() }); @@ -13,9 +13,9 @@ export const zBar = z.object({ }); export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/validators/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/validators/zod.gen.ts index ee041b409..7618e3266 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/validators/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/validators/zod.gen.ts @@ -4,20 +4,13 @@ import * as z from 'zod/v4'; export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz'); -export const zFoo = z.union([ - z.object({ - foo: z.optional(z.string().regex(/^\d{3}-\d{2}-\d{4}$/)), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z.optional(z.int().gt(0)).default(0) - }), - z.null() -]).default(null); +export const zFoo = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy((): any => zBar).optional(), + baz: z.array(z.lazy((): any => zFoo)).optional(), + qux: z.int().gt(0).optional().default(0) +}).nullable().default(null); export const zBar = z.object({ - foo: z.optional(zFoo) + foo: zFoo.optional() }); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/default/zod.gen.ts index 66435ffcc..4fc868122 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/default/zod.gen.ts @@ -81,10 +81,7 @@ export const zSimpleFile = z.string(); /** * This is a simple string */ -export const zSimpleStringWithPattern = z.union([ - z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/)), - z.null() -]); +export const zSimpleStringWithPattern = z.nullable(z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/))); /** * This is a simple enum with strings @@ -180,10 +177,7 @@ export const zArrayWithAnyOfProperties = z.array(z.union([z.object({ })])); export const zAnyOfAnyAndNull = z.object({ - data: z.optional(z.union([ - z.unknown(), - z.null() - ])) + data: z.nullish(z.unknown()) }); /** @@ -282,22 +276,10 @@ export const zModelFromZendesk = z.string(); * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp1: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp1: z.union([ - z.string(), - z.null() - ]), - nullableProp2: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp2: z.union([ - z.string(), - z.null() - ]), + nullableProp1: z.nullish(z.string()), + nullableRequiredProp1: z.nullable(z.string()), + nullableProp2: z.nullish(z.string()), + nullableRequiredProp2: z.nullable(z.string()), 'foo_bar-enum': z.optional(z.enum([ 'Success', 'Warning', @@ -394,9 +376,7 @@ export const zDeprecatedModel = z.object({ * This is a model with one property containing a circular reference */ export const zModelWithCircularReference = z.object({ - get prop() { - return z.optional(z.lazy((): any => zModelWithCircularReference)); - } + prop: z.optional(z.lazy((): any => zModelWithCircularReference)) }); /** @@ -495,24 +475,20 @@ export const zConstValue = z.literal('ConstValue'); * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithNestedAnyOfAndNull = z.object({ - propA: z.optional(z.union([ - z.array(z.union([z3eNum1Период, zConstValue])), - z.null() - ])) + propA: z.nullish(z.array(z.union([z3eNum1Период, zConstValue]))) }); /** * This is a model with one property with a 'one of' relationship */ export const zCompositionWithOneOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.nullish(z.union([ z.object({ boolean: z.optional(z.boolean()) }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() + zModelWithDictionary ])) }); @@ -550,26 +526,22 @@ export const zCompositionWithOneOfAndComplexArrayDictionary = z.object({ * This is a model with one property with a 'all of' relationship */ export const zCompositionWithAllOfAndNullable = z.object({ - propA: z.optional(z.union([ - z.intersection(z.intersection(z.intersection(z.object({ - boolean: z.optional(z.boolean()) - }), zModelWithEnum), zModelWithArray), zModelWithDictionary), - z.null() - ])) + propA: z.nullish(z.intersection(z.intersection(z.intersection(z.object({ + boolean: z.optional(z.boolean()) + }), zModelWithEnum), zModelWithArray), zModelWithDictionary)) }); /** * This is a model with one property with a 'any of' relationship */ export const zCompositionWithAnyOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.nullish(z.union([ z.object({ boolean: z.optional(z.boolean()) }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() + zModelWithDictionary ])) }); @@ -596,10 +568,7 @@ export const zCompositionExtendedModel = z.intersection(zCompositionBaseModel, z export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.readonly(z.string()), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.nullable(z.string()), string: z.optional(z.string()), number: z.optional(z.number()), boolean: z.optional(z.boolean()), @@ -622,20 +591,11 @@ export const zModelWithReference = z.object({ * This is a model with one nested property */ export const zModelWithNestedProperties = z.object({ - first: z.readonly(z.union([ - z.readonly(z.object({ - second: z.readonly(z.union([ - z.readonly(z.object({ - third: z.readonly(z.union([ - z.readonly(z.string()), - z.null() - ])) - })), - z.null() - ])) - })), - z.null() - ])) + first: z.nullable(z.readonly(z.object({ + second: z.nullable(z.readonly(z.object({ + third: z.nullable(z.readonly(z.string())) + }))) + }))) }); /** @@ -742,21 +702,15 @@ export const zModelWithAdditionalPropertiesEqTrue = z.object({ }); export const zNestedAnyOfArraysNullable = z.object({ - nullableArray: z.optional(z.union([ - z.array(z.union([z.string(), z.boolean()])), - z.null() - ])) + nullableArray: z.nullish(z.array(z.union([z.string(), z.boolean()]))) }); /** * An object that can be null */ -export const zNullableObject = z._default(z.union([ - z.object({ - foo: z.optional(z.string()) - }), - z.null() -]), null); +export const zNullableObject = z._default(z.nullable(z.object({ + foo: z.optional(z.string()) +})), null); /** * Some % character @@ -846,21 +800,18 @@ export const zModelWithPrefixItemsConstantSizeArray = z.tuple([ ]); export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([ - z.union([ + z.nullable(z.union([ z.number(), - z.null(), z.string() - ]), - z.union([ + ])), + z.nullable(z.union([ z.number(), - z.null(), z.string() - ]), - z.union([ + ])), + z.nullable(z.union([ z.number(), - z.null(), z.string() - ]) + ])) ]); export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([z.intersection(z.number(), z.string()), z.intersection(z.number(), z.string())]); @@ -979,23 +930,14 @@ export const zAdditionalPropertiesIntegerIssue = z.object({ export const zGenericSchemaDuplicateIssue1SystemBoolean = z.object({ item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), + error: z.nullish(z.string()), hasError: z.optional(z.readonly(z.boolean())), data: z.optional(z.record(z.string(), z.never())) }); export const zGenericSchemaDuplicateIssue1SystemString = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])), + item: z.nullish(z.string()), + error: z.nullish(z.string()), hasError: z.optional(z.readonly(z.boolean())) }); @@ -1027,10 +969,7 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.nullable(z.string()), string: z.optional(z.string()), number: z.optional(z.number()), boolean: z.optional(z.boolean()), @@ -1101,22 +1040,13 @@ export const zOneOfAllOfIssueWritable = z.union([ export const zGenericSchemaDuplicateIssue1SystemBooleanWritable = z.object({ item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), + error: z.nullish(z.string()), data: z.optional(z.record(z.string(), z.never())) }); export const zGenericSchemaDuplicateIssue1SystemStringWritable = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])) + item: z.nullish(z.string()), + error: z.nullish(z.string()) }); /** @@ -1132,10 +1062,7 @@ export const zCompositionWithOneOfAndProperties = z.intersection(z.union([ bar: zNonAsciiStringæøåÆøÅöôêÊ字符串 }) ]), z.object({ - baz: z.union([ - z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' })), - z.null() - ]), + baz: z.nullable(z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }))), qux: z.int().check(z.gte(0), z.maximum(255, { error: 'Invalid value: Expected uint8 to be <= 255' })) })); @@ -1143,10 +1070,7 @@ export const zModelWithOneOfAndProperties = z.intersection(z.union([ zSimpleParameter, zNonAsciiStringæøåÆøÅöôêÊ字符串 ]), z.object({ - baz: z.union([ - z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' })), - z.null() - ]), + baz: z.nullable(z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }))), qux: z.int().check(z.gte(0), z.maximum(255, { error: 'Invalid value: Expected uint8 to be <= 255' })) })); @@ -1296,70 +1220,40 @@ export const zDeprecatedCallData = z.object({ path: z.optional(z.never()), query: z.optional(z.never()), headers: z.object({ - parameter: z.union([ - zDeprecatedModel, - z.null() - ]) + parameter: z.nullable(zDeprecatedModel) }) }); export const zCallWithParametersData = z.object({ - body: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + body: z.nullable(z.record(z.string(), z.unknown())), path: z.object({ - parameterPath: z.union([ - z.string(), - z.null() - ]), - 'api-version': z.union([ - z.string(), - z.null() - ]) + parameterPath: z.nullable(z.string()), + 'api-version': z.nullable(z.string()) }), query: z.object({ foo_ref_enum: z.optional(zModelWithNestedArrayEnumsDataFoo), foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.union([ - z.string(), - z.null() - ]) + cursor: z.nullable(z.string()) }), headers: z.object({ - parameterHeader: z.union([ - z.string(), - z.null() - ]) + parameterHeader: z.nullable(z.string()) }) }); export const zCallWithWeirdParameterNamesData = z.object({ - body: z.union([ - zModelWithString, - z.null() - ]), + body: z.nullable(zModelWithString), path: z.object({ 'parameter.path.1': z.optional(z.string()), 'parameter-path-2': z.optional(z.string()), 'PARAMETER-PATH-3': z.optional(z.string()), - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.nullable(z.string()) }), query: z.object({ default: z.optional(z.string()), - 'parameter-query': z.union([ - z.string(), - z.null() - ]) + 'parameter-query': z.nullable(z.string()) }), headers: z.object({ - 'parameter.header': z.union([ - z.string(), - z.null() - ]) + 'parameter.header': z.nullable(z.string()) }) }); @@ -1373,10 +1267,7 @@ export const zGetCallWithOptionalParamData = z.object({ export const zPostCallWithOptionalParamData = z.object({ body: z.optional(z.object({ - offset: z.optional(z.union([ - z.number(), - z.null() - ])) + offset: z.nullish(z.number()) })), path: z.optional(z.never()), query: z.object({ @@ -1409,27 +1300,15 @@ export const zCallWithDefaultParametersData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), query: z.optional(z.object({ - parameterString: z._default(z.optional(z.union([ - z._default(z.string(), 'Hello World!'), - z.null() - ])), 'Hello World!'), - parameterNumber: z._default(z.optional(z.union([ - z._default(z.number(), 123), - z.null() - ])), 123), - parameterBoolean: z._default(z.optional(z.union([ - z._default(z.boolean(), true), - z.null() - ])), true), + parameterString: z._default(z.nullish(z.string()), 'Hello World!'), + parameterNumber: z._default(z.nullish(z.number()), 123), + parameterBoolean: z._default(z.nullish(z.boolean()), true), parameterEnum: z.optional(z.enum([ 'Success', 'Warning', 'Error' ])), - parameterModel: z.optional(z.union([ - z._default(zModelWithString, { prop: 'Hello World!' }), - z.null() - ])) + parameterModel: z.nullish(zModelWithString) })) }); @@ -1459,14 +1338,8 @@ export const zCallToTestOrderOfParamsData = z.object({ parameterStringWithDefault: z._default(z.string(), 'Hello World!'), parameterStringWithEmptyDefault: z._default(z.string(), ''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.optional(z.union([ - z.string(), - z.null() - ])), - parameterStringNullableWithDefault: z._default(z.optional(z.union([ - z.string(), - z.null() - ])), null) + parameterStringNullableWithNoDefault: z.nullish(z.string()), + parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) }) }); @@ -1574,26 +1447,11 @@ export const zCollectionFormatData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), query: z.object({ - parameterArrayCSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArraySSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayTSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayPipes: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayMulti: z.union([ - z.array(z.string()), - z.null() - ]) + parameterArrayCSV: z.nullable(z.array(z.string())), + parameterArraySSV: z.nullable(z.array(z.string())), + parameterArrayTSV: z.nullable(z.array(z.string())), + parameterArrayPipes: z.nullable(z.array(z.string())), + parameterArrayMulti: z.nullable(z.array(z.string())) }) }); @@ -1604,32 +1462,16 @@ export const zTypesData = z.object({ })), query: z.object({ parameterNumber: z._default(z.number(), 123), - parameterString: z._default(z.union([ - z._default(z.string(), 'default'), - z.null() - ]), 'default'), - parameterBoolean: z._default(z.union([ - z._default(z.boolean(), true), - z.null() - ]), true), - parameterObject: z._default(z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), null), - parameterArray: z.union([ - z.array(z.string()), - z.null() - ]), - parameterDictionary: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), - parameterEnum: z.union([ + parameterString: z._default(z.nullable(z.string()), 'default'), + parameterBoolean: z._default(z.nullable(z.boolean()), true), + parameterObject: z._default(z.nullable(z.record(z.string(), z.unknown())), null), + parameterArray: z.nullable(z.array(z.string())), + parameterDictionary: z.nullable(z.record(z.string(), z.unknown())), + parameterEnum: z.nullable(z.union([ z.literal('Success'), z.literal('Warning'), - z.literal('Error'), - z.null() - ]) + z.literal('Error') + ])) }) }); @@ -1643,10 +1485,7 @@ export const zTypesResponse = z.union([ export const zUploadFileData = z.object({ body: z.string(), path: z.object({ - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.nullable(z.string()) }), query: z.optional(z.never()) }); @@ -1707,10 +1546,7 @@ export const zMultipartResponseResponse = z.object({ export const zMultipartRequestData = z.object({ body: z.optional(z.object({ content: z.optional(z.string()), - data: z.optional(z.union([ - zModelWithString, - z.null() - ])) + data: z.nullish(zModelWithString) })), path: z.optional(z.never()), query: z.optional(z.never()) @@ -1718,28 +1554,16 @@ export const zMultipartRequestData = z.object({ export const zComplexParamsData = z.object({ body: z.optional(z.object({ - key: z.readonly(z.union([ - z.readonly(z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/))), - z.null() - ])), - name: z.union([ - z.string().check(z.maxLength(255)), - z.null() - ]), + key: z.nullable(z.readonly(z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/)))), + name: z.nullable(z.string().check(z.maxLength(255))), enabled: z._default(z.optional(z.boolean()), true), type: z.enum([ 'Monkey', 'Horse', 'Bird' ]), - listOfModels: z.optional(z.union([ - z.array(zModelWithString), - z.null() - ])), - listOfStrings: z.optional(z.union([ - z.array(z.string()), - z.null() - ])), + listOfModels: z.nullish(z.array(zModelWithString)), + listOfStrings: z.nullish(z.array(z.string())), parameters: z.union([ zModelWithString, zModelWithEnum, @@ -1748,10 +1572,7 @@ export const zComplexParamsData = z.object({ ]), user: z.optional(z.readonly(z.object({ id: z.optional(z.readonly(z.int().check(z.minimum(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }), z.maximum(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })))), - name: z.optional(z.readonly(z.union([ - z.readonly(z.string()), - z.null() - ]))) + name: z.nullish(z.readonly(z.string())) }))) })), path: z.object({ diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/enum-resolver-permissive/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/enum-resolver-permissive/zod.gen.ts index 60ea6ed96..6f60a52cf 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/enum-resolver-permissive/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/enum-resolver-permissive/zod.gen.ts @@ -2,7 +2,7 @@ import * as z from 'zod/v4-mini'; -export const zFoo = z.union([z.enum(['foo', 'bar']), z.string()]); +export const zFoo = z.nullable(z.union([z.enum(['foo', 'bar']), z.string()])); export const zBar = z.union([z.enum(['foo', 'bar']), z.string()]); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-circular-ref-2/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-circular-ref-2/zod.gen.ts index 3a8f1806c..133c88c8f 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-circular-ref-2/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-circular-ref-2/zod.gen.ts @@ -3,10 +3,7 @@ import * as z from 'zod/v4-mini'; export const zBar = z.object({ - bar: z.union([ - z.array(z.lazy((): any => zBar)), - z.null() - ]) + bar: z.nullable(z.array(z.lazy((): any => zBar))) }); export const zFoo = z.object({ diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-circular-ref/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-circular-ref/zod.gen.ts index dda5d4694..d1aa42ffa 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-circular-ref/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-circular-ref/zod.gen.ts @@ -3,9 +3,7 @@ import * as z from 'zod/v4-mini'; export const zBar = z.object({ - get bar() { - return z.optional(z.array(z.lazy((): any => zBar))); - } + bar: z.optional(z.array(z.lazy((): any => zBar))) }); export const zFoo = z.object({ diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-dates/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-dates/zod.gen.ts index 8ecedac9a..9b93e42fc 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-dates/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-dates/zod.gen.ts @@ -11,19 +11,12 @@ export const zQux = z.record(z.string(), z.object({ /** * This is Foo schema. */ -export const zFoo = z._default(z.union([ - z.object({ - foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z._default(z.optional(z.int().check(z.gt(0))), 0) - }), - z.null() -]), null); +export const zFoo = z._default(z.nullable(z.object({ + foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), + bar: z.optional(z.lazy((): any => zBar)), + baz: z.optional(z.array(z.lazy((): any => zFoo))), + qux: z._default(z.optional(z.int().check(z.gt(0))), 0) +})), null); /** * This is Bar schema. diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-metadata/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-metadata/zod.gen.ts index 789eb6d8a..87ec55918 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-metadata/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-metadata/zod.gen.ts @@ -11,25 +11,18 @@ export const zQux = z.record(z.string(), z.object({ /** * This is Foo schema. */ -export const zFoo = z._default(z.union([ - z.object({ - foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/)).register(z.globalRegistry, { - description: 'This is foo property.' - })), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo)).register(z.globalRegistry, { - description: 'This is baz property.' - })); - }, - qux: z._default(z.optional(z.int().check(z.gt(0)).register(z.globalRegistry, { - description: 'This is qux property.' - })), 0) - }), - z.null() -]), null); +export const zFoo = z._default(z.nullable(z.object({ + foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/)).register(z.globalRegistry, { + description: 'This is foo property.' + })), + bar: z.optional(z.lazy((): any => zBar)), + baz: z.optional(z.array(z.lazy((): any => zFoo)).register(z.globalRegistry, { + description: 'This is baz property.' + })), + qux: z._default(z.optional(z.int().check(z.gt(0)).register(z.globalRegistry, { + description: 'This is qux property.' + })), 0) +})), null); /** * This is Bar schema. diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-types/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-types/zod.gen.ts index a8353e832..272e5ee8b 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-types/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators-types/zod.gen.ts @@ -15,19 +15,12 @@ export type QuxZodType = z.infer; /** * This is Foo schema. */ -export const zFoo = z._default(z.union([ - z.object({ - foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z._default(z.optional(z.int().check(z.gt(0))), 0) - }), - z.null() -]), null); +export const zFoo = z._default(z.nullable(z.object({ + foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), + bar: z.optional(z.lazy((): any => zBar)), + baz: z.optional(z.array(z.lazy((): any => zFoo))), + qux: z._default(z.optional(z.int().check(z.gt(0))), 0) +})), null); export type FooZodType = z.infer; diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators/zod.gen.ts index 304d89bb5..e21539a88 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/validators/zod.gen.ts @@ -11,19 +11,12 @@ export const zQux = z.record(z.string(), z.object({ /** * This is Foo schema. */ -export const zFoo = z._default(z.union([ - z.object({ - foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z._default(z.optional(z.int().check(z.gt(0))), 0) - }), - z.null() -]), null); +export const zFoo = z._default(z.nullable(z.object({ + foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), + bar: z.optional(z.lazy((): any => zBar)), + baz: z.optional(z.array(z.lazy((): any => zFoo))), + qux: z._default(z.optional(z.int().check(z.gt(0))), 0) +})), null); /** * This is Bar schema. diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/default/zod.gen.ts index d61228f60..4742b6e60 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/default/zod.gen.ts @@ -81,10 +81,7 @@ export const zSimpleFile = z.string(); /** * This is a simple string */ -export const zSimpleStringWithPattern = z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), - z.null() -]); +export const zSimpleStringWithPattern = z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).nullable(); /** * This is a simple enum with strings @@ -180,10 +177,7 @@ export const zArrayWithAnyOfProperties = z.array(z.union([z.object({ })])); export const zAnyOfAnyAndNull = z.object({ - data: z.union([ - z.unknown(), - z.null() - ]).optional() + data: z.unknown().nullish() }); /** @@ -282,22 +276,10 @@ export const zModelFromZendesk = z.string(); * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp1: z.union([ - z.string(), - z.null() - ]).optional(), - nullableRequiredProp1: z.union([ - z.string(), - z.null() - ]), - nullableProp2: z.union([ - z.string(), - z.null() - ]).optional(), - nullableRequiredProp2: z.union([ - z.string(), - z.null() - ]), + nullableProp1: z.string().nullish(), + nullableRequiredProp1: z.string().nullable(), + nullableProp2: z.string().nullish(), + nullableRequiredProp2: z.string().nullable(), 'foo_bar-enum': z.enum([ 'Success', 'Warning', @@ -493,10 +475,7 @@ export const zConstValue = z.literal('ConstValue'); * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithNestedAnyOfAndNull = z.object({ - propA: z.union([ - z.array(z.union([z3eNum1Период, zConstValue])), - z.null() - ]).optional() + propA: z.array(z.union([z3eNum1Период, zConstValue])).nullish() }); /** @@ -509,9 +488,8 @@ export const zCompositionWithOneOfAndNullable = z.object({ }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ]).optional() + zModelWithDictionary + ]).nullish() }); /** @@ -548,12 +526,9 @@ export const zCompositionWithOneOfAndComplexArrayDictionary = z.object({ * This is a model with one property with a 'all of' relationship */ export const zCompositionWithAllOfAndNullable = z.object({ - propA: z.union([ - z.object({ - boolean: z.boolean().optional() - }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary), - z.null() - ]).optional() + propA: z.object({ + boolean: z.boolean().optional() + }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary).nullish() }); /** @@ -566,9 +541,8 @@ export const zCompositionWithAnyOfAndNullable = z.object({ }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ]).optional() + zModelWithDictionary + ]).nullish() }); /** @@ -594,10 +568,7 @@ export const zCompositionExtendedModel = zCompositionBaseModel.and(z.object({ export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.string().readonly(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.string().nullable(), string: z.string().optional(), number: z.number().optional(), boolean: z.boolean().optional(), @@ -620,20 +591,11 @@ export const zModelWithReference = z.object({ * This is a model with one nested property */ export const zModelWithNestedProperties = z.object({ - first: z.union([ - z.object({ - second: z.union([ - z.object({ - third: z.union([ - z.string().readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() + first: z.object({ + second: z.object({ + third: z.string().readonly().nullable() + }).readonly().nullable() + }).readonly().nullable() }); /** @@ -740,21 +702,15 @@ export const zModelWithAdditionalPropertiesEqTrue = z.object({ }); export const zNestedAnyOfArraysNullable = z.object({ - nullableArray: z.union([ - z.array(z.union([z.string(), z.boolean()])), - z.null() - ]).optional() + nullableArray: z.array(z.union([z.string(), z.boolean()])).nullish() }); /** * An object that can be null */ -export const zNullableObject = z.union([ - z.object({ - foo: z.string().optional() - }), - z.null() -]).default(null); +export const zNullableObject = z.object({ + foo: z.string().optional() +}).nullable().default(null); /** * Some % character @@ -846,19 +802,16 @@ export const zModelWithPrefixItemsConstantSizeArray = z.tuple([ export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([ z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]) + ]).nullable() ]); export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([z.intersection(z.number(), z.string()), z.intersection(z.number(), z.string())]); @@ -977,23 +930,14 @@ export const zAdditionalPropertiesIntegerIssue = z.object({ export const zGenericSchemaDuplicateIssue1SystemBoolean = z.object({ item: z.boolean().optional(), - error: z.union([ - z.string(), - z.null() - ]).optional(), + error: z.string().nullish(), hasError: z.boolean().readonly().optional(), data: z.record(z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemString = z.object({ - item: z.union([ - z.string(), - z.null() - ]).optional(), - error: z.union([ - z.string(), - z.null() - ]).optional(), + item: z.string().nullish(), + error: z.string().nullish(), hasError: z.boolean().readonly().optional() }); @@ -1025,10 +969,7 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.string().nullable(), string: z.string().optional(), number: z.number().optional(), boolean: z.boolean().optional(), @@ -1099,22 +1040,13 @@ export const zOneOfAllOfIssueWritable = z.union([ export const zGenericSchemaDuplicateIssue1SystemBooleanWritable = z.object({ item: z.boolean().optional(), - error: z.union([ - z.string(), - z.null() - ]).optional(), + error: z.string().nullish(), data: z.record(z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemStringWritable = z.object({ - item: z.union([ - z.string(), - z.null() - ]).optional(), - error: z.union([ - z.string(), - z.null() - ]).optional() + item: z.string().nullish(), + error: z.string().nullish() }); /** @@ -1130,10 +1062,7 @@ export const zCompositionWithOneOfAndProperties = z.intersection(z.union([ bar: zNonAsciiStringæøåÆøÅöôêÊ字符串 }) ]), z.object({ - baz: z.union([ - z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.number().int().gte(0).max(255, { message: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1141,10 +1070,7 @@ export const zModelWithOneOfAndProperties = z.intersection(z.union([ zSimpleParameter, zNonAsciiStringæøåÆøÅöôêÊ字符串 ]), z.object({ - baz: z.union([ - z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.number().int().gte(0).max(255, { message: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1294,70 +1220,40 @@ export const zDeprecatedCallData = z.object({ path: z.never().optional(), query: z.never().optional(), headers: z.object({ - parameter: z.union([ - zDeprecatedModel, - z.null() - ]) + parameter: zDeprecatedModel.nullable() }) }); export const zCallWithParametersData = z.object({ - body: z.union([ - z.record(z.unknown()), - z.null() - ]), + body: z.record(z.unknown()).nullable(), path: z.object({ - parameterPath: z.union([ - z.string(), - z.null() - ]), - 'api-version': z.union([ - z.string(), - z.null() - ]) + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }), query: z.object({ foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.union([ - z.string(), - z.null() - ]) + cursor: z.string().nullable() }), headers: z.object({ - parameterHeader: z.union([ - z.string(), - z.null() - ]) + parameterHeader: z.string().nullable() }) }); export const zCallWithWeirdParameterNamesData = z.object({ - body: z.union([ - zModelWithString, - z.null() - ]), + body: zModelWithString.nullable(), path: z.object({ 'parameter.path.1': z.string().optional(), 'parameter-path-2': z.string().optional(), 'PARAMETER-PATH-3': z.string().optional(), - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.string().nullable() }), query: z.object({ default: z.string().optional(), - 'parameter-query': z.union([ - z.string(), - z.null() - ]) + 'parameter-query': z.string().nullable() }), headers: z.object({ - 'parameter.header': z.union([ - z.string(), - z.null() - ]) + 'parameter.header': z.string().nullable() }) }); @@ -1371,10 +1267,7 @@ export const zGetCallWithOptionalParamData = z.object({ export const zPostCallWithOptionalParamData = z.object({ body: z.object({ - offset: z.union([ - z.number(), - z.null() - ]).optional() + offset: z.number().nullish() }).optional(), path: z.never().optional(), query: z.object({ @@ -1407,27 +1300,15 @@ export const zCallWithDefaultParametersData = z.object({ body: z.never().optional(), path: z.never().optional(), query: z.object({ - parameterString: z.union([ - z.string().default('Hello World!'), - z.null() - ]).optional().default('Hello World!'), - parameterNumber: z.union([ - z.number().default(123), - z.null() - ]).optional().default(123), - parameterBoolean: z.union([ - z.boolean().default(true), - z.null() - ]).optional().default(true), + parameterString: z.string().nullish().default('Hello World!'), + parameterNumber: z.number().nullish().default(123), + parameterBoolean: z.boolean().nullish().default(true), parameterEnum: z.enum([ 'Success', 'Warning', 'Error' ]).optional(), - parameterModel: z.union([ - zModelWithString.default({ prop: 'Hello World!' }), - z.null() - ]).optional() + parameterModel: zModelWithString.nullish() }).optional() }); @@ -1457,14 +1338,8 @@ export const zCallToTestOrderOfParamsData = z.object({ parameterStringWithDefault: z.string().default('Hello World!'), parameterStringWithEmptyDefault: z.string().default(''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.union([ - z.string(), - z.null() - ]).optional(), - parameterStringNullableWithDefault: z.union([ - z.string(), - z.null() - ]).optional().default(null) + parameterStringNullableWithNoDefault: z.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }) }); @@ -1572,26 +1447,11 @@ export const zCollectionFormatData = z.object({ body: z.never().optional(), path: z.never().optional(), query: z.object({ - parameterArrayCSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArraySSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayTSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayPipes: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayMulti: z.union([ - z.array(z.string()), - z.null() - ]) + parameterArrayCSV: z.array(z.string()).nullable(), + parameterArraySSV: z.array(z.string()).nullable(), + parameterArrayTSV: z.array(z.string()).nullable(), + parameterArrayPipes: z.array(z.string()).nullable(), + parameterArrayMulti: z.array(z.string()).nullable() }) }); @@ -1602,32 +1462,16 @@ export const zTypesData = z.object({ }).optional(), query: z.object({ parameterNumber: z.number().default(123), - parameterString: z.union([ - z.string().default('default'), - z.null() - ]).default('default'), - parameterBoolean: z.union([ - z.boolean().default(true), - z.null() - ]).default(true), - parameterObject: z.union([ - z.record(z.unknown()), - z.null() - ]).default(null), - parameterArray: z.union([ - z.array(z.string()), - z.null() - ]), - parameterDictionary: z.union([ - z.record(z.unknown()), - z.null() - ]), + parameterString: z.string().nullable().default('default'), + parameterBoolean: z.boolean().nullable().default(true), + parameterObject: z.record(z.unknown()).nullable().default(null), + parameterArray: z.array(z.string()).nullable(), + parameterDictionary: z.record(z.unknown()).nullable(), parameterEnum: z.union([ z.literal('Success'), z.literal('Warning'), - z.literal('Error'), - z.null() - ]) + z.literal('Error') + ]).nullable() }) }); @@ -1641,10 +1485,7 @@ export const zTypesResponse = z.union([ export const zUploadFileData = z.object({ body: z.string(), path: z.object({ - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.string().nullable() }), query: z.never().optional() }); @@ -1705,10 +1546,7 @@ export const zMultipartResponseResponse = z.object({ export const zMultipartRequestData = z.object({ body: z.object({ content: z.string().optional(), - data: z.union([ - zModelWithString, - z.null() - ]).optional() + data: zModelWithString.nullish() }).optional(), path: z.never().optional(), query: z.never().optional() @@ -1716,28 +1554,16 @@ export const zMultipartRequestData = z.object({ export const zComplexParamsData = z.object({ body: z.object({ - key: z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly(), - z.null() - ]).readonly(), - name: z.union([ - z.string().max(255), - z.null() - ]), + key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly().nullable(), + name: z.string().max(255).nullable(), enabled: z.boolean().optional().default(true), type: z.enum([ 'Monkey', 'Horse', 'Bird' ]), - listOfModels: z.union([ - z.array(zModelWithString), - z.null() - ]).optional(), - listOfStrings: z.union([ - z.array(z.string()), - z.null() - ]).optional(), + listOfModels: z.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), parameters: z.union([ zModelWithString, zModelWithEnum, @@ -1746,10 +1572,7 @@ export const zComplexParamsData = z.object({ ]), user: z.object({ id: z.number().int().min(-2147483648, { message: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { message: 'Invalid value: Expected int32 to be <= 2147483647' }).readonly().optional(), - name: z.union([ - z.string().readonly(), - z.null() - ]).readonly().optional() + name: z.string().readonly().nullish() }).readonly().optional() }).optional(), path: z.object({ diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/enum-resolver-permissive/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/enum-resolver-permissive/zod.gen.ts index 8e2f23122..ebf95932f 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/enum-resolver-permissive/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/enum-resolver-permissive/zod.gen.ts @@ -2,7 +2,7 @@ import { z } from 'zod'; -export const zFoo = z.union([z.enum(['foo', 'bar']), z.string()]); +export const zFoo = z.union([z.enum(['foo', 'bar']), z.string()]).nullable(); export const zBar = z.union([z.enum(['foo', 'bar']), z.string()]); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-circular-ref-2/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-circular-ref-2/zod.gen.ts index f2c188be3..b2db86b0e 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-circular-ref-2/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-circular-ref-2/zod.gen.ts @@ -3,10 +3,7 @@ import { z } from 'zod'; export const zBar: z.AnyZodObject = z.object({ - bar: z.union([ - z.array(z.lazy(() => zBar)), - z.null() - ]) + bar: z.array(z.lazy(() => zBar)).nullable() }); export const zFoo = z.object({ diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-dates/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-dates/zod.gen.ts index c9317d591..56a06552a 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-dates/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-dates/zod.gen.ts @@ -11,15 +11,12 @@ export const zQux = z.record(z.object({ /** * This is Foo schema. */ -export const zFoo: z.ZodTypeAny = z.union([ - z.object({ - foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), - bar: z.lazy(() => zBar).optional(), - baz: z.array(z.lazy(() => zFoo)).optional(), - qux: z.number().int().gt(0).optional().default(0) - }), - z.null() -]).default(null); +export const zFoo: z.ZodTypeAny = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy(() => zBar).optional(), + baz: z.array(z.lazy(() => zFoo)).optional(), + qux: z.number().int().gt(0).optional().default(0) +}).nullable().default(null); /** * This is Bar schema. diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-metadata/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-metadata/zod.gen.ts index 58ea4d7b8..685be7b15 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-metadata/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-metadata/zod.gen.ts @@ -11,15 +11,12 @@ export const zQux = z.record(z.object({ /** * This is Foo schema. */ -export const zFoo: z.ZodTypeAny = z.union([ - z.object({ - foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).describe('This is foo property.').optional(), - bar: z.lazy(() => zBar).optional(), - baz: z.array(z.lazy(() => zFoo)).describe('This is baz property.').optional(), - qux: z.number().int().gt(0).describe('This is qux property.').optional().default(0) - }), - z.null() -]).default(null); +export const zFoo: z.ZodTypeAny = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).describe('This is foo property.').optional(), + bar: z.lazy(() => zBar).optional(), + baz: z.array(z.lazy(() => zFoo)).describe('This is baz property.').optional(), + qux: z.number().int().gt(0).describe('This is qux property.').optional().default(0) +}).nullable().default(null); /** * This is Bar schema. diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-types/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-types/zod.gen.ts index c26d40cf3..89abc2a22 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-types/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators-types/zod.gen.ts @@ -15,15 +15,12 @@ export type QuxZodType = z.infer; /** * This is Foo schema. */ -export const zFoo: z.ZodTypeAny = z.union([ - z.object({ - foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), - bar: z.lazy(() => zBar).optional(), - baz: z.array(z.lazy(() => zFoo)).optional(), - qux: z.number().int().gt(0).optional().default(0) - }), - z.null() -]).default(null); +export const zFoo: z.ZodTypeAny = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy(() => zBar).optional(), + baz: z.array(z.lazy(() => zFoo)).optional(), + qux: z.number().int().gt(0).optional().default(0) +}).nullable().default(null); export type FooZodType = z.infer; diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators/zod.gen.ts index 8e5318a8c..9ccffb61d 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/validators/zod.gen.ts @@ -11,15 +11,12 @@ export const zQux = z.record(z.object({ /** * This is Foo schema. */ -export const zFoo: z.ZodTypeAny = z.union([ - z.object({ - foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), - bar: z.lazy(() => zBar).optional(), - baz: z.array(z.lazy(() => zFoo)).optional(), - qux: z.number().int().gt(0).optional().default(0) - }), - z.null() -]).default(null); +export const zFoo: z.ZodTypeAny = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy(() => zBar).optional(), + baz: z.array(z.lazy(() => zFoo)).optional(), + qux: z.number().int().gt(0).optional().default(0) +}).nullable().default(null); /** * This is Bar schema. diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/array-items-all-of/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/array-items-all-of/zod.gen.ts index 8ff0d5371..400acc952 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/array-items-all-of/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/array-items-all-of/zod.gen.ts @@ -3,18 +3,18 @@ import * as z from 'zod/v4'; export const zArrayWithAllOfObjects = z.array(z.object({ - id: z.optional(z.int()) + id: z.int().optional() }).and(z.object({ - name: z.optional(z.string()) + name: z.string().optional() }))); export const zArrayWithAllOfPrimitives = z.array(z.intersection(z.number(), z.string())); export const zBaseModel = z.object({ - id: z.optional(z.int()), - createdAt: z.optional(z.iso.datetime()) + id: z.int().optional(), + createdAt: z.iso.datetime().optional() }); export const zArrayWithAllOfRefs = z.array(zBaseModel.and(z.object({ - extra: z.optional(z.string()) + extra: z.string().optional() }))); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/array-items-one-of-length-1/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/array-items-one-of-length-1/zod.gen.ts index e1f2e86f8..92dfb2397 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/array-items-one-of-length-1/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/array-items-one-of-length-1/zod.gen.ts @@ -5,5 +5,5 @@ import * as z from 'zod/v4'; export const zBar = z.string(); export const zFoo = z.object({ - foo: z.optional(z.array(zBar).min(1).max(2147483647)) + foo: z.array(zBar).min(1).max(2147483647).optional() }); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/default/zod.gen.ts index 2b94366c7..5fd7046ad 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/default/zod.gen.ts @@ -81,10 +81,7 @@ export const zSimpleFile = z.string(); /** * This is a simple string */ -export const zSimpleStringWithPattern = z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), - z.null() -]); +export const zSimpleStringWithPattern = z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).nullable(); /** * This is a simple enum with strings @@ -166,35 +163,32 @@ export const zArrayWithStrings = z.array(z.string()).default(['test']); * This is a simple array with properties */ export const zArrayWithProperties = z.array(z.object({ - '16x16': z.optional(zCamelCaseCommentWithBreaks), - bar: z.optional(z.string()) + '16x16': zCamelCaseCommentWithBreaks.optional(), + bar: z.string().optional() })); /** * This is a simple array with any of properties */ export const zArrayWithAnyOfProperties = z.array(z.union([z.object({ - foo: z.optional(z.string()).default('test') + foo: z.string().optional().default('test') }), z.object({ - bar: z.optional(z.string()) + bar: z.string().optional() })])); export const zAnyOfAnyAndNull = z.object({ - data: z.optional(z.union([ - z.unknown(), - z.null() - ])) + data: z.unknown().nullish() }); /** * This is a simple array with any of properties */ export const zAnyOfArrays = z.object({ - results: z.optional(z.array(z.union([z.object({ - foo: z.optional(z.string()) + results: z.array(z.union([z.object({ + foo: z.string().optional() }), z.object({ - bar: z.optional(z.string()) - })]))) + bar: z.string().optional() + })])).optional() }); /** @@ -203,8 +197,8 @@ export const zAnyOfArrays = z.object({ export const zDictionaryWithString = z.record(z.string(), z.string()); export const zDictionaryWithPropertiesAndAdditionalProperties = z.object({ - foo: z.optional(z.number()), - bar: z.optional(z.boolean()) + foo: z.number().optional(), + bar: z.boolean().optional() }); /** @@ -216,29 +210,29 @@ export const zDictionaryWithDictionary = z.record(z.string(), z.record(z.string( * This is a complex dictionary */ export const zDictionaryWithProperties = z.record(z.string(), z.object({ - foo: z.optional(z.string()), - bar: z.optional(z.string()) + foo: z.string().optional(), + bar: z.string().optional() })); /** * This is a model with one number property */ export const zModelWithInteger = z.object({ - prop: z.optional(z.int()) + prop: z.int().optional() }); /** * This is a model with one boolean property */ export const zModelWithBoolean = z.object({ - prop: z.optional(z.boolean()) + prop: z.boolean().optional() }); /** * This is a model with one string property */ export const zModelWithString = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** @@ -270,7 +264,7 @@ export const zDictionaryWithArray = z.record(z.string(), z.array(zModelWithStrin * This is a model with one string property */ export const zModelWithStringError = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** @@ -282,103 +276,91 @@ export const zModelFromZendesk = z.string(); * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp1: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp1: z.union([ - z.string(), - z.null() - ]), - nullableProp2: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp2: z.union([ - z.string(), - z.null() - ]), - 'foo_bar-enum': z.optional(z.enum([ + nullableProp1: z.string().nullish(), + nullableRequiredProp1: z.string().nullable(), + nullableProp2: z.string().nullish(), + nullableRequiredProp2: z.string().nullable(), + 'foo_bar-enum': z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])) + ]).optional() }); /** * This is a model with one enum */ export const zModelWithEnum = z.object({ - 'foo_bar-enum': z.optional(z.enum([ + 'foo_bar-enum': z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])), - statusCode: z.optional(z.enum([ + ]).optional(), + statusCode: z.enum([ '100', '200 FOO', '300 FOO_BAR', '400 foo-bar', '500 foo.bar', '600 foo&bar' - ])), - bool: z.optional(z.literal(true)) + ]).optional(), + bool: z.literal(true).optional() }); /** * This is a model with one enum with escaped name */ export const zModelWithEnumWithHyphen = z.object({ - 'foo-bar-baz-qux': z.optional(z.enum(['3.0'])) + 'foo-bar-baz-qux': z.enum(['3.0']).optional() }); /** * This is a model with one enum */ export const zModelWithEnumFromDescription = z.object({ - test: z.optional(z.int()) + test: z.int().optional() }); /** * This is a model with nested enums */ export const zModelWithNestedEnums = z.object({ - dictionaryWithEnum: z.optional(z.record(z.string(), z.enum([ + dictionaryWithEnum: z.record(z.string(), z.enum([ 'Success', 'Warning', 'Error' - ]))), - dictionaryWithEnumFromDescription: z.optional(z.record(z.string(), z.int())), - arrayWithEnum: z.optional(z.array(z.enum([ + ])).optional(), + dictionaryWithEnumFromDescription: z.record(z.string(), z.int()).optional(), + arrayWithEnum: z.array(z.enum([ 'Success', 'Warning', 'Error' - ]))), - arrayWithDescription: z.optional(z.array(z.int())), - 'foo_bar-enum': z.optional(z.enum([ + ])).optional(), + arrayWithDescription: z.array(z.int()).optional(), + 'foo_bar-enum': z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])) + ]).optional() }); /** * This is a model with one property containing an array */ export const zModelWithArray = z.object({ - prop: z.optional(z.array(zModelWithString)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithString).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); /** * This is a model with one property containing a dictionary */ export const zModelWithDictionary = z.object({ - prop: z.optional(z.record(z.string(), z.string())) + prop: z.record(z.string(), z.string()).optional() }); /** @@ -387,41 +369,39 @@ export const zModelWithDictionary = z.object({ * @deprecated */ export const zDeprecatedModel = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** * This is a model with one property containing a circular reference */ export const zModelWithCircularReference = z.object({ - get prop() { - return z.optional(z.lazy((): any => zModelWithCircularReference)); - } + prop: z.lazy((): any => zModelWithCircularReference).optional() }); /** * This is a model with one property with a 'one of' relationship */ export const zCompositionWithOneOf = z.object({ - propA: z.optional(z.union([ + propA: z.union([ zModelWithString, zModelWithEnum, zModelWithArray, zModelWithDictionary - ])) + ]).optional() }); /** * This is a model with one property with a 'one of' relationship where the options are not $ref */ export const zCompositionWithOneOfAnonymous = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - propA: z.optional(z.string()) + propA: z.string().optional() }), z.string(), z.int() - ])) + ]).optional() }); /** @@ -429,7 +409,7 @@ export const zCompositionWithOneOfAnonymous = z.object({ */ export const zModelCircle = z.object({ kind: z.string(), - radius: z.optional(z.number()) + radius: z.number().optional() }); /** @@ -437,7 +417,7 @@ export const zModelCircle = z.object({ */ export const zModelSquare = z.object({ kind: z.string(), - sideLength: z.optional(z.number()) + sideLength: z.number().optional() }); /** @@ -456,35 +436,35 @@ export const zCompositionWithOneOfDiscriminator = z.union([ * This is a model with one property with a 'any of' relationship */ export const zCompositionWithAnyOf = z.object({ - propA: z.optional(z.union([ + propA: z.union([ zModelWithString, zModelWithEnum, zModelWithArray, zModelWithDictionary - ])) + ]).optional() }); /** * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithAnyOfAnonymous = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - propA: z.optional(z.string()) + propA: z.string().optional() }), z.string(), z.int() - ])) + ]).optional() }); /** * This is a model with nested 'any of' property with a type null */ export const zCompositionWithNestedAnyAndTypeNull = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.array(z.union([zModelWithDictionary, z.null()])), z.array(z.union([zModelWithArray, z.null()])) - ])) + ]).optional() }); export const z3eNum1Период = z.enum(['Bird', 'Dog']); @@ -495,90 +475,82 @@ export const zConstValue = z.literal('ConstValue'); * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithNestedAnyOfAndNull = z.object({ - propA: z.optional(z.union([ - z.array(z.union([z3eNum1Период, zConstValue])), - z.null() - ])) + propA: z.array(z.union([z3eNum1Период, zConstValue])).nullish() }); /** * This is a model with one property with a 'one of' relationship */ export const zCompositionWithOneOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - boolean: z.optional(z.boolean()) + boolean: z.boolean().optional() }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ])) + zModelWithDictionary + ]).nullish() }); /** * This is a model that contains a simple dictionary within composition */ export const zCompositionWithOneOfAndSimpleDictionary = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.boolean(), z.record(z.string(), z.number()) - ])) + ]).optional() }); /** * This is a model that contains a dictionary of simple arrays within composition */ export const zCompositionWithOneOfAndSimpleArrayDictionary = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.boolean(), z.record(z.string(), z.array(z.boolean())) - ])) + ]).optional() }); /** * This is a model that contains a dictionary of complex arrays (composited) within composition */ export const zCompositionWithOneOfAndComplexArrayDictionary = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.boolean(), z.record(z.string(), z.array(z.union([z.number(), z.string()]))) - ])) + ]).optional() }); /** * This is a model with one property with a 'all of' relationship */ export const zCompositionWithAllOfAndNullable = z.object({ - propA: z.optional(z.union([ - z.object({ - boolean: z.optional(z.boolean()) - }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary), - z.null() - ])) + propA: z.object({ + boolean: z.boolean().optional() + }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary).nullish() }); /** * This is a model with one property with a 'any of' relationship */ export const zCompositionWithAnyOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - boolean: z.optional(z.boolean()) + boolean: z.boolean().optional() }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ])) + zModelWithDictionary + ]).nullish() }); /** * This is a base model with two simple optional properties */ export const zCompositionBaseModel = z.object({ - firstName: z.optional(z.string()), - lastname: z.optional(z.string()) + firstName: z.string().optional(), + lastname: z.string().optional() }); /** @@ -596,87 +568,75 @@ export const zCompositionExtendedModel = zCompositionBaseModel.and(z.object({ export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.string().readonly(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), - string: z.optional(z.string()), - number: z.optional(z.number()), - boolean: z.optional(z.boolean()), - reference: z.optional(zModelWithString), - 'property with space': z.optional(z.string()), - default: z.optional(z.string()), - try: z.optional(z.string()), - '@namespace.string': z.optional(z.string().readonly()), - '@namespace.integer': z.optional(z.int().readonly()) + requiredAndNullable: z.string().nullable(), + string: z.string().optional(), + number: z.number().optional(), + boolean: z.boolean().optional(), + reference: zModelWithString.optional(), + 'property with space': z.string().optional(), + default: z.string().optional(), + try: z.string().optional(), + '@namespace.string': z.string().readonly().optional(), + '@namespace.integer': z.int().readonly().optional() }); /** * This is a model with one property containing a reference */ export const zModelWithReference = z.object({ - prop: z.optional(zModelWithProperties) + prop: zModelWithProperties.optional() }); /** * This is a model with one nested property */ export const zModelWithNestedProperties = z.object({ - first: z.union([ - z.object({ - second: z.union([ - z.object({ - third: z.union([ - z.string().readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() + first: z.object({ + second: z.object({ + third: z.string().readonly().nullable() + }).readonly().nullable() + }).readonly().nullable() }); /** * This is a model with duplicated properties */ export const zModelWithDuplicateProperties = z.object({ - prop: z.optional(zModelWithString) + prop: zModelWithString.optional() }); /** * This is a model with ordered properties */ export const zModelWithOrderedProperties = z.object({ - zebra: z.optional(z.string()), - apple: z.optional(z.string()), - hawaii: z.optional(z.string()) + zebra: z.string().optional(), + apple: z.string().optional(), + hawaii: z.string().optional() }); /** * This is a model with duplicated imports */ export const zModelWithDuplicateImports = z.object({ - propA: z.optional(zModelWithString), - propB: z.optional(zModelWithString), - propC: z.optional(zModelWithString) + propA: zModelWithString.optional(), + propB: zModelWithString.optional(), + propC: zModelWithString.optional() }); /** * This is a model that extends another model */ export const zModelThatExtends = zModelWithString.and(z.object({ - propExtendsA: z.optional(z.string()), - propExtendsB: z.optional(zModelWithString) + propExtendsA: z.string().optional(), + propExtendsB: zModelWithString.optional() })); /** * This is a model that extends another model */ export const zModelThatExtendsExtends = zModelWithString.and(zModelThatExtends).and(z.object({ - propExtendsC: z.optional(z.string()), - propExtendsD: z.optional(zModelWithString) + propExtendsC: z.string().optional(), + propExtendsD: zModelWithString.optional() })); /** @@ -685,31 +645,31 @@ export const zModelThatExtendsExtends = zModelWithString.and(zModelThatExtends). export const zModelWithPattern = z.object({ key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), name: z.string().max(255), - enabled: z.optional(z.boolean().readonly()), - modified: z.optional(z.iso.datetime().readonly()), - id: z.optional(z.string().regex(/^\d{2}-\d{3}-\d{4}$/)), - text: z.optional(z.string().regex(/^\w+$/)), - patternWithSingleQuotes: z.optional(z.string().regex(/^[a-zA-Z0-9']*$/)), - patternWithNewline: z.optional(z.string().regex(/aaa\nbbb/)), - patternWithBacktick: z.optional(z.string().regex(/aaa`bbb/)) + enabled: z.boolean().readonly().optional(), + modified: z.iso.datetime().readonly().optional(), + id: z.string().regex(/^\d{2}-\d{3}-\d{4}$/).optional(), + text: z.string().regex(/^\w+$/).optional(), + patternWithSingleQuotes: z.string().regex(/^[a-zA-Z0-9']*$/).optional(), + patternWithNewline: z.string().regex(/aaa\nbbb/).optional(), + patternWithBacktick: z.string().regex(/aaa`bbb/).optional() }); export const zFile = z.object({ - id: z.optional(z.string().min(1).readonly()), - updated_at: z.optional(z.iso.datetime().readonly()), - created_at: z.optional(z.iso.datetime().readonly()), + id: z.string().min(1).readonly().optional(), + updated_at: z.iso.datetime().readonly().optional(), + created_at: z.iso.datetime().readonly().optional(), mime: z.string().min(1).max(24), - file: z.optional(z.url().readonly()) + file: z.url().readonly().optional() }); export const zDefault = z.object({ - name: z.optional(z.string()) + name: z.string().optional() }); export const zPageable = z.object({ - page: z.optional(z.int().gte(0).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })).default(0), - size: z.optional(z.int().gte(1).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })), - sort: z.optional(z.array(z.string())) + page: z.int().gte(0).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional().default(0), + size: z.int().gte(1).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional(), + sort: z.array(z.string()).optional() }); /** @@ -728,35 +688,29 @@ export const zFreeFormObjectWithAdditionalPropertiesEqTrue = z.record(z.string() export const zFreeFormObjectWithAdditionalPropertiesEqEmptyObject = z.record(z.string(), z.unknown()); export const zModelWithConst = z.object({ - String: z.optional(z.literal('String')), - number: z.optional(z.literal(0)), - null: z.optional(z.null()), - withType: z.optional(z.literal('Some string')) + String: z.literal('String').optional(), + number: z.literal(0).optional(), + null: z.null().optional(), + withType: z.literal('Some string').optional() }); /** * This is a model with one property and additionalProperties: true */ export const zModelWithAdditionalPropertiesEqTrue = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); export const zNestedAnyOfArraysNullable = z.object({ - nullableArray: z.optional(z.union([ - z.array(z.union([z.string(), z.boolean()])), - z.null() - ])) + nullableArray: z.array(z.union([z.string(), z.boolean()])).nullish() }); /** * An object that can be null */ -export const zNullableObject = z.union([ - z.object({ - foo: z.optional(z.string()) - }), - z.null() -]).default(null); +export const zNullableObject = z.object({ + foo: z.string().optional() +}).nullable().default(null); /** * Some % character @@ -764,7 +718,7 @@ export const zNullableObject = z.union([ export const zCharactersInDescription = z.string(); export const zModelWithNullableObject = z.object({ - data: z.optional(zNullableObject) + data: zNullableObject.optional() }); export const zModelWithOneOfEnum = z.union([ @@ -792,17 +746,17 @@ export const zModelWithNestedArrayEnumsDataFoo = z.enum(['foo', 'bar']); export const zModelWithNestedArrayEnumsDataBar = z.enum(['baz', 'qux']); export const zModelWithNestedArrayEnumsData = z.object({ - foo: z.optional(z.array(zModelWithNestedArrayEnumsDataFoo)), - bar: z.optional(z.array(zModelWithNestedArrayEnumsDataBar)) + foo: z.array(zModelWithNestedArrayEnumsDataFoo).optional(), + bar: z.array(zModelWithNestedArrayEnumsDataBar).optional() }); export const zModelWithNestedArrayEnums = z.object({ - array_strings: z.optional(z.array(z.string())), - data: z.optional(zModelWithNestedArrayEnumsData) + array_strings: z.array(z.string()).optional(), + data: zModelWithNestedArrayEnumsData.optional() }); export const zModelWithNestedCompositionEnums = z.object({ - foo: z.optional(zModelWithNestedArrayEnumsDataFoo) + foo: zModelWithNestedArrayEnumsDataFoo.optional() }); export const zModelWithReadOnlyAndWriteOnly = z.object({ @@ -814,9 +768,9 @@ export const zModelWithReadOnlyAndWriteOnly = z.object({ * This is a model with one property containing an array */ export const zModelWithArrayReadOnlyAndWriteOnly = z.object({ - prop: z.optional(z.array(zModelWithReadOnlyAndWriteOnly)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithReadOnlyAndWriteOnly).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); export const zModelWithConstantSizeArray = z.tuple([z.number(), z.number()]); @@ -848,25 +802,22 @@ export const zModelWithPrefixItemsConstantSizeArray = z.tuple([ export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([ z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]) + ]).nullable() ]); export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([z.intersection(z.number(), z.string()), z.intersection(z.number(), z.string())]); export const zModelWithNumericEnumUnion = z.object({ - value: z.optional(z.union([ + value: z.union([ z.literal(-10), z.literal(-1), z.literal(0), @@ -874,14 +825,14 @@ export const zModelWithNumericEnumUnion = z.object({ z.literal(3), z.literal(6), z.literal(12) - ])) + ]).optional() }); /** * Some description with `back ticks` */ export const zModelWithBackticksInDescription = z.object({ - template: z.optional(z.string()) + template: z.string().optional() }); /** @@ -923,40 +874,40 @@ export const zModelWithAnyOfConstantSizeArrayWithNSizeAndOptions = z.tuple([z.un ])]); export const zSchemaWithFormRestrictedKeys = z.object({ - description: z.optional(z.string()), - 'x-enum-descriptions': z.optional(z.string()), - 'x-enum-varnames': z.optional(z.string()), - 'x-enumNames': z.optional(z.string()), - title: z.optional(z.string()), - object: z.optional(z.object({ - description: z.optional(z.string()), - 'x-enum-descriptions': z.optional(z.string()), - 'x-enum-varnames': z.optional(z.string()), - 'x-enumNames': z.optional(z.string()), - title: z.optional(z.string()) - })), - array: z.optional(z.array(z.object({ - description: z.optional(z.string()), - 'x-enum-descriptions': z.optional(z.string()), - 'x-enum-varnames': z.optional(z.string()), - 'x-enumNames': z.optional(z.string()), - title: z.optional(z.string()) - }))) + description: z.string().optional(), + 'x-enum-descriptions': z.string().optional(), + 'x-enum-varnames': z.string().optional(), + 'x-enumNames': z.string().optional(), + title: z.string().optional(), + object: z.object({ + description: z.string().optional(), + 'x-enum-descriptions': z.string().optional(), + 'x-enum-varnames': z.string().optional(), + 'x-enumNames': z.string().optional(), + title: z.string().optional() + }).optional(), + array: z.array(z.object({ + description: z.string().optional(), + 'x-enum-descriptions': z.string().optional(), + 'x-enum-varnames': z.string().optional(), + 'x-enumNames': z.string().optional(), + title: z.string().optional() + })).optional() }); /** * This schema was giving PascalCase transformations a hard time */ export const zIoK8sApimachineryPkgApisMetaV1Preconditions = z.object({ - resourceVersion: z.optional(z.string()), - uid: z.optional(z.string()) + resourceVersion: z.string().optional(), + uid: z.string().optional() }); /** * This schema was giving PascalCase transformations a hard time */ export const zIoK8sApimachineryPkgApisMetaV1DeleteOptions = z.object({ - preconditions: z.optional(zIoK8sApimachineryPkgApisMetaV1Preconditions) + preconditions: zIoK8sApimachineryPkgApisMetaV1Preconditions.optional() }); export const zAdditionalPropertiesUnknownIssue = z.record(z.string(), z.union([ @@ -978,25 +929,16 @@ export const zAdditionalPropertiesIntegerIssue = z.object({ }); export const zGenericSchemaDuplicateIssue1SystemBoolean = z.object({ - item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), - hasError: z.optional(z.boolean().readonly()), - data: z.optional(z.record(z.string(), z.never())) + item: z.boolean().optional(), + error: z.string().nullish(), + hasError: z.boolean().readonly().optional(), + data: z.record(z.string(), z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemString = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])), - hasError: z.optional(z.boolean().readonly()) + item: z.string().nullish(), + error: z.string().nullish(), + hasError: z.boolean().readonly().optional() }); export const zOneOfAllOfIssue = z.union([ @@ -1009,7 +951,7 @@ export const zOneOfAllOfIssue = z.union([ export const zExternalSharedExternalSharedModel = z.object({ id: z.string(), - name: z.optional(z.string()) + name: z.string().optional() }); /** @@ -1027,24 +969,21 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), - string: z.optional(z.string()), - number: z.optional(z.number()), - boolean: z.optional(z.boolean()), - reference: z.optional(zModelWithString), - 'property with space': z.optional(z.string()), - default: z.optional(z.string()), - try: z.optional(z.string()) + requiredAndNullable: z.string().nullable(), + string: z.string().optional(), + number: z.number().optional(), + boolean: z.boolean().optional(), + reference: zModelWithString.optional(), + 'property with space': z.string().optional(), + default: z.string().optional(), + try: z.string().optional() }); /** * This is a model with one property containing a reference */ export const zModelWithReferenceWritable = z.object({ - prop: z.optional(zModelWithPropertiesWritable) + prop: zModelWithPropertiesWritable.optional() }); /** @@ -1053,11 +992,11 @@ export const zModelWithReferenceWritable = z.object({ export const zModelWithPatternWritable = z.object({ key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), name: z.string().max(255), - id: z.optional(z.string().regex(/^\d{2}-\d{3}-\d{4}$/)), - text: z.optional(z.string().regex(/^\w+$/)), - patternWithSingleQuotes: z.optional(z.string().regex(/^[a-zA-Z0-9']*$/)), - patternWithNewline: z.optional(z.string().regex(/aaa\nbbb/)), - patternWithBacktick: z.optional(z.string().regex(/aaa`bbb/)) + id: z.string().regex(/^\d{2}-\d{3}-\d{4}$/).optional(), + text: z.string().regex(/^\w+$/).optional(), + patternWithSingleQuotes: z.string().regex(/^[a-zA-Z0-9']*$/).optional(), + patternWithNewline: z.string().regex(/aaa\nbbb/).optional(), + patternWithBacktick: z.string().regex(/aaa`bbb/).optional() }); export const zFileWritable = z.object({ @@ -1073,9 +1012,9 @@ export const zModelWithReadOnlyAndWriteOnlyWritable = z.object({ * This is a model with one property containing an array */ export const zModelWithArrayReadOnlyAndWriteOnlyWritable = z.object({ - prop: z.optional(z.array(zModelWithReadOnlyAndWriteOnlyWritable)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithReadOnlyAndWriteOnlyWritable).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); export const zModelWithAnyOfConstantSizeArrayWithNSizeAndOptionsWritable = z.tuple([z.union([ @@ -1100,23 +1039,14 @@ export const zOneOfAllOfIssueWritable = z.union([ ]); export const zGenericSchemaDuplicateIssue1SystemBooleanWritable = z.object({ - item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), - data: z.optional(z.record(z.string(), z.never())) + item: z.boolean().optional(), + error: z.string().nullish(), + data: z.record(z.string(), z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemStringWritable = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])) + item: z.string().nullish(), + error: z.string().nullish() }); /** @@ -1132,10 +1062,7 @@ export const zCompositionWithOneOfAndProperties = z.intersection(z.union([ bar: zNonAsciiStringæøåÆøÅöôêÊ字符串 }) ]), z.object({ - baz: z.union([ - z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.int().gte(0).max(255, { error: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1143,10 +1070,7 @@ export const zModelWithOneOfAndProperties = z.intersection(z.union([ zSimpleParameter, zNonAsciiStringæøåÆøÅöôêÊ字符串 ]), z.object({ - baz: z.union([ - z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.int().gte(0).max(255, { error: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1166,15 +1090,15 @@ export const zSimpleRequestBody = zModelWithString; export const zSimpleFormData = zModelWithString; export const zExportData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zImportData = z.object({ @@ -1182,8 +1106,8 @@ export const zImportData = z.object({ zModelWithReadOnlyAndWriteOnlyWritable, zModelWithArrayReadOnlyAndWriteOnlyWritable ]), - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); export const zImportResponse = z.union([ @@ -1192,15 +1116,15 @@ export const zImportResponse = z.union([ ]); export const zFooWowData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zApiVVersionODataControllerCountData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -1209,14 +1133,14 @@ export const zApiVVersionODataControllerCountData = z.object({ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ foo_param: z.union([ z.string(), z.uuid() ]) }), - query: z.optional(z.never()) + query: z.never().optional() }); /** @@ -1225,160 +1149,127 @@ export const zGetApiVbyApiVersionSimpleOperationData = z.object({ export const zGetApiVbyApiVersionSimpleOperationResponse = z.number(); export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDeleteFooData3 = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ foo_param: z.string(), BarParam: z.string() }), - query: z.optional(z.never()), + query: z.never().optional(), headers: z.object({ 'x-Foo-Bar': zModelWithString }) }); export const zCallWithDescriptionsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterWithBreaks: z.optional(z.string()), - parameterWithBackticks: z.optional(z.string()), - parameterWithSlashes: z.optional(z.string()), - parameterWithExpressionPlaceholders: z.optional(z.string()), - parameterWithQuotes: z.optional(z.string()), - parameterWithReservedCharacters: z.optional(z.string()) - })) + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterWithBreaks: z.string().optional(), + parameterWithBackticks: z.string().optional(), + parameterWithSlashes: z.string().optional(), + parameterWithExpressionPlaceholders: z.string().optional(), + parameterWithQuotes: z.string().optional(), + parameterWithReservedCharacters: z.string().optional() + }).optional() }); export const zDeprecatedCallData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional(), headers: z.object({ - parameter: z.union([ - zDeprecatedModel, - z.null() - ]) + parameter: zDeprecatedModel.nullable() }) }); export const zCallWithParametersData = z.object({ - body: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + body: z.record(z.string(), z.unknown()).nullable(), path: z.object({ - parameterPath: z.union([ - z.string(), - z.null() - ]), - 'api-version': z.union([ - z.string(), - z.null() - ]) + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }), query: z.object({ - foo_ref_enum: z.optional(zModelWithNestedArrayEnumsDataFoo), + foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.union([ - z.string(), - z.null() - ]) + cursor: z.string().nullable() }), headers: z.object({ - parameterHeader: z.union([ - z.string(), - z.null() - ]) + parameterHeader: z.string().nullable() }) }); export const zCallWithWeirdParameterNamesData = z.object({ - body: z.union([ - zModelWithString, - z.null() - ]), + body: zModelWithString.nullable(), path: z.object({ - 'parameter.path.1': z.optional(z.string()), - 'parameter-path-2': z.optional(z.string()), - 'PARAMETER-PATH-3': z.optional(z.string()), - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string().nullable() }), query: z.object({ - default: z.optional(z.string()), - 'parameter-query': z.union([ - z.string(), - z.null() - ]) + default: z.string().optional(), + 'parameter-query': z.string().nullable() }), headers: z.object({ - 'parameter.header': z.union([ - z.string(), - z.null() - ]) + 'parameter.header': z.string().nullable() }) }); export const zGetCallWithOptionalParamData = z.object({ body: zModelWithOneOfEnum, - path: z.optional(z.never()), - query: z.optional(z.object({ - page: z.optional(z.number()) - })) + path: z.never().optional(), + query: z.object({ + page: z.number().optional() + }).optional() }); export const zPostCallWithOptionalParamData = z.object({ - body: z.optional(z.object({ - offset: z.optional(z.union([ - z.number(), - z.null() - ])) - })), - path: z.optional(z.never()), + body: z.object({ + offset: z.number().nullish() + }).optional(), + path: z.never().optional(), query: z.object({ parameter: zPageable }) @@ -1390,114 +1281,96 @@ export const zPostCallWithOptionalParamResponse = z.union([ ]); export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: z.optional(zSimpleRequestBody), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) + body: zSimpleRequestBody.optional(), + path: z.never().optional(), + query: z.object({ + parameter: z.string().optional() + }).optional() }); export const zPostApiVbyApiVersionFormDataData = z.object({ - body: z.optional(zSimpleFormData), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) + body: zSimpleFormData.optional(), + path: z.never().optional(), + query: z.object({ + parameter: z.string().optional() + }).optional() }); export const zCallWithDefaultParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z.optional(z.union([ - z.string().default('Hello World!'), - z.null() - ])).default('Hello World!'), - parameterNumber: z.optional(z.union([ - z.number().default(123), - z.null() - ])).default(123), - parameterBoolean: z.optional(z.union([ - z.boolean().default(true), - z.null() - ])).default(true), - parameterEnum: z.optional(z.enum([ + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterString: z.string().nullish().default('Hello World!'), + parameterNumber: z.number().nullish().default(123), + parameterBoolean: z.boolean().nullish().default(true), + parameterEnum: z.enum([ 'Success', 'Warning', 'Error' - ])), - parameterModel: z.optional(z.union([ - zModelWithString.default({ prop: 'Hello World!' }), - z.null() - ])) - })) + ]).optional(), + parameterModel: zModelWithString.nullish() + }).optional() }); export const zCallWithDefaultOptionalParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z.optional(z.string()).default('Hello World!'), - parameterNumber: z.optional(z.number()).default(123), - parameterBoolean: z.optional(z.boolean()).default(true), - parameterEnum: z.optional(z.enum([ + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterString: z.string().optional().default('Hello World!'), + parameterNumber: z.number().optional().default(123), + parameterBoolean: z.boolean().optional().default(true), + parameterEnum: z.enum([ 'Success', 'Warning', 'Error' - ])), - parameterModel: z.optional(zModelWithString).default({ prop: 'Hello World!' }) - })) + ]).optional(), + parameterModel: zModelWithString.optional().default({ prop: 'Hello World!' }) + }).optional() }); export const zCallToTestOrderOfParamsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ - parameterOptionalStringWithDefault: z.optional(z.string()).default('Hello World!'), - parameterOptionalStringWithEmptyDefault: z.optional(z.string()).default(''), - parameterOptionalStringWithNoDefault: z.optional(z.string()), + parameterOptionalStringWithDefault: z.string().optional().default('Hello World!'), + parameterOptionalStringWithEmptyDefault: z.string().optional().default(''), + parameterOptionalStringWithNoDefault: z.string().optional(), parameterStringWithDefault: z.string().default('Hello World!'), parameterStringWithEmptyDefault: z.string().default(''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.optional(z.union([ - z.string(), - z.null() - ])), - parameterStringNullableWithDefault: z.optional(z.union([ - z.string(), - z.null() - ])).default(null) + parameterStringNullableWithNoDefault: z.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }) }); export const zDuplicateNameData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName2Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName3Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName4Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -1506,9 +1379,9 @@ export const zCallWithNoContentResponseData = z.object({ export const zCallWithNoContentResponseResponse = z.void(); export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseAndNoContentResponseResponse = z.union([ @@ -1517,17 +1390,17 @@ export const zCallWithResponseAndNoContentResponseResponse = z.union([ ]); export const zDummyAData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDummyAResponse = z400; export const zDummyBData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -1536,17 +1409,17 @@ export const zDummyBData = z.object({ export const zDummyBResponse = z.void(); export const zCallWithResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseResponse = zImport; export const zCallWithDuplicateResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithDuplicateResponsesResponse = z.union([ @@ -1555,81 +1428,50 @@ export const zCallWithDuplicateResponsesResponse = z.union([ ]); export const zCallWithResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponsesResponse = z.union([ z.object({ - '@namespace.string': z.optional(z.string().readonly()), - '@namespace.integer': z.optional(z.int().readonly()), - value: z.optional(z.array(zModelWithString).readonly()) + '@namespace.string': z.string().readonly().optional(), + '@namespace.integer': z.int().readonly().optional(), + value: z.array(zModelWithString).readonly().optional() }), zModelThatExtends, zModelThatExtendsExtends ]); export const zCollectionFormatData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ - parameterArrayCSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArraySSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayTSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayPipes: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayMulti: z.union([ - z.array(z.string()), - z.null() - ]) + parameterArrayCSV: z.array(z.string()).nullable(), + parameterArraySSV: z.array(z.string()).nullable(), + parameterArrayTSV: z.array(z.string()).nullable(), + parameterArrayPipes: z.array(z.string()).nullable(), + parameterArrayMulti: z.array(z.string()).nullable() }) }); export const zTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.object({ - id: z.optional(z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })) - })), + body: z.never().optional(), + path: z.object({ + id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional() + }).optional(), query: z.object({ parameterNumber: z.number().default(123), - parameterString: z.union([ - z.string().default('default'), - z.null() - ]).default('default'), - parameterBoolean: z.union([ - z.boolean().default(true), - z.null() - ]).default(true), - parameterObject: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]).default(null), - parameterArray: z.union([ - z.array(z.string()), - z.null() - ]), - parameterDictionary: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + parameterString: z.string().nullable().default('default'), + parameterBoolean: z.boolean().nullable().default(true), + parameterObject: z.record(z.string(), z.unknown()).nullable().default(null), + parameterArray: z.array(z.string()).nullable(), + parameterDictionary: z.record(z.string(), z.unknown()).nullable(), parameterEnum: z.union([ z.literal('Success'), z.literal('Warning'), - z.literal('Error'), - z.null() - ]) + z.literal('Error') + ]).nullable() }) }); @@ -1643,23 +1485,20 @@ export const zTypesResponse = z.union([ export const zUploadFileData = z.object({ body: z.string(), path: z.object({ - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.string().nullable() }), - query: z.optional(z.never()) + query: z.never().optional() }); export const zUploadFileResponse = z.boolean(); export const zFileResponseData = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ id: z.string(), 'api-version': z.string() }), - query: z.optional(z.never()) + query: z.never().optional() }); /** @@ -1668,15 +1507,15 @@ export const zFileResponseData = z.object({ export const zFileResponseResponse = z.string(); export const zComplexTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ parameterObject: z.object({ - first: z.optional(z.object({ - second: z.optional(z.object({ - third: z.optional(z.string()) - })) - })) + first: z.object({ + second: z.object({ + third: z.string().optional() + }).optional() + }).optional() }), parameterReference: zModelWithString }) @@ -1688,77 +1527,59 @@ export const zComplexTypesData = z.object({ export const zComplexTypesResponse = z.array(zModelWithString); export const zMultipartResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** * OK */ export const zMultipartResponseResponse = z.object({ - file: z.optional(z.string()), - metadata: z.optional(z.object({ - foo: z.optional(z.string()), - bar: z.optional(z.string()) - })) + file: z.string().optional(), + metadata: z.object({ + foo: z.string().optional(), + bar: z.string().optional() + }).optional() }); export const zMultipartRequestData = z.object({ - body: z.optional(z.object({ - content: z.optional(z.string()), - data: z.optional(z.union([ - zModelWithString, - z.null() - ])) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.object({ + content: z.string().optional(), + data: zModelWithString.nullish() + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zComplexParamsData = z.object({ - body: z.optional(z.object({ - key: z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly(), - z.null() - ]).readonly(), - name: z.union([ - z.string().max(255), - z.null() - ]), - enabled: z.optional(z.boolean()).default(true), + body: z.object({ + key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly().nullable(), + name: z.string().max(255).nullable(), + enabled: z.boolean().optional().default(true), type: z.enum([ 'Monkey', 'Horse', 'Bird' ]), - listOfModels: z.optional(z.union([ - z.array(zModelWithString), - z.null() - ])), - listOfStrings: z.optional(z.union([ - z.array(z.string()), - z.null() - ])), + listOfModels: z.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), parameters: z.union([ zModelWithString, zModelWithEnum, zModelWithArray, zModelWithDictionary ]), - user: z.optional(z.object({ - id: z.optional(z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).readonly()), - name: z.optional(z.union([ - z.string().readonly(), - z.null() - ]).readonly()) - }).readonly()) - })), + user: z.object({ + id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).readonly().optional(), + name: z.string().readonly().nullish() + }).readonly().optional() + }).optional(), path: z.object({ id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }), 'api-version': z.string() }), - query: z.optional(z.never()) + query: z.never().optional() }); /** @@ -1767,22 +1588,22 @@ export const zComplexParamsData = z.object({ export const zComplexParamsResponse = zModelWithString; export const zCallWithResultFromHeaderData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zTestErrorCodeData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ status: z.int() }) }); export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ nonAsciiParamæøåÆØÅöôêÊ: z.int() }) @@ -1795,6 +1616,6 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiS export const zPutWithFormUrlEncodedData = z.object({ body: zArrayWithStrings, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/enum-null/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/enum-null/zod.gen.ts index d75ecfc9c..60e4c5a54 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/enum-null/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/enum-null/zod.gen.ts @@ -2,7 +2,7 @@ import * as z from 'zod/v4'; -export const zFoo = z.nullable(z.enum(['foo', 'bar'])); +export const zFoo = z.enum(['foo', 'bar']).nullable(); export const zBar = z.enum(['foo', 'bar']); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/enum-resolver-permissive/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/enum-resolver-permissive/zod.gen.ts index f71dd3169..d5f405a0e 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/enum-resolver-permissive/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/enum-resolver-permissive/zod.gen.ts @@ -2,7 +2,7 @@ import * as z from 'zod/v4'; -export const zFoo = z.union([z.enum(['foo', 'bar']), z.string()]); +export const zFoo = z.union([z.enum(['foo', 'bar']), z.string()]).nullable(); export const zBar = z.union([z.enum(['foo', 'bar']), z.string()]); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts index e4eb78007..3f4e8d91b 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts @@ -3,35 +3,35 @@ import * as z from 'zod/v4'; export const zFoo = z.object({ - foo: z.optional(z.literal('foo')), - bar: z.optional(z.literal(3.2)), - baz: z.optional(z.literal(-1)), - qux: z.optional(z.literal(true)), - quux: z.optional(z.tuple([ + foo: z.literal('foo').optional(), + bar: z.literal(3.2).optional(), + baz: z.literal(-1).optional(), + qux: z.literal(true).optional(), + quux: z.tuple([ z.literal(1), z.literal(2), z.literal(3), z.literal('foo'), z.literal(true) - ])), - corge: z.optional(z.record(z.string(), z.unknown())), - garply: z.optional(z.literal(BigInt('10'))), - numberInt8: z.optional(z.literal(100)), - numberInt16: z.optional(z.literal(1000)), - numberInt32: z.optional(z.literal(100000)), - numberInt64: z.optional(z.literal(BigInt(1000000000000))), - numberUint8: z.optional(z.literal(200)), - numberUint16: z.optional(z.literal(50000)), - numberUint32: z.optional(z.literal(3000000000)), - numberUint64: z.optional(z.literal(BigInt(18000000000000000000))), - integerInt8: z.optional(z.literal(-100)), - integerInt16: z.optional(z.literal(-1000)), - integerInt32: z.optional(z.literal(-100000)), - integerInt64: z.optional(z.literal(BigInt(-1000000000000))), - integerUint8: z.optional(z.literal(255)), - integerUint16: z.optional(z.literal(65535)), - integerUint32: z.optional(z.literal(4294967295)), - integerUint64: z.optional(z.literal(BigInt('18446744073709551615'))), - stringInt64: z.optional(z.literal(BigInt('-9223372036854775808'))), - stringUint64: z.optional(z.literal(BigInt('18446744073709551615'))) + ]).optional(), + corge: z.record(z.string(), z.unknown()).optional(), + garply: z.literal(BigInt('10')).optional(), + numberInt8: z.literal(100).optional(), + numberInt16: z.literal(1000).optional(), + numberInt32: z.literal(100000).optional(), + numberInt64: z.literal(BigInt(1000000000000)).optional(), + numberUint8: z.literal(200).optional(), + numberUint16: z.literal(50000).optional(), + numberUint32: z.literal(3000000000).optional(), + numberUint64: z.literal(BigInt(18000000000000000000)).optional(), + integerInt8: z.literal(-100).optional(), + integerInt16: z.literal(-1000).optional(), + integerInt32: z.literal(-100000).optional(), + integerInt64: z.literal(BigInt(-1000000000000)).optional(), + integerUint8: z.literal(255).optional(), + integerUint16: z.literal(65535).optional(), + integerUint32: z.literal(4294967295).optional(), + integerUint64: z.literal(BigInt('18446744073709551615')).optional(), + stringInt64: z.literal(BigInt('-9223372036854775808')).optional(), + stringUint64: z.literal(BigInt('18446744073709551615')).optional() }); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/type-format-zod/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/type-format-zod/zod.gen.ts index 796146a69..9b6647e58 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/type-format-zod/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/type-format-zod/zod.gen.ts @@ -3,7 +3,7 @@ import * as z from 'zod/v4'; export const zFoo = z.object({ - bar: z.optional(z.int()), + bar: z.int().optional(), foo: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).default(BigInt(0)), id: z.string() }); @@ -13,9 +13,9 @@ export const zBar = z.object({ }); export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-bigint-min-max/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-bigint-min-max/zod.gen.ts index da0f87120..b87ef9569 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-bigint-min-max/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-bigint-min-max/zod.gen.ts @@ -3,5 +3,5 @@ import * as z from 'zod/v4'; export const zFoo = z.object({ - foo: z.optional(z.coerce.bigint().gte(BigInt(0)).lte(BigInt(100))) + foo: z.coerce.bigint().gte(BigInt(0)).lte(BigInt(100)).optional() }); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-circular-ref-2/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-circular-ref-2/zod.gen.ts index 9994ed379..19e8bf98d 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-circular-ref-2/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-circular-ref-2/zod.gen.ts @@ -3,10 +3,7 @@ import * as z from 'zod/v4'; export const zBar = z.object({ - bar: z.union([ - z.array(z.lazy((): any => zBar)), - z.null() - ]) + bar: z.array(z.lazy((): any => zBar)).nullable() }); export const zFoo = z.object({ diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-circular-ref/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-circular-ref/zod.gen.ts index 5aa01a341..a7eb7ba7b 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-circular-ref/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-circular-ref/zod.gen.ts @@ -3,13 +3,11 @@ import * as z from 'zod/v4'; export const zBar = z.object({ - get bar() { - return z.optional(z.array(z.lazy((): any => zBar))); - } + bar: z.array(z.lazy((): any => zBar)).optional() }); export const zFoo = z.object({ - foo: z.optional(zBar) + foo: zBar.optional() }); export const zBaz = z.lazy((): any => zQux); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-dates/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-dates/zod.gen.ts index 71ced48b6..400ed387a 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-dates/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-dates/zod.gen.ts @@ -5,31 +5,24 @@ import * as z from 'zod/v4'; export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz'); export const zQux = z.record(z.string(), z.object({ - qux: z.optional(z.string()) + qux: z.string().optional() })); /** * This is Foo schema. */ -export const zFoo = z.union([ - z.object({ - foo: z.optional(z.string().regex(/^\d{3}-\d{2}-\d{4}$/)), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z.optional(z.int().gt(0)).default(0) - }), - z.null() -]).default(null); +export const zFoo = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy((): any => zBar).optional(), + baz: z.array(z.lazy((): any => zFoo)).optional(), + qux: z.int().gt(0).optional().default(0) +}).nullable().default(null); /** * This is Bar schema. */ export const zBar = z.object({ - foo: z.optional(zFoo) + foo: zFoo.optional() }); /** @@ -38,27 +31,27 @@ export const zBar = z.object({ export const zFoo2 = z.string(); export const zFoo3 = z.object({ - foo: z.optional(zBar) + foo: zBar.optional() }); export const zPatchFooData = z.object({ body: z.object({ - foo: z.optional(z.string()) + foo: z.string().optional() }), - path: z.optional(z.never()), - query: z.optional(z.object({ - foo: z.optional(z.string()), - bar: z.optional(zBar), - baz: z.optional(z.object({ - baz: z.optional(z.string()) - })), - qux: z.optional(z.iso.date()), - quux: z.optional(z.iso.datetime({ offset: true })) - })) + path: z.never().optional(), + query: z.object({ + foo: z.string().optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.iso.date().optional(), + quux: z.iso.datetime({ offset: true }).optional() + }).optional() }); export const zPostFooData = z.object({ body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-metadata/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-metadata/zod.gen.ts index cccb35d6d..8adbe94ba 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-metadata/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-metadata/zod.gen.ts @@ -5,37 +5,30 @@ import * as z from 'zod/v4'; export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz'); export const zQux = z.record(z.string(), z.object({ - qux: z.optional(z.string()) + qux: z.string().optional() })); /** * This is Foo schema. */ -export const zFoo = z.union([ - z.object({ - foo: z.optional(z.string().regex(/^\d{3}-\d{2}-\d{4}$/).register(z.globalRegistry, { - description: 'This is foo property.' - })), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo)).register(z.globalRegistry, { - description: 'This is baz property.' - })); - }, - qux: z.optional(z.int().gt(0).register(z.globalRegistry, { - description: 'This is qux property.' - })).default(0) - }), - z.null() -]).default(null); +export const zFoo = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).register(z.globalRegistry, { + description: 'This is foo property.' + }).optional(), + bar: z.lazy((): any => zBar).optional(), + baz: z.array(z.lazy((): any => zFoo)).register(z.globalRegistry, { + description: 'This is baz property.' + }).optional(), + qux: z.int().gt(0).register(z.globalRegistry, { + description: 'This is qux property.' + }).optional().default(0) +}).nullable().default(null); /** * This is Bar schema. */ export const zBar = z.object({ - foo: z.optional(zFoo) + foo: zFoo.optional() }).register(z.globalRegistry, { description: 'This is Bar schema.' }); @@ -48,29 +41,29 @@ export const zFoo2 = z.string().register(z.globalRegistry, { }); export const zFoo3 = z.object({ - foo: z.optional(zBar) + foo: zBar.optional() }); export const zPatchFooData = z.object({ body: z.object({ - foo: z.optional(z.string()) + foo: z.string().optional() }), - path: z.optional(z.never()), - query: z.optional(z.object({ - foo: z.optional(z.string().register(z.globalRegistry, { + path: z.never().optional(), + query: z.object({ + foo: z.string().register(z.globalRegistry, { description: 'This is Foo parameter.' - })), - bar: z.optional(zBar), - baz: z.optional(z.object({ - baz: z.optional(z.string()) - })), - qux: z.optional(z.iso.date()), - quux: z.optional(z.iso.datetime()) - })) + }).optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.iso.date().optional(), + quux: z.iso.datetime().optional() + }).optional() }); export const zPostFooData = z.object({ body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-types/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-types/zod.gen.ts index 267a75881..2fcda22b9 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-types/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-types/zod.gen.ts @@ -7,7 +7,7 @@ export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz'); export type BazZodType = z.infer; export const zQux = z.record(z.string(), z.object({ - qux: z.optional(z.string()) + qux: z.string().optional() })); export type QuxZodType = z.infer; @@ -15,19 +15,12 @@ export type QuxZodType = z.infer; /** * This is Foo schema. */ -export const zFoo = z.union([ - z.object({ - foo: z.optional(z.string().regex(/^\d{3}-\d{2}-\d{4}$/)), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z.optional(z.int().gt(0)).default(0) - }), - z.null() -]).default(null); +export const zFoo = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy((): any => zBar).optional(), + baz: z.array(z.lazy((): any => zFoo)).optional(), + qux: z.int().gt(0).optional().default(0) +}).nullable().default(null); export type FooZodType = z.infer; @@ -35,7 +28,7 @@ export type FooZodType = z.infer; * This is Bar schema. */ export const zBar = z.object({ - foo: z.optional(zFoo) + foo: zFoo.optional() }); export type BarZodType = z.infer; @@ -48,33 +41,33 @@ export const zFoo2 = z.string(); export type FooZodType2 = z.infer; export const zFoo3 = z.object({ - foo: z.optional(zBar) + foo: zBar.optional() }); export type FooZodType3 = z.infer; export const zPatchFooData = z.object({ body: z.object({ - foo: z.optional(z.string()) + foo: z.string().optional() }), - path: z.optional(z.never()), - query: z.optional(z.object({ - foo: z.optional(z.string()), - bar: z.optional(zBar), - baz: z.optional(z.object({ - baz: z.optional(z.string()) - })), - qux: z.optional(z.iso.date()), - quux: z.optional(z.iso.datetime()) - })) + path: z.never().optional(), + query: z.object({ + foo: z.string().optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.iso.date().optional(), + quux: z.iso.datetime().optional() + }).optional() }); export type PatchFooDataZodType = z.infer; export const zPostFooData = z.object({ body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); export type PostFooDataZodType = z.infer; diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-union-merge/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-union-merge/zod.gen.ts index d5b3d03c2..2358fb8df 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-union-merge/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators-union-merge/zod.gen.ts @@ -32,7 +32,7 @@ export const zCatDetails = z.object({ export const zPetStore = z.object({ animals: z.array(z.object({ name: z.string(), - type: z.optional(z.enum(['dog', 'cat'])), + type: z.enum(['dog', 'cat']).optional(), details: z.union([ zDogDetails, zCatDetails diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators/zod.gen.ts index fa38d9c13..d6b4bb64a 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/validators/zod.gen.ts @@ -5,31 +5,24 @@ import * as z from 'zod/v4'; export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz'); export const zQux = z.record(z.string(), z.object({ - qux: z.optional(z.string()) + qux: z.string().optional() })); /** * This is Foo schema. */ -export const zFoo = z.union([ - z.object({ - foo: z.optional(z.string().regex(/^\d{3}-\d{2}-\d{4}$/)), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z.optional(z.int().gt(0)).default(0) - }), - z.null() -]).default(null); +export const zFoo = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy((): any => zBar).optional(), + baz: z.array(z.lazy((): any => zFoo)).optional(), + qux: z.int().gt(0).optional().default(0) +}).nullable().default(null); /** * This is Bar schema. */ export const zBar = z.object({ - foo: z.optional(zFoo) + foo: zFoo.optional() }); /** @@ -38,27 +31,27 @@ export const zBar = z.object({ export const zFoo2 = z.string(); export const zFoo3 = z.object({ - foo: z.optional(zBar) + foo: zBar.optional() }); export const zPatchFooData = z.object({ body: z.object({ - foo: z.optional(z.string()) + foo: z.string().optional() }), - path: z.optional(z.never()), - query: z.optional(z.object({ - foo: z.optional(z.string()), - bar: z.optional(zBar), - baz: z.optional(z.object({ - baz: z.optional(z.string()) - })), - qux: z.optional(z.iso.date()), - quux: z.optional(z.iso.datetime()) - })) + path: z.never().optional(), + query: z.object({ + foo: z.string().optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.iso.date().optional(), + quux: z.iso.datetime().optional() + }).optional() }); export const zPostFooData = z.object({ body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/default/zod.gen.ts index 635fd26df..4e30c7716 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/default/zod.gen.ts @@ -217,14 +217,8 @@ export const zModelWithStringError = z.object({ * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp: z.union([ - z.string(), - z.null() - ]) + nullableProp: z.nullish(z.string()), + nullableRequiredProp: z.nullable(z.string()) }); /** @@ -293,9 +287,7 @@ export const zModelWithDictionary = z.object({ * This is a model with one property containing a circular reference */ export const zModelWithCircularReference = z.object({ - get prop() { - return z.optional(z.lazy((): any => zModelWithCircularReference)); - } + prop: z.optional(z.lazy((): any => zModelWithCircularReference)) }); /** @@ -605,14 +597,8 @@ export const zCallToTestOrderOfParamsData = z.object({ parameterStringWithDefault: z._default(z.string(), 'Hello World!'), parameterStringWithEmptyDefault: z._default(z.string(), ''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.optional(z.union([ - z.string(), - z.null() - ])), - parameterStringNullableWithDefault: z._default(z.optional(z.union([ - z.string(), - z.null() - ])), null) + parameterStringNullableWithNoDefault: z.nullish(z.string()), + parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) }) }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/default/zod.gen.ts index 1d61a080e..75e09687d 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/default/zod.gen.ts @@ -217,14 +217,8 @@ export const zModelWithStringError = z.object({ * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp: z.union([ - z.string(), - z.null() - ]).optional(), - nullableRequiredProp: z.union([ - z.string(), - z.null() - ]) + nullableProp: z.string().nullish(), + nullableRequiredProp: z.string().nullable() }); /** @@ -603,14 +597,8 @@ export const zCallToTestOrderOfParamsData = z.object({ parameterStringWithDefault: z.string().default('Hello World!'), parameterStringWithEmptyDefault: z.string().default(''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.union([ - z.string(), - z.null() - ]).optional(), - parameterStringNullableWithDefault: z.union([ - z.string(), - z.null() - ]).optional().default(null) + parameterStringNullableWithNoDefault: z.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }) }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/array-items-all-of/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/array-items-all-of/zod.gen.ts index 5a58c7fcc..37fd72b6a 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/array-items-all-of/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/array-items-all-of/zod.gen.ts @@ -3,18 +3,18 @@ import * as z from 'zod'; export const zArrayWithAllOfObjects = z.array(z.object({ - id: z.optional(z.int()) + id: z.int().optional() }).and(z.object({ - name: z.optional(z.string()) + name: z.string().optional() }))); export const zArrayWithAllOfPrimitives = z.array(z.intersection(z.number(), z.string())); export const zBaseModel = z.object({ - id: z.optional(z.int()), - createdAt: z.optional(z.iso.datetime()) + id: z.int().optional(), + createdAt: z.iso.datetime().optional() }); export const zArrayWithAllOfRefs = z.array(zBaseModel.and(z.object({ - extra: z.optional(z.string()) + extra: z.string().optional() }))); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/default/zod.gen.ts index 4bb0f5e24..70c6dd200 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/default/zod.gen.ts @@ -136,8 +136,8 @@ export const zArrayWithStrings = z.array(z.string()); * This is a simple array with properties */ export const zArrayWithProperties = z.array(z.object({ - foo: z.optional(z.string()), - bar: z.optional(z.string()) + foo: z.string().optional(), + bar: z.string().optional() })); /** @@ -154,8 +154,8 @@ export const zDictionaryWithDictionary = z.record(z.string(), z.record(z.string( * This is a complex dictionary */ export const zDictionaryWithProperties = z.record(z.string(), z.object({ - foo: z.optional(z.string()), - bar: z.optional(z.string()) + foo: z.string().optional(), + bar: z.string().optional() })); /** @@ -167,21 +167,21 @@ export const zDate = z.string(); * This is a model with one number property */ export const zModelWithInteger = z.object({ - prop: z.optional(z.int()) + prop: z.int().optional() }); /** * This is a model with one boolean property */ export const zModelWithBoolean = z.object({ - prop: z.optional(z.boolean()) + prop: z.boolean().optional() }); /** * This is a model with one string property */ export const zModelWithString = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); export const zSimpleReference = zModelWithString; @@ -210,92 +210,84 @@ export const zDictionaryWithArray = z.record(z.string(), z.array(zModelWithStrin * This is a model with one string property */ export const zModelWithStringError = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp: z.union([ - z.string(), - z.null() - ]) + nullableProp: z.string().nullish(), + nullableRequiredProp: z.string().nullable() }); /** * This is a model with one enum */ export const zModelWithEnum = z.object({ - test: z.optional(z.enum([ + test: z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])), - statusCode: z.optional(z.enum([ + ]).optional(), + statusCode: z.enum([ '100', '200 FOO', '300 FOO_BAR', '400 foo-bar', '500 foo.bar', '600 foo&bar' - ])), - bool: z.optional(z.literal(true)) + ]).optional(), + bool: z.literal(true).optional() }); /** * This is a model with one enum */ export const zModelWithEnumFromDescription = z.object({ - test: z.optional(z.int()) + test: z.int().optional() }); /** * This is a model with nested enums */ export const zModelWithNestedEnums = z.object({ - dictionaryWithEnum: z.optional(z.record(z.string(), z.enum([ + dictionaryWithEnum: z.record(z.string(), z.enum([ 'Success', 'Warning', 'Error' - ]))), - dictionaryWithEnumFromDescription: z.optional(z.record(z.string(), z.int())), - arrayWithEnum: z.optional(z.array(z.enum([ + ])).optional(), + dictionaryWithEnumFromDescription: z.record(z.string(), z.int()).optional(), + arrayWithEnum: z.array(z.enum([ 'Success', 'Warning', 'Error' - ]))), - arrayWithDescription: z.optional(z.array(z.int())) + ])).optional(), + arrayWithDescription: z.array(z.int()).optional() }); /** * This is a model with one property containing an array */ export const zModelWithArray = z.object({ - prop: z.optional(z.array(zModelWithString)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithString).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); /** * This is a model with one property containing a dictionary */ export const zModelWithDictionary = z.object({ - prop: z.optional(z.record(z.string(), z.string())) + prop: z.record(z.string(), z.string()).optional() }); /** * This is a model with one property containing a circular reference */ export const zModelWithCircularReference = z.object({ - get prop() { - return z.optional(z.lazy((): any => zModelWithCircularReference)); - } + prop: z.lazy((): any => zModelWithCircularReference).optional() }); /** @@ -304,22 +296,22 @@ export const zModelWithCircularReference = z.object({ export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.string().readonly(), - string: z.optional(z.string()), - number: z.optional(z.number()), - boolean: z.optional(z.boolean()), - reference: z.optional(zModelWithString), - 'property with space': z.optional(z.string()), - default: z.optional(z.string()), - try: z.optional(z.string()), - '@namespace.string': z.optional(z.string().readonly()), - '@namespace.integer': z.optional(z.int().readonly()) + string: z.string().optional(), + number: z.number().optional(), + boolean: z.boolean().optional(), + reference: zModelWithString.optional(), + 'property with space': z.string().optional(), + default: z.string().optional(), + try: z.string().optional(), + '@namespace.string': z.string().readonly().optional(), + '@namespace.integer': z.int().readonly().optional() }); /** * This is a model with one property containing a reference */ export const zModelWithReference = z.object({ - prop: z.optional(zModelWithProperties) + prop: zModelWithProperties.optional() }); /** @@ -337,45 +329,45 @@ export const zModelWithNestedProperties = z.object({ * This is a model with duplicated properties */ export const zModelWithDuplicateProperties = z.object({ - prop: z.optional(zModelWithString) + prop: zModelWithString.optional() }); /** * This is a model with ordered properties */ export const zModelWithOrderedProperties = z.object({ - zebra: z.optional(z.string()), - apple: z.optional(z.string()), - hawaii: z.optional(z.string()) + zebra: z.string().optional(), + apple: z.string().optional(), + hawaii: z.string().optional() }); /** * This is a model with duplicated imports */ export const zModelWithDuplicateImports = z.object({ - propA: z.optional(zModelWithString), - propB: z.optional(zModelWithString), - propC: z.optional(zModelWithString) + propA: zModelWithString.optional(), + propB: zModelWithString.optional(), + propC: zModelWithString.optional() }); /** * This is a model that extends another model */ export const zModelThatExtends = zModelWithString.and(z.object({ - propExtendsA: z.optional(z.string()), - propExtendsB: z.optional(zModelWithString) + propExtendsA: z.string().optional(), + propExtendsB: zModelWithString.optional() })); /** * This is a model that extends another model */ export const zModelThatExtendsExtends = zModelWithString.and(zModelThatExtends).and(z.object({ - propExtendsC: z.optional(z.string()), - propExtendsD: z.optional(zModelWithString) + propExtendsC: z.string().optional(), + propExtendsD: zModelWithString.optional() })); export const zDefault = z.object({ - name: z.optional(z.string()) + name: z.string().optional() }); /** @@ -384,40 +376,40 @@ export const zDefault = z.object({ export const zModelWithPattern = z.object({ key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), name: z.string().max(255), - enabled: z.optional(z.boolean().readonly()), - modified: z.optional(z.iso.datetime().readonly()), - id: z.optional(z.string().regex(/^\d{2}-\d{3}-\d{4}$/)), - text: z.optional(z.string().regex(/^\w+$/)), - patternWithSingleQuotes: z.optional(z.string().regex(/^[a-zA-Z0-9']*$/)), - patternWithNewline: z.optional(z.string().regex(/aaa\nbbb/)), - patternWithBacktick: z.optional(z.string().regex(/aaa`bbb/)) + enabled: z.boolean().readonly().optional(), + modified: z.iso.datetime().readonly().optional(), + id: z.string().regex(/^\d{2}-\d{3}-\d{4}$/).optional(), + text: z.string().regex(/^\w+$/).optional(), + patternWithSingleQuotes: z.string().regex(/^[a-zA-Z0-9']*$/).optional(), + patternWithNewline: z.string().regex(/aaa\nbbb/).optional(), + patternWithBacktick: z.string().regex(/aaa`bbb/).optional() }); export const zParameterActivityParams = z.object({ - description: z.optional(z.string()), - graduate_id: z.optional(z.int()), - organization_id: z.optional(z.int()), - parent_activity: z.optional(z.int()), - post_id: z.optional(z.int()) + description: z.string().optional(), + graduate_id: z.int().optional(), + organization_id: z.int().optional(), + parent_activity: z.int().optional(), + post_id: z.int().optional() }); export const zResponsePostActivityResponse = z.object({ - description: z.optional(z.string()), - graduate_id: z.optional(z.int()), - organization_id: z.optional(z.int()), - parent_activity_id: z.optional(z.int()), - post_id: z.optional(z.int()) + description: z.string().optional(), + graduate_id: z.int().optional(), + organization_id: z.int().optional(), + parent_activity_id: z.int().optional(), + post_id: z.int().optional() }); export const zFailureFailure = z.object({ - error: z.optional(z.string()), - message: z.optional(z.string()), - reference_code: z.optional(z.string()) + error: z.string().optional(), + message: z.string().optional(), + reference_code: z.string().optional() }); export const zExternalSharedExternalSharedModel = z.object({ id: z.string(), - name: z.optional(z.string()) + name: z.string().optional() }); export const zExternalRefA = zExternalSharedExternalSharedModel; @@ -429,20 +421,20 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - string: z.optional(z.string()), - number: z.optional(z.number()), - boolean: z.optional(z.boolean()), - reference: z.optional(zModelWithString), - 'property with space': z.optional(z.string()), - default: z.optional(z.string()), - try: z.optional(z.string()) + string: z.string().optional(), + number: z.number().optional(), + boolean: z.boolean().optional(), + reference: zModelWithString.optional(), + 'property with space': z.string().optional(), + default: z.string().optional(), + try: z.string().optional() }); /** * This is a model with one property containing a reference */ export const zModelWithReferenceWritable = z.object({ - prop: z.optional(zModelWithPropertiesWritable) + prop: zModelWithPropertiesWritable.optional() }); /** @@ -451,88 +443,88 @@ export const zModelWithReferenceWritable = z.object({ export const zModelWithPatternWritable = z.object({ key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), name: z.string().max(255), - id: z.optional(z.string().regex(/^\d{2}-\d{3}-\d{4}$/)), - text: z.optional(z.string().regex(/^\w+$/)), - patternWithSingleQuotes: z.optional(z.string().regex(/^[a-zA-Z0-9']*$/)), - patternWithNewline: z.optional(z.string().regex(/aaa\nbbb/)), - patternWithBacktick: z.optional(z.string().regex(/aaa`bbb/)) + id: z.string().regex(/^\d{2}-\d{3}-\d{4}$/).optional(), + text: z.string().regex(/^\w+$/).optional(), + patternWithSingleQuotes: z.string().regex(/^[a-zA-Z0-9']*$/).optional(), + patternWithNewline: z.string().regex(/aaa\nbbb/).optional(), + patternWithBacktick: z.string().regex(/aaa`bbb/).optional() }); export const zServiceWithEmptyTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zFooWowData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithDescriptionsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterWithBreaks: z.optional(z.string()), - parameterWithBackticks: z.optional(z.string()), - parameterWithSlashes: z.optional(z.string()), - parameterWithExpressionPlaceholders: z.optional(z.string()), - parameterWithQuotes: z.optional(z.string()), - parameterWithReservedCharacters: z.optional(z.string()) - })) + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterWithBreaks: z.string().optional(), + parameterWithBackticks: z.string().optional(), + parameterWithSlashes: z.string().optional(), + parameterWithExpressionPlaceholders: z.string().optional(), + parameterWithQuotes: z.string().optional(), + parameterWithReservedCharacters: z.string().optional() + }).optional() }); export const zCallWithParametersData = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ parameterPath: z.string(), 'api-version': z.string() @@ -548,13 +540,13 @@ export const zCallWithParametersData = z.object({ export const zCallWithWeirdParameterNamesData = z.object({ body: z.string(), path: z.object({ - 'parameter.path.1': z.optional(z.string()), - 'parameter-path-2': z.optional(z.string()), - 'PARAMETER-PATH-3': z.optional(z.string()), + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), 'api-version': z.string() }), query: z.object({ - default: z.optional(z.string()), + default: z.string().optional(), 'parameter-query': z.string() }), headers: z.object({ @@ -563,8 +555,8 @@ export const zCallWithWeirdParameterNamesData = z.object({ }); export const zCallWithDefaultParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ parameterString: z.string().default('Hello World!'), parameterNumber: z.number().default(123), @@ -575,81 +567,75 @@ export const zCallWithDefaultParametersData = z.object({ 'Error' ]), parameterModel: z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }).default({ prop: 'Hello World!' }) }) }); export const zCallWithDefaultOptionalParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z.optional(z.string()).default('Hello World!'), - parameterNumber: z.optional(z.number()).default(123), - parameterBoolean: z.optional(z.boolean()).default(true), - parameterEnum: z.optional(z.enum([ + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterString: z.string().optional().default('Hello World!'), + parameterNumber: z.number().optional().default(123), + parameterBoolean: z.boolean().optional().default(true), + parameterEnum: z.enum([ 'Success', 'Warning', 'Error' - ])) - })) + ]).optional() + }).optional() }); export const zCallToTestOrderOfParamsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ - parameterOptionalStringWithDefault: z.optional(z.string()).default('Hello World!'), - parameterOptionalStringWithEmptyDefault: z.optional(z.string()).default(''), - parameterOptionalStringWithNoDefault: z.optional(z.string()), + parameterOptionalStringWithDefault: z.string().optional().default('Hello World!'), + parameterOptionalStringWithEmptyDefault: z.string().optional().default(''), + parameterOptionalStringWithNoDefault: z.string().optional(), parameterStringWithDefault: z.string().default('Hello World!'), parameterStringWithEmptyDefault: z.string().default(''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.optional(z.union([ - z.string(), - z.null() - ])), - parameterStringNullableWithDefault: z.optional(z.union([ - z.string(), - z.null() - ])).default(null) + parameterStringNullableWithNoDefault: z.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }) }); export const zDuplicateNameData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName2Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName3Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName4Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseAndNoContentResponseResponse = z.union([ @@ -658,21 +644,21 @@ export const zCallWithResponseAndNoContentResponseResponse = z.union([ ]); export const zDummyAData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDummyBData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -681,9 +667,9 @@ export const zCallWithResponseData = z.object({ export const zCallWithResponseResponse = zModelWithString; export const zCallWithDuplicateResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -692,24 +678,24 @@ export const zCallWithDuplicateResponsesData = z.object({ export const zCallWithDuplicateResponsesResponse = zModelWithString; export const zCallWithResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponsesResponse = z.union([ z.object({ - '@namespace.string': z.optional(z.string().readonly()), - '@namespace.integer': z.optional(z.int().readonly()), - value: z.optional(z.array(zModelWithString).readonly()) + '@namespace.string': z.string().readonly().optional(), + '@namespace.integer': z.int().readonly().optional(), + value: z.array(zModelWithString).readonly().optional() }), zModelThatExtends, zModelThatExtendsExtends ]); export const zCollectionFormatData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ parameterArrayCSV: z.array(z.string()), parameterArraySSV: z.array(z.string()), @@ -720,10 +706,10 @@ export const zCollectionFormatData = z.object({ }); export const zTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.object({ - id: z.optional(z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })) - })), + body: z.never().optional(), + path: z.object({ + id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional() + }).optional(), query: z.object({ parameterNumber: z.number().default(123), parameterString: z.string().default('default'), @@ -746,18 +732,18 @@ export const zTypesResponse = z.union([ ]); export const zComplexTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ parameterObject: z.object({ - first: z.optional(z.object({ - second: z.optional(z.object({ - third: z.optional(z.string()) - })) - })) + first: z.object({ + second: z.object({ + third: z.string().optional() + }).optional() + }).optional() }), parameterReference: z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }) }) }); @@ -768,22 +754,22 @@ export const zComplexTypesData = z.object({ export const zComplexTypesResponse = z.array(zModelWithString); export const zCallWithResultFromHeaderData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zTestErrorCodeData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ status: z.string() }) }); export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ nonAsciiParamæøåÆØÅöôêÊ: z.int() }) @@ -796,8 +782,8 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = zNonAsciiStringæ export const zPostApiVbyApiVersionBodyData = z.object({ body: zParameterActivityParams, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/type-format-zod/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/type-format-zod/zod.gen.ts index b4eb8a8ef..bb1956f79 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/type-format-zod/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/type-format-zod/zod.gen.ts @@ -3,7 +3,7 @@ import * as z from 'zod'; export const zFoo = z.object({ - bar: z.optional(z.int()), + bar: z.int().optional(), foo: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).default(BigInt(0)), id: z.string() }); @@ -13,9 +13,9 @@ export const zBar = z.object({ }); export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/circular/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/circular/zod.gen.ts index 7cced9697..c9bffc923 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/circular/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/circular/zod.gen.ts @@ -3,24 +3,16 @@ import * as z from 'zod/mini'; export const zFoo = z.object({ - get quux() { - return z.optional(z.lazy((): any => zQuux)); - } + quux: z.optional(z.lazy((): any => zQuux)) }); export const zBar = z.object({ - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.lazy((): any => zBaz)); - } + bar: z.optional(z.lazy((): any => zBar)), + baz: z.optional(z.lazy((): any => zBaz)) }); export const zBaz = z.object({ - get quux() { - return z.optional(z.lazy((): any => zQuux)); - } + quux: z.optional(z.lazy((): any => zQuux)) }); export const zQux = z.union([ diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/default/zod.gen.ts index 38d4da2fe..7e22b891c 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/default/zod.gen.ts @@ -81,10 +81,7 @@ export const zSimpleFile = z.string(); /** * This is a simple string */ -export const zSimpleStringWithPattern = z.union([ - z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/)), - z.null() -]); +export const zSimpleStringWithPattern = z.nullable(z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/))); /** * This is a simple enum with strings @@ -279,22 +276,10 @@ export const zModelFromZendesk = z.string(); * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp1: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp1: z.union([ - z.string(), - z.null() - ]), - nullableProp2: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp2: z.union([ - z.string(), - z.null() - ]), + nullableProp1: z.nullish(z.string()), + nullableRequiredProp1: z.nullable(z.string()), + nullableProp2: z.nullish(z.string()), + nullableRequiredProp2: z.nullable(z.string()), 'foo_bar-enum': z.optional(z.enum([ 'Success', 'Warning', @@ -391,9 +376,7 @@ export const zDeprecatedModel = z.object({ * This is a model with one property containing a circular reference */ export const zModelWithCircularReference = z.object({ - get prop() { - return z.optional(z.lazy((): any => zModelWithCircularReference)); - } + prop: z.optional(z.lazy((): any => zModelWithCircularReference)) }); /** @@ -479,14 +462,8 @@ export const zCompositionWithAnyOfAnonymous = z.object({ */ export const zCompositionWithNestedAnyAndTypeNull = z.object({ propA: z.optional(z.union([ - z.array(z.union([ - zModelWithDictionary, - z.null() - ])), - z.array(z.union([ - zModelWithArray, - z.null() - ])) + z.array(z.nullable(zModelWithDictionary)), + z.array(z.nullable(zModelWithArray)) ])) }); @@ -498,24 +475,20 @@ export const zConstValue = z.enum(['ConstValue']); * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithNestedAnyOfAndNull = z.object({ - propA: z.optional(z.union([ - z.array(z.union([z3eNum1Период, zConstValue])), - z.null() - ])) + propA: z.nullish(z.array(z.union([z3eNum1Период, zConstValue]))) }); /** * This is a model with one property with a 'one of' relationship */ export const zCompositionWithOneOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.nullish(z.union([ z.object({ boolean: z.optional(z.boolean()) }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() + zModelWithDictionary ])) }); @@ -553,26 +526,22 @@ export const zCompositionWithOneOfAndComplexArrayDictionary = z.object({ * This is a model with one property with a 'all of' relationship */ export const zCompositionWithAllOfAndNullable = z.object({ - propA: z.optional(z.union([ - z.intersection(z.intersection(z.intersection(z.object({ - boolean: z.optional(z.boolean()) - }), zModelWithEnum), zModelWithArray), zModelWithDictionary), - z.null() - ])) + propA: z.nullish(z.intersection(z.intersection(z.intersection(z.object({ + boolean: z.optional(z.boolean()) + }), zModelWithEnum), zModelWithArray), zModelWithDictionary)) }); /** * This is a model with one property with a 'any of' relationship */ export const zCompositionWithAnyOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.nullish(z.union([ z.object({ boolean: z.optional(z.boolean()) }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() + zModelWithDictionary ])) }); @@ -599,10 +568,7 @@ export const zCompositionExtendedModel = z.intersection(zCompositionBaseModel, z export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.readonly(z.string()), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.nullable(z.string()), string: z.optional(z.string()), number: z.optional(z.number()), boolean: z.optional(z.boolean()), @@ -625,20 +591,11 @@ export const zModelWithReference = z.object({ * This is a model with one nested property */ export const zModelWithNestedProperties = z.object({ - first: z.readonly(z.union([ - z.readonly(z.object({ - second: z.readonly(z.union([ - z.readonly(z.object({ - third: z.readonly(z.union([ - z.readonly(z.string()), - z.null() - ])) - })), - z.null() - ])) - })), - z.null() - ])) + first: z.nullable(z.readonly(z.object({ + second: z.nullable(z.readonly(z.object({ + third: z.nullable(z.readonly(z.string())) + }))) + }))) }); /** @@ -745,21 +702,15 @@ export const zModelWithAdditionalPropertiesEqTrue = z.object({ }); export const zNestedAnyOfArraysNullable = z.object({ - nullableArray: z.optional(z.union([ - z.array(z.union([z.string(), z.boolean()])), - z.null() - ])) + nullableArray: z.nullish(z.array(z.union([z.string(), z.boolean()]))) }); /** * An object that can be null */ -export const zNullableObject = z._default(z.union([ - z.object({ - foo: z.optional(z.string()) - }), - z.null() -]), null); +export const zNullableObject = z._default(z.nullable(z.object({ + foo: z.optional(z.string()) +})), null); /** * Some % character @@ -846,21 +797,18 @@ export const zModelWithPrefixItemsConstantSizeArray = z.array(z.union([ ])); export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([ - z.union([ + z.nullable(z.union([ z.number(), - z.null(), z.string() - ]), - z.union([ + ])), + z.nullable(z.union([ z.number(), - z.null(), z.string() - ]), - z.union([ + ])), + z.nullable(z.union([ z.number(), - z.null(), z.string() - ]) + ])) ]); export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([z.intersection(z.number(), z.string()), z.intersection(z.number(), z.string())]); @@ -979,23 +927,14 @@ export const zAdditionalPropertiesIntegerIssue = z.object({ export const zGenericSchemaDuplicateIssue1SystemBoolean = z.object({ item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), + error: z.nullish(z.string()), hasError: z.optional(z.readonly(z.boolean())), data: z.optional(z.record(z.string(), z.never())) }); export const zGenericSchemaDuplicateIssue1SystemString = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])), + item: z.nullish(z.string()), + error: z.nullish(z.string()), hasError: z.optional(z.readonly(z.boolean())) }); @@ -1021,10 +960,7 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.nullable(z.string()), string: z.optional(z.string()), number: z.optional(z.number()), boolean: z.optional(z.boolean()), @@ -1095,22 +1031,13 @@ export const zOneOfAllOfIssueWritable = z.union([ export const zGenericSchemaDuplicateIssue1SystemBooleanWritable = z.object({ item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), + error: z.nullish(z.string()), data: z.optional(z.record(z.string(), z.never())) }); export const zGenericSchemaDuplicateIssue1SystemStringWritable = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])) + item: z.nullish(z.string()), + error: z.nullish(z.string()) }); /** @@ -1126,10 +1053,7 @@ export const zCompositionWithOneOfAndProperties = z.intersection(z.union([ bar: zNonAsciiStringæøåÆøÅöôêÊ字符串 }) ]), z.object({ - baz: z.union([ - z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' })), - z.null() - ]), + baz: z.nullable(z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }))), qux: z.int().check(z.gte(0), z.maximum(255, { error: 'Invalid value: Expected uint8 to be <= 255' })) })); @@ -1137,10 +1061,7 @@ export const zModelWithOneOfAndProperties = z.intersection(z.union([ zSimpleParameter, zNonAsciiStringæøåÆøÅöôêÊ字符串 ]), z.object({ - baz: z.union([ - z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' })), - z.null() - ]), + baz: z.nullable(z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }))), qux: z.int().check(z.gte(0), z.maximum(255, { error: 'Invalid value: Expected uint8 to be <= 255' })) })); @@ -1281,70 +1202,40 @@ export const zDeprecatedCallData = z.object({ path: z.optional(z.never()), query: z.optional(z.never()), headers: z.object({ - parameter: z.union([ - zDeprecatedModel, - z.null() - ]) + parameter: z.nullable(zDeprecatedModel) }) }); export const zCallWithParametersData = z.object({ - body: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + body: z.nullable(z.record(z.string(), z.unknown())), path: z.object({ - parameterPath: z.union([ - z.string(), - z.null() - ]), - 'api-version': z.union([ - z.string(), - z.null() - ]) + parameterPath: z.nullable(z.string()), + 'api-version': z.nullable(z.string()) }), query: z.object({ foo_ref_enum: z.optional(zModelWithNestedArrayEnumsDataFoo), foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.union([ - z.string(), - z.null() - ]) + cursor: z.nullable(z.string()) }), headers: z.object({ - parameterHeader: z.union([ - z.string(), - z.null() - ]) + parameterHeader: z.nullable(z.string()) }) }); export const zCallWithWeirdParameterNamesData = z.object({ - body: z.union([ - zModelWithString, - z.null() - ]), + body: z.nullable(zModelWithString), path: z.object({ 'parameter.path.1': z.optional(z.string()), 'parameter-path-2': z.optional(z.string()), 'PARAMETER-PATH-3': z.optional(z.string()), - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.nullable(z.string()) }), query: z.object({ default: z.optional(z.string()), - 'parameter-query': z.union([ - z.string(), - z.null() - ]) + 'parameter-query': z.nullable(z.string()) }), headers: z.object({ - 'parameter.header': z.union([ - z.string(), - z.null() - ]) + 'parameter.header': z.nullable(z.string()) }) }); @@ -1358,10 +1249,7 @@ export const zGetCallWithOptionalParamData = z.object({ export const zPostCallWithOptionalParamData = z.object({ body: z.optional(z.object({ - offset: z.optional(z.union([ - z.number(), - z.null() - ])) + offset: z.nullish(z.number()) })), path: z.optional(z.never()), query: z.object({ @@ -1394,27 +1282,15 @@ export const zCallWithDefaultParametersData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), query: z.optional(z.object({ - parameterString: z._default(z.optional(z.union([ - z._default(z.string(), 'Hello World!'), - z.null() - ])), 'Hello World!'), - parameterNumber: z._default(z.optional(z.union([ - z._default(z.number(), 123), - z.null() - ])), 123), - parameterBoolean: z._default(z.optional(z.union([ - z._default(z.boolean(), true), - z.null() - ])), true), + parameterString: z._default(z.nullish(z.string()), 'Hello World!'), + parameterNumber: z._default(z.nullish(z.number()), 123), + parameterBoolean: z._default(z.nullish(z.boolean()), true), parameterEnum: z.optional(z.enum([ 'Success', 'Warning', 'Error' ])), - parameterModel: z.optional(z.union([ - zModelWithString, - z.null() - ])) + parameterModel: z.nullish(zModelWithString) })) }); @@ -1444,14 +1320,8 @@ export const zCallToTestOrderOfParamsData = z.object({ parameterStringWithDefault: z._default(z.string(), 'Hello World!'), parameterStringWithEmptyDefault: z._default(z.string(), ''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.optional(z.union([ - z.string(), - z.null() - ])), - parameterStringNullableWithDefault: z._default(z.optional(z.union([ - z.string(), - z.null() - ])), null) + parameterStringNullableWithNoDefault: z.nullish(z.string()), + parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) }) }); @@ -1559,26 +1429,11 @@ export const zCollectionFormatData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), query: z.object({ - parameterArrayCSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArraySSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayTSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayPipes: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayMulti: z.union([ - z.array(z.string()), - z.null() - ]) + parameterArrayCSV: z.nullable(z.array(z.string())), + parameterArraySSV: z.nullable(z.array(z.string())), + parameterArrayTSV: z.nullable(z.array(z.string())), + parameterArrayPipes: z.nullable(z.array(z.string())), + parameterArrayMulti: z.nullable(z.array(z.string())) }) }); @@ -1589,26 +1444,11 @@ export const zTypesData = z.object({ })), query: z.object({ parameterNumber: z._default(z.number(), 123), - parameterString: z._default(z.union([ - z._default(z.string(), 'default'), - z.null() - ]), 'default'), - parameterBoolean: z._default(z.union([ - z._default(z.boolean(), true), - z.null() - ]), true), - parameterObject: z._default(z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), null), - parameterArray: z.union([ - z.array(z.string()), - z.null() - ]), - parameterDictionary: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + parameterString: z._default(z.nullable(z.string()), 'default'), + parameterBoolean: z._default(z.nullable(z.boolean()), true), + parameterObject: z._default(z.nullable(z.record(z.string(), z.unknown())), null), + parameterArray: z.nullable(z.array(z.string())), + parameterDictionary: z.nullable(z.record(z.string(), z.unknown())), parameterEnum: z.enum([ 'Success', 'Warning', @@ -1627,10 +1467,7 @@ export const zTypesResponse = z.union([ export const zUploadFileData = z.object({ body: z.string(), path: z.object({ - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.nullable(z.string()) }), query: z.optional(z.never()) }); @@ -1691,10 +1528,7 @@ export const zMultipartResponseResponse = z.object({ export const zMultipartRequestData = z.object({ body: z.optional(z.object({ content: z.optional(z.string()), - data: z.optional(z.union([ - zModelWithString, - z.null() - ])) + data: z.nullish(zModelWithString) })), path: z.optional(z.never()), query: z.optional(z.never()) @@ -1702,28 +1536,16 @@ export const zMultipartRequestData = z.object({ export const zComplexParamsData = z.object({ body: z.optional(z.object({ - key: z.readonly(z.union([ - z.readonly(z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/))), - z.null() - ])), - name: z.union([ - z.string().check(z.maxLength(255)), - z.null() - ]), + key: z.nullable(z.readonly(z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/)))), + name: z.nullable(z.string().check(z.maxLength(255))), enabled: z._default(z.optional(z.boolean()), true), type: z.enum([ 'Monkey', 'Horse', 'Bird' ]), - listOfModels: z.optional(z.union([ - z.array(zModelWithString), - z.null() - ])), - listOfStrings: z.optional(z.union([ - z.array(z.string()), - z.null() - ])), + listOfModels: z.nullish(z.array(zModelWithString)), + listOfStrings: z.nullish(z.array(z.string())), parameters: z.union([ zModelWithString, zModelWithEnum, @@ -1732,10 +1554,7 @@ export const zComplexParamsData = z.object({ ]), user: z.optional(z.readonly(z.object({ id: z.optional(z.readonly(z.int().check(z.minimum(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }), z.maximum(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })))), - name: z.optional(z.readonly(z.union([ - z.readonly(z.string()), - z.null() - ]))) + name: z.nullish(z.readonly(z.string())) }))) })), path: z.object({ diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/validators/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/validators/zod.gen.ts index 7a5c78486..e80f1ac17 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/validators/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/validators/zod.gen.ts @@ -4,19 +4,12 @@ import * as z from 'zod/mini'; export const zBaz = z._default(z.readonly(z.string().check(z.regex(/foo\nbar/))), 'baz'); -export const zFoo = z._default(z.union([ - z.object({ - foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z._default(z.optional(z.int().check(z.gt(0))), 0) - }), - z.null() -]), null); +export const zFoo = z._default(z.nullable(z.object({ + foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), + bar: z.optional(z.lazy((): any => zBar)), + baz: z.optional(z.array(z.lazy((): any => zFoo))), + qux: z._default(z.optional(z.int().check(z.gt(0))), 0) +})), null); export const zBar = z.object({ foo: z.optional(zFoo) diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/default/zod.gen.ts index 6a2d2968e..fa53f469b 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/default/zod.gen.ts @@ -81,10 +81,7 @@ export const zSimpleFile = z.string(); /** * This is a simple string */ -export const zSimpleStringWithPattern = z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), - z.null() -]); +export const zSimpleStringWithPattern = z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).nullable(); /** * This is a simple enum with strings @@ -279,22 +276,10 @@ export const zModelFromZendesk = z.string(); * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp1: z.union([ - z.string(), - z.null() - ]).optional(), - nullableRequiredProp1: z.union([ - z.string(), - z.null() - ]), - nullableProp2: z.union([ - z.string(), - z.null() - ]).optional(), - nullableRequiredProp2: z.union([ - z.string(), - z.null() - ]), + nullableProp1: z.string().nullish(), + nullableRequiredProp1: z.string().nullable(), + nullableProp2: z.string().nullish(), + nullableRequiredProp2: z.string().nullable(), 'foo_bar-enum': z.enum([ 'Success', 'Warning', @@ -477,14 +462,8 @@ export const zCompositionWithAnyOfAnonymous = z.object({ */ export const zCompositionWithNestedAnyAndTypeNull = z.object({ propA: z.union([ - z.array(z.union([ - zModelWithDictionary, - z.null() - ])), - z.array(z.union([ - zModelWithArray, - z.null() - ])) + z.array(zModelWithDictionary.nullable()), + z.array(zModelWithArray.nullable()) ]).optional() }); @@ -496,10 +475,7 @@ export const zConstValue = z.enum(['ConstValue']); * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithNestedAnyOfAndNull = z.object({ - propA: z.union([ - z.array(z.union([z3eNum1Период, zConstValue])), - z.null() - ]).optional() + propA: z.array(z.union([z3eNum1Период, zConstValue])).nullish() }); /** @@ -512,9 +488,8 @@ export const zCompositionWithOneOfAndNullable = z.object({ }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ]).optional() + zModelWithDictionary + ]).nullish() }); /** @@ -551,12 +526,9 @@ export const zCompositionWithOneOfAndComplexArrayDictionary = z.object({ * This is a model with one property with a 'all of' relationship */ export const zCompositionWithAllOfAndNullable = z.object({ - propA: z.union([ - z.object({ - boolean: z.boolean().optional() - }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary), - z.null() - ]).optional() + propA: z.object({ + boolean: z.boolean().optional() + }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary).nullish() }); /** @@ -569,9 +541,8 @@ export const zCompositionWithAnyOfAndNullable = z.object({ }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ]).optional() + zModelWithDictionary + ]).nullish() }); /** @@ -597,10 +568,7 @@ export const zCompositionExtendedModel = zCompositionBaseModel.and(z.object({ export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.string().readonly(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.string().nullable(), string: z.string().optional(), number: z.number().optional(), boolean: z.boolean().optional(), @@ -623,20 +591,11 @@ export const zModelWithReference = z.object({ * This is a model with one nested property */ export const zModelWithNestedProperties = z.object({ - first: z.union([ - z.object({ - second: z.union([ - z.object({ - third: z.union([ - z.string().readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() + first: z.object({ + second: z.object({ + third: z.string().readonly().nullable() + }).readonly().nullable() + }).readonly().nullable() }); /** @@ -743,21 +702,15 @@ export const zModelWithAdditionalPropertiesEqTrue = z.object({ }); export const zNestedAnyOfArraysNullable = z.object({ - nullableArray: z.union([ - z.array(z.union([z.string(), z.boolean()])), - z.null() - ]).optional() + nullableArray: z.array(z.union([z.string(), z.boolean()])).nullish() }); /** * An object that can be null */ -export const zNullableObject = z.union([ - z.object({ - foo: z.string().optional() - }), - z.null() -]).default(null); +export const zNullableObject = z.object({ + foo: z.string().optional() +}).nullable().default(null); /** * Some % character @@ -846,19 +799,16 @@ export const zModelWithPrefixItemsConstantSizeArray = z.array(z.union([ export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([ z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]) + ]).nullable() ]); export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([z.intersection(z.number(), z.string()), z.intersection(z.number(), z.string())]); @@ -977,23 +927,14 @@ export const zAdditionalPropertiesIntegerIssue = z.object({ export const zGenericSchemaDuplicateIssue1SystemBoolean = z.object({ item: z.boolean().optional(), - error: z.union([ - z.string(), - z.null() - ]).optional(), + error: z.string().nullish(), hasError: z.boolean().readonly().optional(), data: z.record(z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemString = z.object({ - item: z.union([ - z.string(), - z.null() - ]).optional(), - error: z.union([ - z.string(), - z.null() - ]).optional(), + item: z.string().nullish(), + error: z.string().nullish(), hasError: z.boolean().readonly().optional() }); @@ -1019,10 +960,7 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.string().nullable(), string: z.string().optional(), number: z.number().optional(), boolean: z.boolean().optional(), @@ -1093,22 +1031,13 @@ export const zOneOfAllOfIssueWritable = z.union([ export const zGenericSchemaDuplicateIssue1SystemBooleanWritable = z.object({ item: z.boolean().optional(), - error: z.union([ - z.string(), - z.null() - ]).optional(), + error: z.string().nullish(), data: z.record(z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemStringWritable = z.object({ - item: z.union([ - z.string(), - z.null() - ]).optional(), - error: z.union([ - z.string(), - z.null() - ]).optional() + item: z.string().nullish(), + error: z.string().nullish() }); /** @@ -1124,10 +1053,7 @@ export const zCompositionWithOneOfAndProperties = z.intersection(z.union([ bar: zNonAsciiStringæøåÆøÅöôêÊ字符串 }) ]), z.object({ - baz: z.union([ - z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.number().int().gte(0).max(255, { message: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1135,10 +1061,7 @@ export const zModelWithOneOfAndProperties = z.intersection(z.union([ zSimpleParameter, zNonAsciiStringæøåÆøÅöôêÊ字符串 ]), z.object({ - baz: z.union([ - z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.number().int().gte(0).max(255, { message: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1279,70 +1202,40 @@ export const zDeprecatedCallData = z.object({ path: z.never().optional(), query: z.never().optional(), headers: z.object({ - parameter: z.union([ - zDeprecatedModel, - z.null() - ]) + parameter: zDeprecatedModel.nullable() }) }); export const zCallWithParametersData = z.object({ - body: z.union([ - z.record(z.unknown()), - z.null() - ]), + body: z.record(z.unknown()).nullable(), path: z.object({ - parameterPath: z.union([ - z.string(), - z.null() - ]), - 'api-version': z.union([ - z.string(), - z.null() - ]) + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }), query: z.object({ foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.union([ - z.string(), - z.null() - ]) + cursor: z.string().nullable() }), headers: z.object({ - parameterHeader: z.union([ - z.string(), - z.null() - ]) + parameterHeader: z.string().nullable() }) }); export const zCallWithWeirdParameterNamesData = z.object({ - body: z.union([ - zModelWithString, - z.null() - ]), + body: zModelWithString.nullable(), path: z.object({ 'parameter.path.1': z.string().optional(), 'parameter-path-2': z.string().optional(), 'PARAMETER-PATH-3': z.string().optional(), - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.string().nullable() }), query: z.object({ default: z.string().optional(), - 'parameter-query': z.union([ - z.string(), - z.null() - ]) + 'parameter-query': z.string().nullable() }), headers: z.object({ - 'parameter.header': z.union([ - z.string(), - z.null() - ]) + 'parameter.header': z.string().nullable() }) }); @@ -1356,10 +1249,7 @@ export const zGetCallWithOptionalParamData = z.object({ export const zPostCallWithOptionalParamData = z.object({ body: z.object({ - offset: z.union([ - z.number(), - z.null() - ]).optional() + offset: z.number().nullish() }).optional(), path: z.never().optional(), query: z.object({ @@ -1392,27 +1282,15 @@ export const zCallWithDefaultParametersData = z.object({ body: z.never().optional(), path: z.never().optional(), query: z.object({ - parameterString: z.union([ - z.string().default('Hello World!'), - z.null() - ]).optional().default('Hello World!'), - parameterNumber: z.union([ - z.number().default(123), - z.null() - ]).optional().default(123), - parameterBoolean: z.union([ - z.boolean().default(true), - z.null() - ]).optional().default(true), + parameterString: z.string().nullish().default('Hello World!'), + parameterNumber: z.number().nullish().default(123), + parameterBoolean: z.boolean().nullish().default(true), parameterEnum: z.enum([ 'Success', 'Warning', 'Error' ]).optional(), - parameterModel: z.union([ - zModelWithString, - z.null() - ]).optional() + parameterModel: zModelWithString.nullish() }).optional() }); @@ -1442,14 +1320,8 @@ export const zCallToTestOrderOfParamsData = z.object({ parameterStringWithDefault: z.string().default('Hello World!'), parameterStringWithEmptyDefault: z.string().default(''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.union([ - z.string(), - z.null() - ]).optional(), - parameterStringNullableWithDefault: z.union([ - z.string(), - z.null() - ]).optional().default(null) + parameterStringNullableWithNoDefault: z.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }) }); @@ -1557,26 +1429,11 @@ export const zCollectionFormatData = z.object({ body: z.never().optional(), path: z.never().optional(), query: z.object({ - parameterArrayCSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArraySSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayTSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayPipes: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayMulti: z.union([ - z.array(z.string()), - z.null() - ]) + parameterArrayCSV: z.array(z.string()).nullable(), + parameterArraySSV: z.array(z.string()).nullable(), + parameterArrayTSV: z.array(z.string()).nullable(), + parameterArrayPipes: z.array(z.string()).nullable(), + parameterArrayMulti: z.array(z.string()).nullable() }) }); @@ -1587,26 +1444,11 @@ export const zTypesData = z.object({ }).optional(), query: z.object({ parameterNumber: z.number().default(123), - parameterString: z.union([ - z.string().default('default'), - z.null() - ]).default('default'), - parameterBoolean: z.union([ - z.boolean().default(true), - z.null() - ]).default(true), - parameterObject: z.union([ - z.record(z.unknown()), - z.null() - ]).default(null), - parameterArray: z.union([ - z.array(z.string()), - z.null() - ]), - parameterDictionary: z.union([ - z.record(z.unknown()), - z.null() - ]), + parameterString: z.string().nullable().default('default'), + parameterBoolean: z.boolean().nullable().default(true), + parameterObject: z.record(z.unknown()).nullable().default(null), + parameterArray: z.array(z.string()).nullable(), + parameterDictionary: z.record(z.unknown()).nullable(), parameterEnum: z.enum([ 'Success', 'Warning', @@ -1625,10 +1467,7 @@ export const zTypesResponse = z.union([ export const zUploadFileData = z.object({ body: z.string(), path: z.object({ - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.string().nullable() }), query: z.never().optional() }); @@ -1689,10 +1528,7 @@ export const zMultipartResponseResponse = z.object({ export const zMultipartRequestData = z.object({ body: z.object({ content: z.string().optional(), - data: z.union([ - zModelWithString, - z.null() - ]).optional() + data: zModelWithString.nullish() }).optional(), path: z.never().optional(), query: z.never().optional() @@ -1700,28 +1536,16 @@ export const zMultipartRequestData = z.object({ export const zComplexParamsData = z.object({ body: z.object({ - key: z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly(), - z.null() - ]).readonly(), - name: z.union([ - z.string().max(255), - z.null() - ]), + key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly().nullable(), + name: z.string().max(255).nullable(), enabled: z.boolean().optional().default(true), type: z.enum([ 'Monkey', 'Horse', 'Bird' ]), - listOfModels: z.union([ - z.array(zModelWithString), - z.null() - ]).optional(), - listOfStrings: z.union([ - z.array(z.string()), - z.null() - ]).optional(), + listOfModels: z.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), parameters: z.union([ zModelWithString, zModelWithEnum, @@ -1730,10 +1554,7 @@ export const zComplexParamsData = z.object({ ]), user: z.object({ id: z.number().int().min(-2147483648, { message: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { message: 'Invalid value: Expected int32 to be <= 2147483647' }).readonly().optional(), - name: z.union([ - z.string().readonly(), - z.null() - ]).readonly().optional() + name: z.string().readonly().nullish() }).readonly().optional() }).optional(), path: z.object({ diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/validators/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/validators/zod.gen.ts index bdddc5775..1e7523b1f 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/validators/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/validators/zod.gen.ts @@ -4,15 +4,12 @@ import { z } from 'zod/v3'; export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz'); -export const zFoo: z.ZodTypeAny = z.union([ - z.object({ - foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), - bar: z.lazy(() => zBar).optional(), - baz: z.array(z.lazy(() => zFoo)).optional(), - qux: z.number().int().gt(0).optional().default(0) - }), - z.null() -]).default(null); +export const zFoo: z.ZodTypeAny = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy(() => zBar).optional(), + baz: z.array(z.lazy(() => zFoo)).optional(), + qux: z.number().int().gt(0).optional().default(0) +}).nullable().default(null); export const zBar = z.object({ foo: zFoo.optional() diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/array-items-all-of/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/array-items-all-of/zod.gen.ts index 5a58c7fcc..37fd72b6a 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/array-items-all-of/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/array-items-all-of/zod.gen.ts @@ -3,18 +3,18 @@ import * as z from 'zod'; export const zArrayWithAllOfObjects = z.array(z.object({ - id: z.optional(z.int()) + id: z.int().optional() }).and(z.object({ - name: z.optional(z.string()) + name: z.string().optional() }))); export const zArrayWithAllOfPrimitives = z.array(z.intersection(z.number(), z.string())); export const zBaseModel = z.object({ - id: z.optional(z.int()), - createdAt: z.optional(z.iso.datetime()) + id: z.int().optional(), + createdAt: z.iso.datetime().optional() }); export const zArrayWithAllOfRefs = z.array(zBaseModel.and(z.object({ - extra: z.optional(z.string()) + extra: z.string().optional() }))); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/array-items-one-of-length-1/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/array-items-one-of-length-1/zod.gen.ts index d4647f04a..a7e66aa30 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/array-items-one-of-length-1/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/array-items-one-of-length-1/zod.gen.ts @@ -5,5 +5,5 @@ import * as z from 'zod'; export const zBar = z.string(); export const zFoo = z.object({ - foo: z.optional(z.array(zBar).min(1).max(2147483647)) + foo: z.array(zBar).min(1).max(2147483647).optional() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/circular/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/circular/zod.gen.ts index a953c8432..6fdddaf32 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/circular/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/circular/zod.gen.ts @@ -3,24 +3,16 @@ import * as z from 'zod'; export const zFoo = z.object({ - get quux() { - return z.optional(z.lazy((): any => zQuux)); - } + quux: z.lazy((): any => zQuux).optional() }); export const zBar = z.object({ - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.lazy((): any => zBaz)); - } + bar: z.lazy((): any => zBar).optional(), + baz: z.lazy((): any => zBaz).optional() }); export const zBaz = z.object({ - get quux() { - return z.optional(z.lazy((): any => zQuux)); - } + quux: z.lazy((): any => zQuux).optional() }); export const zQux = z.union([ @@ -33,9 +25,9 @@ export const zQux = z.union([ ]); export const zQuux = z.object({ - qux: z.optional(zQux) + qux: zQux.optional() }); export const zCorge = z.object({ - baz: z.optional(z.array(zBaz)) + baz: z.array(zBaz).optional() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/default/zod.gen.ts index af76f6c56..de9892891 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/default/zod.gen.ts @@ -81,10 +81,7 @@ export const zSimpleFile = z.string(); /** * This is a simple string */ -export const zSimpleStringWithPattern = z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), - z.null() -]); +export const zSimpleStringWithPattern = z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).nullable(); /** * This is a simple enum with strings @@ -166,32 +163,32 @@ export const zArrayWithStrings = z.array(z.string()).default(['test']); * This is a simple array with properties */ export const zArrayWithProperties = z.array(z.object({ - '16x16': z.optional(zCamelCaseCommentWithBreaks), - bar: z.optional(z.string()) + '16x16': zCamelCaseCommentWithBreaks.optional(), + bar: z.string().optional() })); /** * This is a simple array with any of properties */ export const zArrayWithAnyOfProperties = z.array(z.union([z.object({ - foo: z.optional(z.string()).default('test') + foo: z.string().optional().default('test') }), z.object({ - bar: z.optional(z.string()) + bar: z.string().optional() })])); export const zAnyOfAnyAndNull = z.object({ - data: z.optional(z.unknown()) + data: z.unknown().optional() }); /** * This is a simple array with any of properties */ export const zAnyOfArrays = z.object({ - results: z.optional(z.array(z.union([z.object({ - foo: z.optional(z.string()) + results: z.array(z.union([z.object({ + foo: z.string().optional() }), z.object({ - bar: z.optional(z.string()) - })]))) + bar: z.string().optional() + })])).optional() }); /** @@ -200,8 +197,8 @@ export const zAnyOfArrays = z.object({ export const zDictionaryWithString = z.record(z.string(), z.string()); export const zDictionaryWithPropertiesAndAdditionalProperties = z.object({ - foo: z.optional(z.number()), - bar: z.optional(z.boolean()) + foo: z.number().optional(), + bar: z.boolean().optional() }); /** @@ -213,29 +210,29 @@ export const zDictionaryWithDictionary = z.record(z.string(), z.record(z.string( * This is a complex dictionary */ export const zDictionaryWithProperties = z.record(z.string(), z.object({ - foo: z.optional(z.string()), - bar: z.optional(z.string()) + foo: z.string().optional(), + bar: z.string().optional() })); /** * This is a model with one number property */ export const zModelWithInteger = z.object({ - prop: z.optional(z.int()) + prop: z.int().optional() }); /** * This is a model with one boolean property */ export const zModelWithBoolean = z.object({ - prop: z.optional(z.boolean()) + prop: z.boolean().optional() }); /** * This is a model with one string property */ export const zModelWithString = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** @@ -267,7 +264,7 @@ export const zDictionaryWithArray = z.record(z.string(), z.array(zModelWithStrin * This is a model with one string property */ export const zModelWithStringError = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** @@ -279,103 +276,91 @@ export const zModelFromZendesk = z.string(); * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp1: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp1: z.union([ - z.string(), - z.null() - ]), - nullableProp2: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp2: z.union([ - z.string(), - z.null() - ]), - 'foo_bar-enum': z.optional(z.enum([ + nullableProp1: z.string().nullish(), + nullableRequiredProp1: z.string().nullable(), + nullableProp2: z.string().nullish(), + nullableRequiredProp2: z.string().nullable(), + 'foo_bar-enum': z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])) + ]).optional() }); /** * This is a model with one enum */ export const zModelWithEnum = z.object({ - 'foo_bar-enum': z.optional(z.enum([ + 'foo_bar-enum': z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])), - statusCode: z.optional(z.enum([ + ]).optional(), + statusCode: z.enum([ '100', '200 FOO', '300 FOO_BAR', '400 foo-bar', '500 foo.bar', '600 foo&bar' - ])), - bool: z.optional(z.literal(true)) + ]).optional(), + bool: z.literal(true).optional() }); /** * This is a model with one enum with escaped name */ export const zModelWithEnumWithHyphen = z.object({ - 'foo-bar-baz-qux': z.optional(z.enum(['3.0'])) + 'foo-bar-baz-qux': z.enum(['3.0']).optional() }); /** * This is a model with one enum */ export const zModelWithEnumFromDescription = z.object({ - test: z.optional(z.int()) + test: z.int().optional() }); /** * This is a model with nested enums */ export const zModelWithNestedEnums = z.object({ - dictionaryWithEnum: z.optional(z.record(z.string(), z.enum([ + dictionaryWithEnum: z.record(z.string(), z.enum([ 'Success', 'Warning', 'Error' - ]))), - dictionaryWithEnumFromDescription: z.optional(z.record(z.string(), z.int())), - arrayWithEnum: z.optional(z.array(z.enum([ + ])).optional(), + dictionaryWithEnumFromDescription: z.record(z.string(), z.int()).optional(), + arrayWithEnum: z.array(z.enum([ 'Success', 'Warning', 'Error' - ]))), - arrayWithDescription: z.optional(z.array(z.int())), - 'foo_bar-enum': z.optional(z.enum([ + ])).optional(), + arrayWithDescription: z.array(z.int()).optional(), + 'foo_bar-enum': z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])) + ]).optional() }); /** * This is a model with one property containing an array */ export const zModelWithArray = z.object({ - prop: z.optional(z.array(zModelWithString)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithString).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); /** * This is a model with one property containing a dictionary */ export const zModelWithDictionary = z.object({ - prop: z.optional(z.record(z.string(), z.string())) + prop: z.record(z.string(), z.string()).optional() }); /** @@ -384,41 +369,39 @@ export const zModelWithDictionary = z.object({ * @deprecated */ export const zDeprecatedModel = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** * This is a model with one property containing a circular reference */ export const zModelWithCircularReference = z.object({ - get prop() { - return z.optional(z.lazy((): any => zModelWithCircularReference)); - } + prop: z.lazy((): any => zModelWithCircularReference).optional() }); /** * This is a model with one property with a 'one of' relationship */ export const zCompositionWithOneOf = z.object({ - propA: z.optional(z.union([ + propA: z.union([ zModelWithString, zModelWithEnum, zModelWithArray, zModelWithDictionary - ])) + ]).optional() }); /** * This is a model with one property with a 'one of' relationship where the options are not $ref */ export const zCompositionWithOneOfAnonymous = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - propA: z.optional(z.string()) + propA: z.string().optional() }), z.string(), z.int() - ])) + ]).optional() }); /** @@ -426,7 +409,7 @@ export const zCompositionWithOneOfAnonymous = z.object({ */ export const zModelCircle = z.object({ kind: z.string(), - radius: z.optional(z.number()) + radius: z.number().optional() }); /** @@ -434,7 +417,7 @@ export const zModelCircle = z.object({ */ export const zModelSquare = z.object({ kind: z.string(), - sideLength: z.optional(z.number()) + sideLength: z.number().optional() }); /** @@ -453,41 +436,35 @@ export const zCompositionWithOneOfDiscriminator = z.union([ * This is a model with one property with a 'any of' relationship */ export const zCompositionWithAnyOf = z.object({ - propA: z.optional(z.union([ + propA: z.union([ zModelWithString, zModelWithEnum, zModelWithArray, zModelWithDictionary - ])) + ]).optional() }); /** * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithAnyOfAnonymous = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - propA: z.optional(z.string()) + propA: z.string().optional() }), z.string(), z.int() - ])) + ]).optional() }); /** * This is a model with nested 'any of' property with a type null */ export const zCompositionWithNestedAnyAndTypeNull = z.object({ - propA: z.optional(z.union([ - z.array(z.union([ - zModelWithDictionary, - z.null() - ])), - z.array(z.union([ - zModelWithArray, - z.null() - ])) - ])) + propA: z.union([ + z.array(zModelWithDictionary.nullable()), + z.array(zModelWithArray.nullable()) + ]).optional() }); export const z3eNum1Период = z.enum(['Bird', 'Dog']); @@ -498,90 +475,82 @@ export const zConstValue = z.enum(['ConstValue']); * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithNestedAnyOfAndNull = z.object({ - propA: z.optional(z.union([ - z.array(z.union([z3eNum1Период, zConstValue])), - z.null() - ])) + propA: z.array(z.union([z3eNum1Период, zConstValue])).nullish() }); /** * This is a model with one property with a 'one of' relationship */ export const zCompositionWithOneOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - boolean: z.optional(z.boolean()) + boolean: z.boolean().optional() }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ])) + zModelWithDictionary + ]).nullish() }); /** * This is a model that contains a simple dictionary within composition */ export const zCompositionWithOneOfAndSimpleDictionary = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.boolean(), z.record(z.string(), z.number()) - ])) + ]).optional() }); /** * This is a model that contains a dictionary of simple arrays within composition */ export const zCompositionWithOneOfAndSimpleArrayDictionary = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.boolean(), z.record(z.string(), z.array(z.boolean())) - ])) + ]).optional() }); /** * This is a model that contains a dictionary of complex arrays (composited) within composition */ export const zCompositionWithOneOfAndComplexArrayDictionary = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.boolean(), z.record(z.string(), z.array(z.union([z.number(), z.string()]))) - ])) + ]).optional() }); /** * This is a model with one property with a 'all of' relationship */ export const zCompositionWithAllOfAndNullable = z.object({ - propA: z.optional(z.union([ - z.object({ - boolean: z.optional(z.boolean()) - }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary), - z.null() - ])) + propA: z.object({ + boolean: z.boolean().optional() + }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary).nullish() }); /** * This is a model with one property with a 'any of' relationship */ export const zCompositionWithAnyOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - boolean: z.optional(z.boolean()) + boolean: z.boolean().optional() }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ])) + zModelWithDictionary + ]).nullish() }); /** * This is a base model with two simple optional properties */ export const zCompositionBaseModel = z.object({ - firstName: z.optional(z.string()), - lastname: z.optional(z.string()) + firstName: z.string().optional(), + lastname: z.string().optional() }); /** @@ -599,87 +568,75 @@ export const zCompositionExtendedModel = zCompositionBaseModel.and(z.object({ export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.string().readonly(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), - string: z.optional(z.string()), - number: z.optional(z.number()), - boolean: z.optional(z.boolean()), - reference: z.optional(zModelWithString), - 'property with space': z.optional(z.string()), - default: z.optional(z.string()), - try: z.optional(z.string()), - '@namespace.string': z.optional(z.string().readonly()), - '@namespace.integer': z.optional(z.int().readonly()) + requiredAndNullable: z.string().nullable(), + string: z.string().optional(), + number: z.number().optional(), + boolean: z.boolean().optional(), + reference: zModelWithString.optional(), + 'property with space': z.string().optional(), + default: z.string().optional(), + try: z.string().optional(), + '@namespace.string': z.string().readonly().optional(), + '@namespace.integer': z.int().readonly().optional() }); /** * This is a model with one property containing a reference */ export const zModelWithReference = z.object({ - prop: z.optional(zModelWithProperties) + prop: zModelWithProperties.optional() }); /** * This is a model with one nested property */ export const zModelWithNestedProperties = z.object({ - first: z.union([ - z.object({ - second: z.union([ - z.object({ - third: z.union([ - z.string().readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() + first: z.object({ + second: z.object({ + third: z.string().readonly().nullable() + }).readonly().nullable() + }).readonly().nullable() }); /** * This is a model with duplicated properties */ export const zModelWithDuplicateProperties = z.object({ - prop: z.optional(zModelWithString) + prop: zModelWithString.optional() }); /** * This is a model with ordered properties */ export const zModelWithOrderedProperties = z.object({ - zebra: z.optional(z.string()), - apple: z.optional(z.string()), - hawaii: z.optional(z.string()) + zebra: z.string().optional(), + apple: z.string().optional(), + hawaii: z.string().optional() }); /** * This is a model with duplicated imports */ export const zModelWithDuplicateImports = z.object({ - propA: z.optional(zModelWithString), - propB: z.optional(zModelWithString), - propC: z.optional(zModelWithString) + propA: zModelWithString.optional(), + propB: zModelWithString.optional(), + propC: zModelWithString.optional() }); /** * This is a model that extends another model */ export const zModelThatExtends = zModelWithString.and(z.object({ - propExtendsA: z.optional(z.string()), - propExtendsB: z.optional(zModelWithString) + propExtendsA: z.string().optional(), + propExtendsB: zModelWithString.optional() })); /** * This is a model that extends another model */ export const zModelThatExtendsExtends = zModelWithString.and(zModelThatExtends).and(z.object({ - propExtendsC: z.optional(z.string()), - propExtendsD: z.optional(zModelWithString) + propExtendsC: z.string().optional(), + propExtendsD: zModelWithString.optional() })); /** @@ -688,31 +645,31 @@ export const zModelThatExtendsExtends = zModelWithString.and(zModelThatExtends). export const zModelWithPattern = z.object({ key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), name: z.string().max(255), - enabled: z.optional(z.boolean().readonly()), - modified: z.optional(z.iso.datetime().readonly()), - id: z.optional(z.string().regex(/^\d{2}-\d{3}-\d{4}$/)), - text: z.optional(z.string().regex(/^\w+$/)), - patternWithSingleQuotes: z.optional(z.string().regex(/^[a-zA-Z0-9']*$/)), - patternWithNewline: z.optional(z.string().regex(/aaa\nbbb/)), - patternWithBacktick: z.optional(z.string().regex(/aaa`bbb/)) + enabled: z.boolean().readonly().optional(), + modified: z.iso.datetime().readonly().optional(), + id: z.string().regex(/^\d{2}-\d{3}-\d{4}$/).optional(), + text: z.string().regex(/^\w+$/).optional(), + patternWithSingleQuotes: z.string().regex(/^[a-zA-Z0-9']*$/).optional(), + patternWithNewline: z.string().regex(/aaa\nbbb/).optional(), + patternWithBacktick: z.string().regex(/aaa`bbb/).optional() }); export const zFile = z.object({ - id: z.optional(z.string().min(1).readonly()), - updated_at: z.optional(z.iso.datetime().readonly()), - created_at: z.optional(z.iso.datetime().readonly()), + id: z.string().min(1).readonly().optional(), + updated_at: z.iso.datetime().readonly().optional(), + created_at: z.iso.datetime().readonly().optional(), mime: z.string().min(1).max(24), - file: z.optional(z.url().readonly()) + file: z.url().readonly().optional() }); export const zDefault = z.object({ - name: z.optional(z.string()) + name: z.string().optional() }); export const zPageable = z.object({ - page: z.optional(z.int().gte(0).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })).default(0), - size: z.optional(z.int().gte(1).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })), - sort: z.optional(z.array(z.string())) + page: z.int().gte(0).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional().default(0), + size: z.int().gte(1).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional(), + sort: z.array(z.string()).optional() }); /** @@ -731,35 +688,29 @@ export const zFreeFormObjectWithAdditionalPropertiesEqTrue = z.record(z.string() export const zFreeFormObjectWithAdditionalPropertiesEqEmptyObject = z.record(z.string(), z.unknown()); export const zModelWithConst = z.object({ - String: z.optional(z.enum(['String'])), - number: z.optional(z.literal(0)), - null: z.optional(z.unknown()), - withType: z.optional(z.enum(['Some string'])) + String: z.enum(['String']).optional(), + number: z.literal(0).optional(), + null: z.unknown().optional(), + withType: z.enum(['Some string']).optional() }); /** * This is a model with one property and additionalProperties: true */ export const zModelWithAdditionalPropertiesEqTrue = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); export const zNestedAnyOfArraysNullable = z.object({ - nullableArray: z.optional(z.union([ - z.array(z.union([z.string(), z.boolean()])), - z.null() - ])) + nullableArray: z.array(z.union([z.string(), z.boolean()])).nullish() }); /** * An object that can be null */ -export const zNullableObject = z.union([ - z.object({ - foo: z.optional(z.string()) - }), - z.null() -]).default(null); +export const zNullableObject = z.object({ + foo: z.string().optional() +}).nullable().default(null); /** * Some % character @@ -767,7 +718,7 @@ export const zNullableObject = z.union([ export const zCharactersInDescription = z.string(); export const zModelWithNullableObject = z.object({ - data: z.optional(zNullableObject) + data: zNullableObject.optional() }); export const zModelWithOneOfEnum = z.union([ @@ -795,17 +746,17 @@ export const zModelWithNestedArrayEnumsDataFoo = z.enum(['foo', 'bar']); export const zModelWithNestedArrayEnumsDataBar = z.enum(['baz', 'qux']); export const zModelWithNestedArrayEnumsData = z.object({ - foo: z.optional(z.array(zModelWithNestedArrayEnumsDataFoo)), - bar: z.optional(z.array(zModelWithNestedArrayEnumsDataBar)) + foo: z.array(zModelWithNestedArrayEnumsDataFoo).optional(), + bar: z.array(zModelWithNestedArrayEnumsDataBar).optional() }); export const zModelWithNestedArrayEnums = z.object({ - array_strings: z.optional(z.array(z.string())), - data: z.optional(zModelWithNestedArrayEnumsData) + array_strings: z.array(z.string()).optional(), + data: zModelWithNestedArrayEnumsData.optional() }); export const zModelWithNestedCompositionEnums = z.object({ - foo: z.optional(zModelWithNestedArrayEnumsDataFoo) + foo: zModelWithNestedArrayEnumsDataFoo.optional() }); export const zModelWithReadOnlyAndWriteOnly = z.object({ @@ -817,9 +768,9 @@ export const zModelWithReadOnlyAndWriteOnly = z.object({ * This is a model with one property containing an array */ export const zModelWithArrayReadOnlyAndWriteOnly = z.object({ - prop: z.optional(z.array(zModelWithReadOnlyAndWriteOnly)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithReadOnlyAndWriteOnly).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); export const zModelWithConstantSizeArray = z.tuple([z.number(), z.number()]); @@ -848,25 +799,22 @@ export const zModelWithPrefixItemsConstantSizeArray = z.array(z.union([ export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([ z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]) + ]).nullable() ]); export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([z.intersection(z.number(), z.string()), z.intersection(z.number(), z.string())]); export const zModelWithNumericEnumUnion = z.object({ - value: z.optional(z.union([ + value: z.union([ z.literal(-10), z.literal(-1), z.literal(0), @@ -874,14 +822,14 @@ export const zModelWithNumericEnumUnion = z.object({ z.literal(3), z.literal(6), z.literal(12) - ])) + ]).optional() }); /** * Some description with `back ticks` */ export const zModelWithBackticksInDescription = z.object({ - template: z.optional(z.string()) + template: z.string().optional() }); /** @@ -923,40 +871,40 @@ export const zModelWithAnyOfConstantSizeArrayWithNSizeAndOptions = z.tuple([z.un ])]); export const zSchemaWithFormRestrictedKeys = z.object({ - description: z.optional(z.string()), - 'x-enum-descriptions': z.optional(z.string()), - 'x-enum-varnames': z.optional(z.string()), - 'x-enumNames': z.optional(z.string()), - title: z.optional(z.string()), - object: z.optional(z.object({ - description: z.optional(z.string()), - 'x-enum-descriptions': z.optional(z.string()), - 'x-enum-varnames': z.optional(z.string()), - 'x-enumNames': z.optional(z.string()), - title: z.optional(z.string()) - })), - array: z.optional(z.array(z.object({ - description: z.optional(z.string()), - 'x-enum-descriptions': z.optional(z.string()), - 'x-enum-varnames': z.optional(z.string()), - 'x-enumNames': z.optional(z.string()), - title: z.optional(z.string()) - }))) + description: z.string().optional(), + 'x-enum-descriptions': z.string().optional(), + 'x-enum-varnames': z.string().optional(), + 'x-enumNames': z.string().optional(), + title: z.string().optional(), + object: z.object({ + description: z.string().optional(), + 'x-enum-descriptions': z.string().optional(), + 'x-enum-varnames': z.string().optional(), + 'x-enumNames': z.string().optional(), + title: z.string().optional() + }).optional(), + array: z.array(z.object({ + description: z.string().optional(), + 'x-enum-descriptions': z.string().optional(), + 'x-enum-varnames': z.string().optional(), + 'x-enumNames': z.string().optional(), + title: z.string().optional() + })).optional() }); /** * This schema was giving PascalCase transformations a hard time */ export const zIoK8sApimachineryPkgApisMetaV1Preconditions = z.object({ - resourceVersion: z.optional(z.string()), - uid: z.optional(z.string()) + resourceVersion: z.string().optional(), + uid: z.string().optional() }); /** * This schema was giving PascalCase transformations a hard time */ export const zIoK8sApimachineryPkgApisMetaV1DeleteOptions = z.object({ - preconditions: z.optional(zIoK8sApimachineryPkgApisMetaV1Preconditions) + preconditions: zIoK8sApimachineryPkgApisMetaV1Preconditions.optional() }); export const zAdditionalPropertiesUnknownIssue = z.record(z.string(), z.union([ @@ -978,25 +926,16 @@ export const zAdditionalPropertiesIntegerIssue = z.object({ }); export const zGenericSchemaDuplicateIssue1SystemBoolean = z.object({ - item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), - hasError: z.optional(z.boolean().readonly()), - data: z.optional(z.record(z.string(), z.never())) + item: z.boolean().optional(), + error: z.string().nullish(), + hasError: z.boolean().readonly().optional(), + data: z.record(z.string(), z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemString = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])), - hasError: z.optional(z.boolean().readonly()) + item: z.string().nullish(), + error: z.string().nullish(), + hasError: z.boolean().readonly().optional() }); export const zOneOfAllOfIssue = z.union([ @@ -1009,7 +948,7 @@ export const zOneOfAllOfIssue = z.union([ export const zExternalSharedExternalSharedModel = z.object({ id: z.string(), - name: z.optional(z.string()) + name: z.string().optional() }); export const zExternalRefA = zExternalSharedExternalSharedModel; @@ -1021,24 +960,21 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), - string: z.optional(z.string()), - number: z.optional(z.number()), - boolean: z.optional(z.boolean()), - reference: z.optional(zModelWithString), - 'property with space': z.optional(z.string()), - default: z.optional(z.string()), - try: z.optional(z.string()) + requiredAndNullable: z.string().nullable(), + string: z.string().optional(), + number: z.number().optional(), + boolean: z.boolean().optional(), + reference: zModelWithString.optional(), + 'property with space': z.string().optional(), + default: z.string().optional(), + try: z.string().optional() }); /** * This is a model with one property containing a reference */ export const zModelWithReferenceWritable = z.object({ - prop: z.optional(zModelWithPropertiesWritable) + prop: zModelWithPropertiesWritable.optional() }); /** @@ -1047,11 +983,11 @@ export const zModelWithReferenceWritable = z.object({ export const zModelWithPatternWritable = z.object({ key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), name: z.string().max(255), - id: z.optional(z.string().regex(/^\d{2}-\d{3}-\d{4}$/)), - text: z.optional(z.string().regex(/^\w+$/)), - patternWithSingleQuotes: z.optional(z.string().regex(/^[a-zA-Z0-9']*$/)), - patternWithNewline: z.optional(z.string().regex(/aaa\nbbb/)), - patternWithBacktick: z.optional(z.string().regex(/aaa`bbb/)) + id: z.string().regex(/^\d{2}-\d{3}-\d{4}$/).optional(), + text: z.string().regex(/^\w+$/).optional(), + patternWithSingleQuotes: z.string().regex(/^[a-zA-Z0-9']*$/).optional(), + patternWithNewline: z.string().regex(/aaa\nbbb/).optional(), + patternWithBacktick: z.string().regex(/aaa`bbb/).optional() }); export const zFileWritable = z.object({ @@ -1067,9 +1003,9 @@ export const zModelWithReadOnlyAndWriteOnlyWritable = z.object({ * This is a model with one property containing an array */ export const zModelWithArrayReadOnlyAndWriteOnlyWritable = z.object({ - prop: z.optional(z.array(zModelWithReadOnlyAndWriteOnlyWritable)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithReadOnlyAndWriteOnlyWritable).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); export const zModelWithAnyOfConstantSizeArrayWithNSizeAndOptionsWritable = z.tuple([z.union([ @@ -1094,23 +1030,14 @@ export const zOneOfAllOfIssueWritable = z.union([ ]); export const zGenericSchemaDuplicateIssue1SystemBooleanWritable = z.object({ - item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), - data: z.optional(z.record(z.string(), z.never())) + item: z.boolean().optional(), + error: z.string().nullish(), + data: z.record(z.string(), z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemStringWritable = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])) + item: z.string().nullish(), + error: z.string().nullish() }); /** @@ -1126,10 +1053,7 @@ export const zCompositionWithOneOfAndProperties = z.intersection(z.union([ bar: zNonAsciiStringæøåÆøÅöôêÊ字符串 }) ]), z.object({ - baz: z.union([ - z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.int().gte(0).max(255, { error: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1137,10 +1061,7 @@ export const zModelWithOneOfAndProperties = z.intersection(z.union([ zSimpleParameter, zNonAsciiStringæøåÆøÅöôêÊ字符串 ]), z.object({ - baz: z.union([ - z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.int().gte(0).max(255, { error: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1154,15 +1075,15 @@ export const zSimpleRequestBody = zModelWithString; export const zSimpleFormData = zModelWithString; export const zExportData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zImportData = z.object({ @@ -1170,8 +1091,8 @@ export const zImportData = z.object({ zModelWithReadOnlyAndWriteOnlyWritable, zModelWithArrayReadOnlyAndWriteOnlyWritable ]), - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); export const zImportResponse = z.union([ @@ -1180,15 +1101,15 @@ export const zImportResponse = z.union([ ]); export const zFooWowData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zApiVVersionODataControllerCountData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -1197,11 +1118,11 @@ export const zApiVVersionODataControllerCountData = z.object({ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ foo_param: z.string() }), - query: z.optional(z.never()) + query: z.never().optional() }); /** @@ -1210,160 +1131,127 @@ export const zGetApiVbyApiVersionSimpleOperationData = z.object({ export const zGetApiVbyApiVersionSimpleOperationResponse = z.number(); export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDeleteFooData3 = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ foo_param: z.string(), BarParam: z.string() }), - query: z.optional(z.never()), + query: z.never().optional(), headers: z.object({ 'x-Foo-Bar': zModelWithString }) }); export const zCallWithDescriptionsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterWithBreaks: z.optional(z.string()), - parameterWithBackticks: z.optional(z.string()), - parameterWithSlashes: z.optional(z.string()), - parameterWithExpressionPlaceholders: z.optional(z.string()), - parameterWithQuotes: z.optional(z.string()), - parameterWithReservedCharacters: z.optional(z.string()) - })) + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterWithBreaks: z.string().optional(), + parameterWithBackticks: z.string().optional(), + parameterWithSlashes: z.string().optional(), + parameterWithExpressionPlaceholders: z.string().optional(), + parameterWithQuotes: z.string().optional(), + parameterWithReservedCharacters: z.string().optional() + }).optional() }); export const zDeprecatedCallData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional(), headers: z.object({ - parameter: z.union([ - zDeprecatedModel, - z.null() - ]) + parameter: zDeprecatedModel.nullable() }) }); export const zCallWithParametersData = z.object({ - body: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + body: z.record(z.string(), z.unknown()).nullable(), path: z.object({ - parameterPath: z.union([ - z.string(), - z.null() - ]), - 'api-version': z.union([ - z.string(), - z.null() - ]) + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }), query: z.object({ - foo_ref_enum: z.optional(zModelWithNestedArrayEnumsDataFoo), + foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.union([ - z.string(), - z.null() - ]) + cursor: z.string().nullable() }), headers: z.object({ - parameterHeader: z.union([ - z.string(), - z.null() - ]) + parameterHeader: z.string().nullable() }) }); export const zCallWithWeirdParameterNamesData = z.object({ - body: z.union([ - zModelWithString, - z.null() - ]), + body: zModelWithString.nullable(), path: z.object({ - 'parameter.path.1': z.optional(z.string()), - 'parameter-path-2': z.optional(z.string()), - 'PARAMETER-PATH-3': z.optional(z.string()), - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string().nullable() }), query: z.object({ - default: z.optional(z.string()), - 'parameter-query': z.union([ - z.string(), - z.null() - ]) + default: z.string().optional(), + 'parameter-query': z.string().nullable() }), headers: z.object({ - 'parameter.header': z.union([ - z.string(), - z.null() - ]) + 'parameter.header': z.string().nullable() }) }); export const zGetCallWithOptionalParamData = z.object({ body: zModelWithOneOfEnum, - path: z.optional(z.never()), - query: z.optional(z.object({ - page: z.optional(z.number()) - })) + path: z.never().optional(), + query: z.object({ + page: z.number().optional() + }).optional() }); export const zPostCallWithOptionalParamData = z.object({ - body: z.optional(z.object({ - offset: z.optional(z.union([ - z.number(), - z.null() - ])) - })), - path: z.optional(z.never()), + body: z.object({ + offset: z.number().nullish() + }).optional(), + path: z.never().optional(), query: z.object({ parameter: zPageable }) @@ -1375,114 +1263,96 @@ export const zPostCallWithOptionalParamResponse = z.union([ ]); export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: z.optional(zSimpleRequestBody), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) + body: zSimpleRequestBody.optional(), + path: z.never().optional(), + query: z.object({ + parameter: z.string().optional() + }).optional() }); export const zPostApiVbyApiVersionFormDataData = z.object({ - body: z.optional(zSimpleFormData), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) + body: zSimpleFormData.optional(), + path: z.never().optional(), + query: z.object({ + parameter: z.string().optional() + }).optional() }); export const zCallWithDefaultParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z.optional(z.union([ - z.string().default('Hello World!'), - z.null() - ])).default('Hello World!'), - parameterNumber: z.optional(z.union([ - z.number().default(123), - z.null() - ])).default(123), - parameterBoolean: z.optional(z.union([ - z.boolean().default(true), - z.null() - ])).default(true), - parameterEnum: z.optional(z.enum([ + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterString: z.string().nullish().default('Hello World!'), + parameterNumber: z.number().nullish().default(123), + parameterBoolean: z.boolean().nullish().default(true), + parameterEnum: z.enum([ 'Success', 'Warning', 'Error' - ])), - parameterModel: z.optional(z.union([ - zModelWithString, - z.null() - ])) - })) + ]).optional(), + parameterModel: zModelWithString.nullish() + }).optional() }); export const zCallWithDefaultOptionalParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z.optional(z.string()).default('Hello World!'), - parameterNumber: z.optional(z.number()).default(123), - parameterBoolean: z.optional(z.boolean()).default(true), - parameterEnum: z.optional(z.enum([ + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterString: z.string().optional().default('Hello World!'), + parameterNumber: z.number().optional().default(123), + parameterBoolean: z.boolean().optional().default(true), + parameterEnum: z.enum([ 'Success', 'Warning', 'Error' - ])), - parameterModel: z.optional(zModelWithString) - })) + ]).optional(), + parameterModel: zModelWithString.optional() + }).optional() }); export const zCallToTestOrderOfParamsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ - parameterOptionalStringWithDefault: z.optional(z.string()).default('Hello World!'), - parameterOptionalStringWithEmptyDefault: z.optional(z.string()).default(''), - parameterOptionalStringWithNoDefault: z.optional(z.string()), + parameterOptionalStringWithDefault: z.string().optional().default('Hello World!'), + parameterOptionalStringWithEmptyDefault: z.string().optional().default(''), + parameterOptionalStringWithNoDefault: z.string().optional(), parameterStringWithDefault: z.string().default('Hello World!'), parameterStringWithEmptyDefault: z.string().default(''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.optional(z.union([ - z.string(), - z.null() - ])), - parameterStringNullableWithDefault: z.optional(z.union([ - z.string(), - z.null() - ])).default(null) + parameterStringNullableWithNoDefault: z.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }) }); export const zDuplicateNameData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName2Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName3Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName4Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -1491,9 +1361,9 @@ export const zCallWithNoContentResponseData = z.object({ export const zCallWithNoContentResponseResponse = z.void(); export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseAndNoContentResponseResponse = z.union([ @@ -1502,17 +1372,17 @@ export const zCallWithResponseAndNoContentResponseResponse = z.union([ ]); export const zDummyAData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDummyAResponse = z400; export const zDummyBData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -1521,17 +1391,17 @@ export const zDummyBData = z.object({ export const zDummyBResponse = z.void(); export const zCallWithResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseResponse = zImport; export const zCallWithDuplicateResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithDuplicateResponsesResponse = z.union([ @@ -1540,75 +1410,45 @@ export const zCallWithDuplicateResponsesResponse = z.union([ ]); export const zCallWithResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponsesResponse = z.union([ z.object({ - '@namespace.string': z.optional(z.string().readonly()), - '@namespace.integer': z.optional(z.int().readonly()), - value: z.optional(z.array(zModelWithString).readonly()) + '@namespace.string': z.string().readonly().optional(), + '@namespace.integer': z.int().readonly().optional(), + value: z.array(zModelWithString).readonly().optional() }), zModelThatExtends, zModelThatExtendsExtends ]); export const zCollectionFormatData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ - parameterArrayCSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArraySSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayTSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayPipes: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayMulti: z.union([ - z.array(z.string()), - z.null() - ]) + parameterArrayCSV: z.array(z.string()).nullable(), + parameterArraySSV: z.array(z.string()).nullable(), + parameterArrayTSV: z.array(z.string()).nullable(), + parameterArrayPipes: z.array(z.string()).nullable(), + parameterArrayMulti: z.array(z.string()).nullable() }) }); export const zTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.object({ - id: z.optional(z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })) - })), + body: z.never().optional(), + path: z.object({ + id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional() + }).optional(), query: z.object({ parameterNumber: z.number().default(123), - parameterString: z.union([ - z.string().default('default'), - z.null() - ]).default('default'), - parameterBoolean: z.union([ - z.boolean().default(true), - z.null() - ]).default(true), - parameterObject: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]).default(null), - parameterArray: z.union([ - z.array(z.string()), - z.null() - ]), - parameterDictionary: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + parameterString: z.string().nullable().default('default'), + parameterBoolean: z.boolean().nullable().default(true), + parameterObject: z.record(z.string(), z.unknown()).nullable().default(null), + parameterArray: z.array(z.string()).nullable(), + parameterDictionary: z.record(z.string(), z.unknown()).nullable(), parameterEnum: z.enum([ 'Success', 'Warning', @@ -1627,23 +1467,20 @@ export const zTypesResponse = z.union([ export const zUploadFileData = z.object({ body: z.string(), path: z.object({ - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.string().nullable() }), - query: z.optional(z.never()) + query: z.never().optional() }); export const zUploadFileResponse = z.boolean(); export const zFileResponseData = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ id: z.string(), 'api-version': z.string() }), - query: z.optional(z.never()) + query: z.never().optional() }); /** @@ -1652,15 +1489,15 @@ export const zFileResponseData = z.object({ export const zFileResponseResponse = z.string(); export const zComplexTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ parameterObject: z.object({ - first: z.optional(z.object({ - second: z.optional(z.object({ - third: z.optional(z.string()) - })) - })) + first: z.object({ + second: z.object({ + third: z.string().optional() + }).optional() + }).optional() }), parameterReference: zModelWithString }) @@ -1672,77 +1509,59 @@ export const zComplexTypesData = z.object({ export const zComplexTypesResponse = z.array(zModelWithString); export const zMultipartResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** * OK */ export const zMultipartResponseResponse = z.object({ - file: z.optional(z.string()), - metadata: z.optional(z.object({ - foo: z.optional(z.string()), - bar: z.optional(z.string()) - })) + file: z.string().optional(), + metadata: z.object({ + foo: z.string().optional(), + bar: z.string().optional() + }).optional() }); export const zMultipartRequestData = z.object({ - body: z.optional(z.object({ - content: z.optional(z.string()), - data: z.optional(z.union([ - zModelWithString, - z.null() - ])) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.object({ + content: z.string().optional(), + data: zModelWithString.nullish() + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zComplexParamsData = z.object({ - body: z.optional(z.object({ - key: z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly(), - z.null() - ]).readonly(), - name: z.union([ - z.string().max(255), - z.null() - ]), - enabled: z.optional(z.boolean()).default(true), + body: z.object({ + key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly().nullable(), + name: z.string().max(255).nullable(), + enabled: z.boolean().optional().default(true), type: z.enum([ 'Monkey', 'Horse', 'Bird' ]), - listOfModels: z.optional(z.union([ - z.array(zModelWithString), - z.null() - ])), - listOfStrings: z.optional(z.union([ - z.array(z.string()), - z.null() - ])), + listOfModels: z.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), parameters: z.union([ zModelWithString, zModelWithEnum, zModelWithArray, zModelWithDictionary ]), - user: z.optional(z.object({ - id: z.optional(z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).readonly()), - name: z.optional(z.union([ - z.string().readonly(), - z.null() - ]).readonly()) - }).readonly()) - })), + user: z.object({ + id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).readonly().optional(), + name: z.string().readonly().nullish() + }).readonly().optional() + }).optional(), path: z.object({ id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }), 'api-version': z.string() }), - query: z.optional(z.never()) + query: z.never().optional() }); /** @@ -1751,22 +1570,22 @@ export const zComplexParamsData = z.object({ export const zComplexParamsResponse = zModelWithString; export const zCallWithResultFromHeaderData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zTestErrorCodeData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ status: z.int() }) }); export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ nonAsciiParamæøåÆØÅöôêÊ: z.int() }) @@ -1779,6 +1598,6 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiS export const zPutWithFormUrlEncodedData = z.object({ body: zArrayWithStrings, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/enum-null/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/enum-null/zod.gen.ts index 75b7a3bf7..991382570 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/enum-null/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/enum-null/zod.gen.ts @@ -2,7 +2,7 @@ import * as z from 'zod'; -export const zFoo = z.nullable(z.enum(['foo', 'bar'])); +export const zFoo = z.enum(['foo', 'bar']).nullable(); export const zBar = z.enum(['foo', 'bar']); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/type-format-zod/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/type-format-zod/zod.gen.ts index b4eb8a8ef..bb1956f79 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/type-format-zod/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/type-format-zod/zod.gen.ts @@ -3,7 +3,7 @@ import * as z from 'zod'; export const zFoo = z.object({ - bar: z.optional(z.int()), + bar: z.int().optional(), foo: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).default(BigInt(0)), id: z.string() }); @@ -13,9 +13,9 @@ export const zBar = z.object({ }); export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/validators/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/validators/zod.gen.ts index d367aa3a1..09932afd1 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/validators/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/validators/zod.gen.ts @@ -4,20 +4,13 @@ import * as z from 'zod'; export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz'); -export const zFoo = z.union([ - z.object({ - foo: z.optional(z.string().regex(/^\d{3}-\d{2}-\d{4}$/)), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z.optional(z.int().gt(0)).default(0) - }), - z.null() -]).default(null); +export const zFoo = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy((): any => zBar).optional(), + baz: z.array(z.lazy((): any => zFoo)).optional(), + qux: z.int().gt(0).optional().default(0) +}).nullable().default(null); export const zBar = z.object({ - foo: z.optional(zFoo) + foo: zFoo.optional() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/default/zod.gen.ts index 5c3ff1e8f..c1347b77d 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/default/zod.gen.ts @@ -81,10 +81,7 @@ export const zSimpleFile = z.string(); /** * This is a simple string */ -export const zSimpleStringWithPattern = z.union([ - z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/)), - z.null() -]); +export const zSimpleStringWithPattern = z.nullable(z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/))); /** * This is a simple enum with strings @@ -180,10 +177,7 @@ export const zArrayWithAnyOfProperties = z.array(z.union([z.object({ })])); export const zAnyOfAnyAndNull = z.object({ - data: z.optional(z.union([ - z.unknown(), - z.null() - ])) + data: z.nullish(z.unknown()) }); /** @@ -282,22 +276,10 @@ export const zModelFromZendesk = z.string(); * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp1: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp1: z.union([ - z.string(), - z.null() - ]), - nullableProp2: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp2: z.union([ - z.string(), - z.null() - ]), + nullableProp1: z.nullish(z.string()), + nullableRequiredProp1: z.nullable(z.string()), + nullableProp2: z.nullish(z.string()), + nullableRequiredProp2: z.nullable(z.string()), 'foo_bar-enum': z.optional(z.enum([ 'Success', 'Warning', @@ -394,9 +376,7 @@ export const zDeprecatedModel = z.object({ * This is a model with one property containing a circular reference */ export const zModelWithCircularReference = z.object({ - get prop() { - return z.optional(z.lazy((): any => zModelWithCircularReference)); - } + prop: z.optional(z.lazy((): any => zModelWithCircularReference)) }); /** @@ -495,24 +475,20 @@ export const zConstValue = z.literal('ConstValue'); * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithNestedAnyOfAndNull = z.object({ - propA: z.optional(z.union([ - z.array(z.union([z3eNum1Период, zConstValue])), - z.null() - ])) + propA: z.nullish(z.array(z.union([z3eNum1Период, zConstValue]))) }); /** * This is a model with one property with a 'one of' relationship */ export const zCompositionWithOneOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.nullish(z.union([ z.object({ boolean: z.optional(z.boolean()) }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() + zModelWithDictionary ])) }); @@ -550,26 +526,22 @@ export const zCompositionWithOneOfAndComplexArrayDictionary = z.object({ * This is a model with one property with a 'all of' relationship */ export const zCompositionWithAllOfAndNullable = z.object({ - propA: z.optional(z.union([ - z.intersection(z.intersection(z.intersection(z.object({ - boolean: z.optional(z.boolean()) - }), zModelWithEnum), zModelWithArray), zModelWithDictionary), - z.null() - ])) + propA: z.nullish(z.intersection(z.intersection(z.intersection(z.object({ + boolean: z.optional(z.boolean()) + }), zModelWithEnum), zModelWithArray), zModelWithDictionary)) }); /** * This is a model with one property with a 'any of' relationship */ export const zCompositionWithAnyOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.nullish(z.union([ z.object({ boolean: z.optional(z.boolean()) }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() + zModelWithDictionary ])) }); @@ -596,10 +568,7 @@ export const zCompositionExtendedModel = z.intersection(zCompositionBaseModel, z export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.readonly(z.string()), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.nullable(z.string()), string: z.optional(z.string()), number: z.optional(z.number()), boolean: z.optional(z.boolean()), @@ -622,20 +591,11 @@ export const zModelWithReference = z.object({ * This is a model with one nested property */ export const zModelWithNestedProperties = z.object({ - first: z.readonly(z.union([ - z.readonly(z.object({ - second: z.readonly(z.union([ - z.readonly(z.object({ - third: z.readonly(z.union([ - z.readonly(z.string()), - z.null() - ])) - })), - z.null() - ])) - })), - z.null() - ])) + first: z.nullable(z.readonly(z.object({ + second: z.nullable(z.readonly(z.object({ + third: z.nullable(z.readonly(z.string())) + }))) + }))) }); /** @@ -742,21 +702,15 @@ export const zModelWithAdditionalPropertiesEqTrue = z.object({ }); export const zNestedAnyOfArraysNullable = z.object({ - nullableArray: z.optional(z.union([ - z.array(z.union([z.string(), z.boolean()])), - z.null() - ])) + nullableArray: z.nullish(z.array(z.union([z.string(), z.boolean()]))) }); /** * An object that can be null */ -export const zNullableObject = z._default(z.union([ - z.object({ - foo: z.optional(z.string()) - }), - z.null() -]), null); +export const zNullableObject = z._default(z.nullable(z.object({ + foo: z.optional(z.string()) +})), null); /** * Some % character @@ -846,21 +800,18 @@ export const zModelWithPrefixItemsConstantSizeArray = z.tuple([ ]); export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([ - z.union([ + z.nullable(z.union([ z.number(), - z.null(), z.string() - ]), - z.union([ + ])), + z.nullable(z.union([ z.number(), - z.null(), z.string() - ]), - z.union([ + ])), + z.nullable(z.union([ z.number(), - z.null(), z.string() - ]) + ])) ]); export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([z.intersection(z.number(), z.string()), z.intersection(z.number(), z.string())]); @@ -979,23 +930,14 @@ export const zAdditionalPropertiesIntegerIssue = z.object({ export const zGenericSchemaDuplicateIssue1SystemBoolean = z.object({ item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), + error: z.nullish(z.string()), hasError: z.optional(z.readonly(z.boolean())), data: z.optional(z.record(z.string(), z.never())) }); export const zGenericSchemaDuplicateIssue1SystemString = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])), + item: z.nullish(z.string()), + error: z.nullish(z.string()), hasError: z.optional(z.readonly(z.boolean())) }); @@ -1027,10 +969,7 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.nullable(z.string()), string: z.optional(z.string()), number: z.optional(z.number()), boolean: z.optional(z.boolean()), @@ -1101,22 +1040,13 @@ export const zOneOfAllOfIssueWritable = z.union([ export const zGenericSchemaDuplicateIssue1SystemBooleanWritable = z.object({ item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), + error: z.nullish(z.string()), data: z.optional(z.record(z.string(), z.never())) }); export const zGenericSchemaDuplicateIssue1SystemStringWritable = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])) + item: z.nullish(z.string()), + error: z.nullish(z.string()) }); /** @@ -1132,10 +1062,7 @@ export const zCompositionWithOneOfAndProperties = z.intersection(z.union([ bar: zNonAsciiStringæøåÆøÅöôêÊ字符串 }) ]), z.object({ - baz: z.union([ - z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' })), - z.null() - ]), + baz: z.nullable(z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }))), qux: z.int().check(z.gte(0), z.maximum(255, { error: 'Invalid value: Expected uint8 to be <= 255' })) })); @@ -1143,10 +1070,7 @@ export const zModelWithOneOfAndProperties = z.intersection(z.union([ zSimpleParameter, zNonAsciiStringæøåÆøÅöôêÊ字符串 ]), z.object({ - baz: z.union([ - z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' })), - z.null() - ]), + baz: z.nullable(z.int().check(z.gte(0), z.maximum(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }))), qux: z.int().check(z.gte(0), z.maximum(255, { error: 'Invalid value: Expected uint8 to be <= 255' })) })); @@ -1296,70 +1220,40 @@ export const zDeprecatedCallData = z.object({ path: z.optional(z.never()), query: z.optional(z.never()), headers: z.object({ - parameter: z.union([ - zDeprecatedModel, - z.null() - ]) + parameter: z.nullable(zDeprecatedModel) }) }); export const zCallWithParametersData = z.object({ - body: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + body: z.nullable(z.record(z.string(), z.unknown())), path: z.object({ - parameterPath: z.union([ - z.string(), - z.null() - ]), - 'api-version': z.union([ - z.string(), - z.null() - ]) + parameterPath: z.nullable(z.string()), + 'api-version': z.nullable(z.string()) }), query: z.object({ foo_ref_enum: z.optional(zModelWithNestedArrayEnumsDataFoo), foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.union([ - z.string(), - z.null() - ]) + cursor: z.nullable(z.string()) }), headers: z.object({ - parameterHeader: z.union([ - z.string(), - z.null() - ]) + parameterHeader: z.nullable(z.string()) }) }); export const zCallWithWeirdParameterNamesData = z.object({ - body: z.union([ - zModelWithString, - z.null() - ]), + body: z.nullable(zModelWithString), path: z.object({ 'parameter.path.1': z.optional(z.string()), 'parameter-path-2': z.optional(z.string()), 'PARAMETER-PATH-3': z.optional(z.string()), - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.nullable(z.string()) }), query: z.object({ default: z.optional(z.string()), - 'parameter-query': z.union([ - z.string(), - z.null() - ]) + 'parameter-query': z.nullable(z.string()) }), headers: z.object({ - 'parameter.header': z.union([ - z.string(), - z.null() - ]) + 'parameter.header': z.nullable(z.string()) }) }); @@ -1373,10 +1267,7 @@ export const zGetCallWithOptionalParamData = z.object({ export const zPostCallWithOptionalParamData = z.object({ body: z.optional(z.object({ - offset: z.optional(z.union([ - z.number(), - z.null() - ])) + offset: z.nullish(z.number()) })), path: z.optional(z.never()), query: z.object({ @@ -1409,27 +1300,15 @@ export const zCallWithDefaultParametersData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), query: z.optional(z.object({ - parameterString: z._default(z.optional(z.union([ - z._default(z.string(), 'Hello World!'), - z.null() - ])), 'Hello World!'), - parameterNumber: z._default(z.optional(z.union([ - z._default(z.number(), 123), - z.null() - ])), 123), - parameterBoolean: z._default(z.optional(z.union([ - z._default(z.boolean(), true), - z.null() - ])), true), + parameterString: z._default(z.nullish(z.string()), 'Hello World!'), + parameterNumber: z._default(z.nullish(z.number()), 123), + parameterBoolean: z._default(z.nullish(z.boolean()), true), parameterEnum: z.optional(z.enum([ 'Success', 'Warning', 'Error' ])), - parameterModel: z.optional(z.union([ - z._default(zModelWithString, { prop: 'Hello World!' }), - z.null() - ])) + parameterModel: z.nullish(zModelWithString) })) }); @@ -1459,14 +1338,8 @@ export const zCallToTestOrderOfParamsData = z.object({ parameterStringWithDefault: z._default(z.string(), 'Hello World!'), parameterStringWithEmptyDefault: z._default(z.string(), ''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.optional(z.union([ - z.string(), - z.null() - ])), - parameterStringNullableWithDefault: z._default(z.optional(z.union([ - z.string(), - z.null() - ])), null) + parameterStringNullableWithNoDefault: z.nullish(z.string()), + parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) }) }); @@ -1574,26 +1447,11 @@ export const zCollectionFormatData = z.object({ body: z.optional(z.never()), path: z.optional(z.never()), query: z.object({ - parameterArrayCSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArraySSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayTSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayPipes: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayMulti: z.union([ - z.array(z.string()), - z.null() - ]) + parameterArrayCSV: z.nullable(z.array(z.string())), + parameterArraySSV: z.nullable(z.array(z.string())), + parameterArrayTSV: z.nullable(z.array(z.string())), + parameterArrayPipes: z.nullable(z.array(z.string())), + parameterArrayMulti: z.nullable(z.array(z.string())) }) }); @@ -1604,32 +1462,16 @@ export const zTypesData = z.object({ })), query: z.object({ parameterNumber: z._default(z.number(), 123), - parameterString: z._default(z.union([ - z._default(z.string(), 'default'), - z.null() - ]), 'default'), - parameterBoolean: z._default(z.union([ - z._default(z.boolean(), true), - z.null() - ]), true), - parameterObject: z._default(z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), null), - parameterArray: z.union([ - z.array(z.string()), - z.null() - ]), - parameterDictionary: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), - parameterEnum: z.union([ + parameterString: z._default(z.nullable(z.string()), 'default'), + parameterBoolean: z._default(z.nullable(z.boolean()), true), + parameterObject: z._default(z.nullable(z.record(z.string(), z.unknown())), null), + parameterArray: z.nullable(z.array(z.string())), + parameterDictionary: z.nullable(z.record(z.string(), z.unknown())), + parameterEnum: z.nullable(z.union([ z.literal('Success'), z.literal('Warning'), - z.literal('Error'), - z.null() - ]) + z.literal('Error') + ])) }) }); @@ -1643,10 +1485,7 @@ export const zTypesResponse = z.union([ export const zUploadFileData = z.object({ body: z.string(), path: z.object({ - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.nullable(z.string()) }), query: z.optional(z.never()) }); @@ -1707,10 +1546,7 @@ export const zMultipartResponseResponse = z.object({ export const zMultipartRequestData = z.object({ body: z.optional(z.object({ content: z.optional(z.string()), - data: z.optional(z.union([ - zModelWithString, - z.null() - ])) + data: z.nullish(zModelWithString) })), path: z.optional(z.never()), query: z.optional(z.never()) @@ -1718,28 +1554,16 @@ export const zMultipartRequestData = z.object({ export const zComplexParamsData = z.object({ body: z.optional(z.object({ - key: z.readonly(z.union([ - z.readonly(z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/))), - z.null() - ])), - name: z.union([ - z.string().check(z.maxLength(255)), - z.null() - ]), + key: z.nullable(z.readonly(z.string().check(z.maxLength(64), z.regex(/^[a-zA-Z0-9_]*$/)))), + name: z.nullable(z.string().check(z.maxLength(255))), enabled: z._default(z.optional(z.boolean()), true), type: z.enum([ 'Monkey', 'Horse', 'Bird' ]), - listOfModels: z.optional(z.union([ - z.array(zModelWithString), - z.null() - ])), - listOfStrings: z.optional(z.union([ - z.array(z.string()), - z.null() - ])), + listOfModels: z.nullish(z.array(zModelWithString)), + listOfStrings: z.nullish(z.array(z.string())), parameters: z.union([ zModelWithString, zModelWithEnum, @@ -1748,10 +1572,7 @@ export const zComplexParamsData = z.object({ ]), user: z.optional(z.readonly(z.object({ id: z.optional(z.readonly(z.int().check(z.minimum(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }), z.maximum(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })))), - name: z.optional(z.readonly(z.union([ - z.readonly(z.string()), - z.null() - ]))) + name: z.nullish(z.readonly(z.string())) }))) })), path: z.object({ diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/defaults-with-ref-and-anyof/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/defaults-with-ref-and-anyof/zod.gen.ts index 108ce0565..94a18b570 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/defaults-with-ref-and-anyof/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/defaults-with-ref-and-anyof/zod.gen.ts @@ -19,16 +19,7 @@ export const zTestSchema = z.object({ primitiveDefault: z._default(z.number(), 42), refWithPrimitiveDefault: z._default(zAudioFormat, 'pcm_16bit_44.1khz'), refWithObjectDefault: z._default(zNestedConfig, { model: 'gpt-4', temperature: 1 }), - anyOfWithNullDefault: z._default(z.union([ - z.number(), - z.null() - ]), null), - anyOfWithRefAndNullDefault: z._default(z.union([ - zLanguage, - z.null() - ]), null), - optionalAnyOfWithDefault: z._default(z.optional(z.union([ - z.string(), - z.null() - ])), null) + anyOfWithNullDefault: z._default(z.nullable(z.number()), null), + anyOfWithRefAndNullDefault: z._default(z.nullable(zLanguage), null), + optionalAnyOfWithDefault: z._default(z.nullish(z.string()), null) }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/enum-resolver-permissive/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/enum-resolver-permissive/zod.gen.ts index 5e88b6e80..c19fb9266 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/enum-resolver-permissive/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/enum-resolver-permissive/zod.gen.ts @@ -2,7 +2,7 @@ import * as z from 'zod/mini'; -export const zFoo = z.union([z.enum(['foo', 'bar']), z.string()]); +export const zFoo = z.nullable(z.union([z.enum(['foo', 'bar']), z.string()])); export const zBar = z.union([z.enum(['foo', 'bar']), z.string()]); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-circular-ref-2/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-circular-ref-2/zod.gen.ts index 6014595af..4a395a61a 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-circular-ref-2/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-circular-ref-2/zod.gen.ts @@ -3,10 +3,7 @@ import * as z from 'zod/mini'; export const zBar = z.object({ - bar: z.union([ - z.array(z.lazy((): any => zBar)), - z.null() - ]) + bar: z.nullable(z.array(z.lazy((): any => zBar))) }); export const zFoo = z.object({ diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-circular-ref/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-circular-ref/zod.gen.ts index ee8b0c76e..3ea103c76 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-circular-ref/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-circular-ref/zod.gen.ts @@ -3,9 +3,7 @@ import * as z from 'zod/mini'; export const zBar = z.object({ - get bar() { - return z.optional(z.array(z.lazy((): any => zBar))); - } + bar: z.optional(z.array(z.lazy((): any => zBar))) }); export const zFoo = z.object({ diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-dates/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-dates/zod.gen.ts index 9ac32990c..47eb9503a 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-dates/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-dates/zod.gen.ts @@ -11,19 +11,12 @@ export const zQux = z.record(z.string(), z.object({ /** * This is Foo schema. */ -export const zFoo = z._default(z.union([ - z.object({ - foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z._default(z.optional(z.int().check(z.gt(0))), 0) - }), - z.null() -]), null); +export const zFoo = z._default(z.nullable(z.object({ + foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), + bar: z.optional(z.lazy((): any => zBar)), + baz: z.optional(z.array(z.lazy((): any => zFoo))), + qux: z._default(z.optional(z.int().check(z.gt(0))), 0) +})), null); /** * This is Bar schema. diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-metadata/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-metadata/zod.gen.ts index e263d218e..004b5e06d 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-metadata/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-metadata/zod.gen.ts @@ -11,25 +11,18 @@ export const zQux = z.record(z.string(), z.object({ /** * This is Foo schema. */ -export const zFoo = z._default(z.union([ - z.object({ - foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/)).register(z.globalRegistry, { - description: 'This is foo property.' - })), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo)).register(z.globalRegistry, { - description: 'This is baz property.' - })); - }, - qux: z._default(z.optional(z.int().check(z.gt(0)).register(z.globalRegistry, { - description: 'This is qux property.' - })), 0) - }), - z.null() -]), null); +export const zFoo = z._default(z.nullable(z.object({ + foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/)).register(z.globalRegistry, { + description: 'This is foo property.' + })), + bar: z.optional(z.lazy((): any => zBar)), + baz: z.optional(z.array(z.lazy((): any => zFoo)).register(z.globalRegistry, { + description: 'This is baz property.' + })), + qux: z._default(z.optional(z.int().check(z.gt(0)).register(z.globalRegistry, { + description: 'This is qux property.' + })), 0) +})), null); /** * This is Bar schema. diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-types/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-types/zod.gen.ts index 669174c0a..e69e527ef 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-types/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-types/zod.gen.ts @@ -15,19 +15,12 @@ export type QuxZodType = z.infer; /** * This is Foo schema. */ -export const zFoo = z._default(z.union([ - z.object({ - foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z._default(z.optional(z.int().check(z.gt(0))), 0) - }), - z.null() -]), null); +export const zFoo = z._default(z.nullable(z.object({ + foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), + bar: z.optional(z.lazy((): any => zBar)), + baz: z.optional(z.array(z.lazy((): any => zFoo))), + qux: z._default(z.optional(z.int().check(z.gt(0))), 0) +})), null); export type FooZodType = z.infer; diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators/zod.gen.ts index b786abd75..3b365dc73 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators/zod.gen.ts @@ -11,19 +11,12 @@ export const zQux = z.record(z.string(), z.object({ /** * This is Foo schema. */ -export const zFoo = z._default(z.union([ - z.object({ - foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z._default(z.optional(z.int().check(z.gt(0))), 0) - }), - z.null() -]), null); +export const zFoo = z._default(z.nullable(z.object({ + foo: z.optional(z.string().check(z.regex(/^\d{3}-\d{2}-\d{4}$/))), + bar: z.optional(z.lazy((): any => zBar)), + baz: z.optional(z.array(z.lazy((): any => zFoo))), + qux: z._default(z.optional(z.int().check(z.gt(0))), 0) +})), null); /** * This is Bar schema. diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/default/zod.gen.ts index 856dbff23..34434e376 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/default/zod.gen.ts @@ -81,10 +81,7 @@ export const zSimpleFile = z.string(); /** * This is a simple string */ -export const zSimpleStringWithPattern = z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), - z.null() -]); +export const zSimpleStringWithPattern = z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).nullable(); /** * This is a simple enum with strings @@ -180,10 +177,7 @@ export const zArrayWithAnyOfProperties = z.array(z.union([z.object({ })])); export const zAnyOfAnyAndNull = z.object({ - data: z.union([ - z.unknown(), - z.null() - ]).optional() + data: z.unknown().nullish() }); /** @@ -282,22 +276,10 @@ export const zModelFromZendesk = z.string(); * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp1: z.union([ - z.string(), - z.null() - ]).optional(), - nullableRequiredProp1: z.union([ - z.string(), - z.null() - ]), - nullableProp2: z.union([ - z.string(), - z.null() - ]).optional(), - nullableRequiredProp2: z.union([ - z.string(), - z.null() - ]), + nullableProp1: z.string().nullish(), + nullableRequiredProp1: z.string().nullable(), + nullableProp2: z.string().nullish(), + nullableRequiredProp2: z.string().nullable(), 'foo_bar-enum': z.enum([ 'Success', 'Warning', @@ -493,10 +475,7 @@ export const zConstValue = z.literal('ConstValue'); * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithNestedAnyOfAndNull = z.object({ - propA: z.union([ - z.array(z.union([z3eNum1Период, zConstValue])), - z.null() - ]).optional() + propA: z.array(z.union([z3eNum1Период, zConstValue])).nullish() }); /** @@ -509,9 +488,8 @@ export const zCompositionWithOneOfAndNullable = z.object({ }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ]).optional() + zModelWithDictionary + ]).nullish() }); /** @@ -548,12 +526,9 @@ export const zCompositionWithOneOfAndComplexArrayDictionary = z.object({ * This is a model with one property with a 'all of' relationship */ export const zCompositionWithAllOfAndNullable = z.object({ - propA: z.union([ - z.object({ - boolean: z.boolean().optional() - }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary), - z.null() - ]).optional() + propA: z.object({ + boolean: z.boolean().optional() + }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary).nullish() }); /** @@ -566,9 +541,8 @@ export const zCompositionWithAnyOfAndNullable = z.object({ }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ]).optional() + zModelWithDictionary + ]).nullish() }); /** @@ -594,10 +568,7 @@ export const zCompositionExtendedModel = zCompositionBaseModel.and(z.object({ export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.string().readonly(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.string().nullable(), string: z.string().optional(), number: z.number().optional(), boolean: z.boolean().optional(), @@ -620,20 +591,11 @@ export const zModelWithReference = z.object({ * This is a model with one nested property */ export const zModelWithNestedProperties = z.object({ - first: z.union([ - z.object({ - second: z.union([ - z.object({ - third: z.union([ - z.string().readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() + first: z.object({ + second: z.object({ + third: z.string().readonly().nullable() + }).readonly().nullable() + }).readonly().nullable() }); /** @@ -740,21 +702,15 @@ export const zModelWithAdditionalPropertiesEqTrue = z.object({ }); export const zNestedAnyOfArraysNullable = z.object({ - nullableArray: z.union([ - z.array(z.union([z.string(), z.boolean()])), - z.null() - ]).optional() + nullableArray: z.array(z.union([z.string(), z.boolean()])).nullish() }); /** * An object that can be null */ -export const zNullableObject = z.union([ - z.object({ - foo: z.string().optional() - }), - z.null() -]).default(null); +export const zNullableObject = z.object({ + foo: z.string().optional() +}).nullable().default(null); /** * Some % character @@ -846,19 +802,16 @@ export const zModelWithPrefixItemsConstantSizeArray = z.tuple([ export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([ z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]) + ]).nullable() ]); export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([z.intersection(z.number(), z.string()), z.intersection(z.number(), z.string())]); @@ -977,23 +930,14 @@ export const zAdditionalPropertiesIntegerIssue = z.object({ export const zGenericSchemaDuplicateIssue1SystemBoolean = z.object({ item: z.boolean().optional(), - error: z.union([ - z.string(), - z.null() - ]).optional(), + error: z.string().nullish(), hasError: z.boolean().readonly().optional(), data: z.record(z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemString = z.object({ - item: z.union([ - z.string(), - z.null() - ]).optional(), - error: z.union([ - z.string(), - z.null() - ]).optional(), + item: z.string().nullish(), + error: z.string().nullish(), hasError: z.boolean().readonly().optional() }); @@ -1025,10 +969,7 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), + requiredAndNullable: z.string().nullable(), string: z.string().optional(), number: z.number().optional(), boolean: z.boolean().optional(), @@ -1099,22 +1040,13 @@ export const zOneOfAllOfIssueWritable = z.union([ export const zGenericSchemaDuplicateIssue1SystemBooleanWritable = z.object({ item: z.boolean().optional(), - error: z.union([ - z.string(), - z.null() - ]).optional(), + error: z.string().nullish(), data: z.record(z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemStringWritable = z.object({ - item: z.union([ - z.string(), - z.null() - ]).optional(), - error: z.union([ - z.string(), - z.null() - ]).optional() + item: z.string().nullish(), + error: z.string().nullish() }); /** @@ -1130,10 +1062,7 @@ export const zCompositionWithOneOfAndProperties = z.intersection(z.union([ bar: zNonAsciiStringæøåÆøÅöôêÊ字符串 }) ]), z.object({ - baz: z.union([ - z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.number().int().gte(0).max(255, { message: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1141,10 +1070,7 @@ export const zModelWithOneOfAndProperties = z.intersection(z.union([ zSimpleParameter, zNonAsciiStringæøåÆøÅöôêÊ字符串 ]), z.object({ - baz: z.union([ - z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.number().int().gte(0).max(65535, { message: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.number().int().gte(0).max(255, { message: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1294,70 +1220,40 @@ export const zDeprecatedCallData = z.object({ path: z.never().optional(), query: z.never().optional(), headers: z.object({ - parameter: z.union([ - zDeprecatedModel, - z.null() - ]) + parameter: zDeprecatedModel.nullable() }) }); export const zCallWithParametersData = z.object({ - body: z.union([ - z.record(z.unknown()), - z.null() - ]), + body: z.record(z.unknown()).nullable(), path: z.object({ - parameterPath: z.union([ - z.string(), - z.null() - ]), - 'api-version': z.union([ - z.string(), - z.null() - ]) + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }), query: z.object({ foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.union([ - z.string(), - z.null() - ]) + cursor: z.string().nullable() }), headers: z.object({ - parameterHeader: z.union([ - z.string(), - z.null() - ]) + parameterHeader: z.string().nullable() }) }); export const zCallWithWeirdParameterNamesData = z.object({ - body: z.union([ - zModelWithString, - z.null() - ]), + body: zModelWithString.nullable(), path: z.object({ 'parameter.path.1': z.string().optional(), 'parameter-path-2': z.string().optional(), 'PARAMETER-PATH-3': z.string().optional(), - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.string().nullable() }), query: z.object({ default: z.string().optional(), - 'parameter-query': z.union([ - z.string(), - z.null() - ]) + 'parameter-query': z.string().nullable() }), headers: z.object({ - 'parameter.header': z.union([ - z.string(), - z.null() - ]) + 'parameter.header': z.string().nullable() }) }); @@ -1371,10 +1267,7 @@ export const zGetCallWithOptionalParamData = z.object({ export const zPostCallWithOptionalParamData = z.object({ body: z.object({ - offset: z.union([ - z.number(), - z.null() - ]).optional() + offset: z.number().nullish() }).optional(), path: z.never().optional(), query: z.object({ @@ -1407,27 +1300,15 @@ export const zCallWithDefaultParametersData = z.object({ body: z.never().optional(), path: z.never().optional(), query: z.object({ - parameterString: z.union([ - z.string().default('Hello World!'), - z.null() - ]).optional().default('Hello World!'), - parameterNumber: z.union([ - z.number().default(123), - z.null() - ]).optional().default(123), - parameterBoolean: z.union([ - z.boolean().default(true), - z.null() - ]).optional().default(true), + parameterString: z.string().nullish().default('Hello World!'), + parameterNumber: z.number().nullish().default(123), + parameterBoolean: z.boolean().nullish().default(true), parameterEnum: z.enum([ 'Success', 'Warning', 'Error' ]).optional(), - parameterModel: z.union([ - zModelWithString.default({ prop: 'Hello World!' }), - z.null() - ]).optional() + parameterModel: zModelWithString.nullish() }).optional() }); @@ -1457,14 +1338,8 @@ export const zCallToTestOrderOfParamsData = z.object({ parameterStringWithDefault: z.string().default('Hello World!'), parameterStringWithEmptyDefault: z.string().default(''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.union([ - z.string(), - z.null() - ]).optional(), - parameterStringNullableWithDefault: z.union([ - z.string(), - z.null() - ]).optional().default(null) + parameterStringNullableWithNoDefault: z.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }) }); @@ -1572,26 +1447,11 @@ export const zCollectionFormatData = z.object({ body: z.never().optional(), path: z.never().optional(), query: z.object({ - parameterArrayCSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArraySSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayTSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayPipes: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayMulti: z.union([ - z.array(z.string()), - z.null() - ]) + parameterArrayCSV: z.array(z.string()).nullable(), + parameterArraySSV: z.array(z.string()).nullable(), + parameterArrayTSV: z.array(z.string()).nullable(), + parameterArrayPipes: z.array(z.string()).nullable(), + parameterArrayMulti: z.array(z.string()).nullable() }) }); @@ -1602,32 +1462,16 @@ export const zTypesData = z.object({ }).optional(), query: z.object({ parameterNumber: z.number().default(123), - parameterString: z.union([ - z.string().default('default'), - z.null() - ]).default('default'), - parameterBoolean: z.union([ - z.boolean().default(true), - z.null() - ]).default(true), - parameterObject: z.union([ - z.record(z.unknown()), - z.null() - ]).default(null), - parameterArray: z.union([ - z.array(z.string()), - z.null() - ]), - parameterDictionary: z.union([ - z.record(z.unknown()), - z.null() - ]), + parameterString: z.string().nullable().default('default'), + parameterBoolean: z.boolean().nullable().default(true), + parameterObject: z.record(z.unknown()).nullable().default(null), + parameterArray: z.array(z.string()).nullable(), + parameterDictionary: z.record(z.unknown()).nullable(), parameterEnum: z.union([ z.literal('Success'), z.literal('Warning'), - z.literal('Error'), - z.null() - ]) + z.literal('Error') + ]).nullable() }) }); @@ -1641,10 +1485,7 @@ export const zTypesResponse = z.union([ export const zUploadFileData = z.object({ body: z.string(), path: z.object({ - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.string().nullable() }), query: z.never().optional() }); @@ -1705,10 +1546,7 @@ export const zMultipartResponseResponse = z.object({ export const zMultipartRequestData = z.object({ body: z.object({ content: z.string().optional(), - data: z.union([ - zModelWithString, - z.null() - ]).optional() + data: zModelWithString.nullish() }).optional(), path: z.never().optional(), query: z.never().optional() @@ -1716,28 +1554,16 @@ export const zMultipartRequestData = z.object({ export const zComplexParamsData = z.object({ body: z.object({ - key: z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly(), - z.null() - ]).readonly(), - name: z.union([ - z.string().max(255), - z.null() - ]), + key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly().nullable(), + name: z.string().max(255).nullable(), enabled: z.boolean().optional().default(true), type: z.enum([ 'Monkey', 'Horse', 'Bird' ]), - listOfModels: z.union([ - z.array(zModelWithString), - z.null() - ]).optional(), - listOfStrings: z.union([ - z.array(z.string()), - z.null() - ]).optional(), + listOfModels: z.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), parameters: z.union([ zModelWithString, zModelWithEnum, @@ -1746,10 +1572,7 @@ export const zComplexParamsData = z.object({ ]), user: z.object({ id: z.number().int().min(-2147483648, { message: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { message: 'Invalid value: Expected int32 to be <= 2147483647' }).readonly().optional(), - name: z.union([ - z.string().readonly(), - z.null() - ]).readonly().optional() + name: z.string().readonly().nullish() }).readonly().optional() }).optional(), path: z.object({ diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/defaults-with-ref-and-anyof/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/defaults-with-ref-and-anyof/zod.gen.ts index 7c2861e7b..7de645541 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/defaults-with-ref-and-anyof/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/defaults-with-ref-and-anyof/zod.gen.ts @@ -19,16 +19,7 @@ export const zTestSchema = z.object({ primitiveDefault: z.number().default(42), refWithPrimitiveDefault: zAudioFormat.default('pcm_16bit_44.1khz'), refWithObjectDefault: zNestedConfig.default({ model: 'gpt-4', temperature: 1 }), - anyOfWithNullDefault: z.union([ - z.number(), - z.null() - ]).default(null), - anyOfWithRefAndNullDefault: z.union([ - zLanguage, - z.null() - ]).default(null), - optionalAnyOfWithDefault: z.union([ - z.string(), - z.null() - ]).optional().default(null) + anyOfWithNullDefault: z.number().nullable().default(null), + anyOfWithRefAndNullDefault: zLanguage.nullable().default(null), + optionalAnyOfWithDefault: z.string().nullish().default(null) }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/enum-resolver-permissive/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/enum-resolver-permissive/zod.gen.ts index ad12dc37a..bfc87fb8a 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/enum-resolver-permissive/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/enum-resolver-permissive/zod.gen.ts @@ -2,7 +2,7 @@ import { z } from 'zod/v3'; -export const zFoo = z.union([z.enum(['foo', 'bar']), z.string()]); +export const zFoo = z.union([z.enum(['foo', 'bar']), z.string()]).nullable(); export const zBar = z.union([z.enum(['foo', 'bar']), z.string()]); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-circular-ref-2/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-circular-ref-2/zod.gen.ts index 4d47e4d61..9b4022d16 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-circular-ref-2/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-circular-ref-2/zod.gen.ts @@ -3,10 +3,7 @@ import { z } from 'zod/v3'; export const zBar: z.AnyZodObject = z.object({ - bar: z.union([ - z.array(z.lazy(() => zBar)), - z.null() - ]) + bar: z.array(z.lazy(() => zBar)).nullable() }); export const zFoo = z.object({ diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-dates/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-dates/zod.gen.ts index 68a0a720f..752d86c56 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-dates/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-dates/zod.gen.ts @@ -11,15 +11,12 @@ export const zQux = z.record(z.object({ /** * This is Foo schema. */ -export const zFoo: z.ZodTypeAny = z.union([ - z.object({ - foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), - bar: z.lazy(() => zBar).optional(), - baz: z.array(z.lazy(() => zFoo)).optional(), - qux: z.number().int().gt(0).optional().default(0) - }), - z.null() -]).default(null); +export const zFoo: z.ZodTypeAny = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy(() => zBar).optional(), + baz: z.array(z.lazy(() => zFoo)).optional(), + qux: z.number().int().gt(0).optional().default(0) +}).nullable().default(null); /** * This is Bar schema. diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-metadata/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-metadata/zod.gen.ts index 10af4babe..4c243e93f 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-metadata/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-metadata/zod.gen.ts @@ -11,15 +11,12 @@ export const zQux = z.record(z.object({ /** * This is Foo schema. */ -export const zFoo: z.ZodTypeAny = z.union([ - z.object({ - foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).describe('This is foo property.').optional(), - bar: z.lazy(() => zBar).optional(), - baz: z.array(z.lazy(() => zFoo)).describe('This is baz property.').optional(), - qux: z.number().int().gt(0).describe('This is qux property.').optional().default(0) - }), - z.null() -]).default(null); +export const zFoo: z.ZodTypeAny = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).describe('This is foo property.').optional(), + bar: z.lazy(() => zBar).optional(), + baz: z.array(z.lazy(() => zFoo)).describe('This is baz property.').optional(), + qux: z.number().int().gt(0).describe('This is qux property.').optional().default(0) +}).nullable().default(null); /** * This is Bar schema. diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-types/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-types/zod.gen.ts index 2b0fa9eed..e2734ee19 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-types/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-types/zod.gen.ts @@ -15,15 +15,12 @@ export type QuxZodType = z.infer; /** * This is Foo schema. */ -export const zFoo: z.ZodTypeAny = z.union([ - z.object({ - foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), - bar: z.lazy(() => zBar).optional(), - baz: z.array(z.lazy(() => zFoo)).optional(), - qux: z.number().int().gt(0).optional().default(0) - }), - z.null() -]).default(null); +export const zFoo: z.ZodTypeAny = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy(() => zBar).optional(), + baz: z.array(z.lazy(() => zFoo)).optional(), + qux: z.number().int().gt(0).optional().default(0) +}).nullable().default(null); export type FooZodType = z.infer; diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators/zod.gen.ts index 15850f6a2..89bcb622f 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators/zod.gen.ts @@ -11,15 +11,12 @@ export const zQux = z.record(z.object({ /** * This is Foo schema. */ -export const zFoo: z.ZodTypeAny = z.union([ - z.object({ - foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), - bar: z.lazy(() => zBar).optional(), - baz: z.array(z.lazy(() => zFoo)).optional(), - qux: z.number().int().gt(0).optional().default(0) - }), - z.null() -]).default(null); +export const zFoo: z.ZodTypeAny = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy(() => zBar).optional(), + baz: z.array(z.lazy(() => zFoo)).optional(), + qux: z.number().int().gt(0).optional().default(0) +}).nullable().default(null); /** * This is Bar schema. diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/array-items-all-of/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/array-items-all-of/zod.gen.ts index 5a58c7fcc..37fd72b6a 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/array-items-all-of/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/array-items-all-of/zod.gen.ts @@ -3,18 +3,18 @@ import * as z from 'zod'; export const zArrayWithAllOfObjects = z.array(z.object({ - id: z.optional(z.int()) + id: z.int().optional() }).and(z.object({ - name: z.optional(z.string()) + name: z.string().optional() }))); export const zArrayWithAllOfPrimitives = z.array(z.intersection(z.number(), z.string())); export const zBaseModel = z.object({ - id: z.optional(z.int()), - createdAt: z.optional(z.iso.datetime()) + id: z.int().optional(), + createdAt: z.iso.datetime().optional() }); export const zArrayWithAllOfRefs = z.array(zBaseModel.and(z.object({ - extra: z.optional(z.string()) + extra: z.string().optional() }))); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/array-items-one-of-length-1/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/array-items-one-of-length-1/zod.gen.ts index d4647f04a..a7e66aa30 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/array-items-one-of-length-1/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/array-items-one-of-length-1/zod.gen.ts @@ -5,5 +5,5 @@ import * as z from 'zod'; export const zBar = z.string(); export const zFoo = z.object({ - foo: z.optional(z.array(zBar).min(1).max(2147483647)) + foo: z.array(zBar).min(1).max(2147483647).optional() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/default/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/default/zod.gen.ts index 559e8c246..242940984 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/default/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/default/zod.gen.ts @@ -81,10 +81,7 @@ export const zSimpleFile = z.string(); /** * This is a simple string */ -export const zSimpleStringWithPattern = z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), - z.null() -]); +export const zSimpleStringWithPattern = z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).nullable(); /** * This is a simple enum with strings @@ -166,35 +163,32 @@ export const zArrayWithStrings = z.array(z.string()).default(['test']); * This is a simple array with properties */ export const zArrayWithProperties = z.array(z.object({ - '16x16': z.optional(zCamelCaseCommentWithBreaks), - bar: z.optional(z.string()) + '16x16': zCamelCaseCommentWithBreaks.optional(), + bar: z.string().optional() })); /** * This is a simple array with any of properties */ export const zArrayWithAnyOfProperties = z.array(z.union([z.object({ - foo: z.optional(z.string()).default('test') + foo: z.string().optional().default('test') }), z.object({ - bar: z.optional(z.string()) + bar: z.string().optional() })])); export const zAnyOfAnyAndNull = z.object({ - data: z.optional(z.union([ - z.unknown(), - z.null() - ])) + data: z.unknown().nullish() }); /** * This is a simple array with any of properties */ export const zAnyOfArrays = z.object({ - results: z.optional(z.array(z.union([z.object({ - foo: z.optional(z.string()) + results: z.array(z.union([z.object({ + foo: z.string().optional() }), z.object({ - bar: z.optional(z.string()) - })]))) + bar: z.string().optional() + })])).optional() }); /** @@ -203,8 +197,8 @@ export const zAnyOfArrays = z.object({ export const zDictionaryWithString = z.record(z.string(), z.string()); export const zDictionaryWithPropertiesAndAdditionalProperties = z.object({ - foo: z.optional(z.number()), - bar: z.optional(z.boolean()) + foo: z.number().optional(), + bar: z.boolean().optional() }); /** @@ -216,29 +210,29 @@ export const zDictionaryWithDictionary = z.record(z.string(), z.record(z.string( * This is a complex dictionary */ export const zDictionaryWithProperties = z.record(z.string(), z.object({ - foo: z.optional(z.string()), - bar: z.optional(z.string()) + foo: z.string().optional(), + bar: z.string().optional() })); /** * This is a model with one number property */ export const zModelWithInteger = z.object({ - prop: z.optional(z.int()) + prop: z.int().optional() }); /** * This is a model with one boolean property */ export const zModelWithBoolean = z.object({ - prop: z.optional(z.boolean()) + prop: z.boolean().optional() }); /** * This is a model with one string property */ export const zModelWithString = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** @@ -270,7 +264,7 @@ export const zDictionaryWithArray = z.record(z.string(), z.array(zModelWithStrin * This is a model with one string property */ export const zModelWithStringError = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** @@ -282,103 +276,91 @@ export const zModelFromZendesk = z.string(); * This is a model with one string property */ export const zModelWithNullableString = z.object({ - nullableProp1: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp1: z.union([ - z.string(), - z.null() - ]), - nullableProp2: z.optional(z.union([ - z.string(), - z.null() - ])), - nullableRequiredProp2: z.union([ - z.string(), - z.null() - ]), - 'foo_bar-enum': z.optional(z.enum([ + nullableProp1: z.string().nullish(), + nullableRequiredProp1: z.string().nullable(), + nullableProp2: z.string().nullish(), + nullableRequiredProp2: z.string().nullable(), + 'foo_bar-enum': z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])) + ]).optional() }); /** * This is a model with one enum */ export const zModelWithEnum = z.object({ - 'foo_bar-enum': z.optional(z.enum([ + 'foo_bar-enum': z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])), - statusCode: z.optional(z.enum([ + ]).optional(), + statusCode: z.enum([ '100', '200 FOO', '300 FOO_BAR', '400 foo-bar', '500 foo.bar', '600 foo&bar' - ])), - bool: z.optional(z.literal(true)) + ]).optional(), + bool: z.literal(true).optional() }); /** * This is a model with one enum with escaped name */ export const zModelWithEnumWithHyphen = z.object({ - 'foo-bar-baz-qux': z.optional(z.enum(['3.0'])) + 'foo-bar-baz-qux': z.enum(['3.0']).optional() }); /** * This is a model with one enum */ export const zModelWithEnumFromDescription = z.object({ - test: z.optional(z.int()) + test: z.int().optional() }); /** * This is a model with nested enums */ export const zModelWithNestedEnums = z.object({ - dictionaryWithEnum: z.optional(z.record(z.string(), z.enum([ + dictionaryWithEnum: z.record(z.string(), z.enum([ 'Success', 'Warning', 'Error' - ]))), - dictionaryWithEnumFromDescription: z.optional(z.record(z.string(), z.int())), - arrayWithEnum: z.optional(z.array(z.enum([ + ])).optional(), + dictionaryWithEnumFromDescription: z.record(z.string(), z.int()).optional(), + arrayWithEnum: z.array(z.enum([ 'Success', 'Warning', 'Error' - ]))), - arrayWithDescription: z.optional(z.array(z.int())), - 'foo_bar-enum': z.optional(z.enum([ + ])).optional(), + arrayWithDescription: z.array(z.int()).optional(), + 'foo_bar-enum': z.enum([ 'Success', 'Warning', 'Error', 'ØÆÅ字符串' - ])) + ]).optional() }); /** * This is a model with one property containing an array */ export const zModelWithArray = z.object({ - prop: z.optional(z.array(zModelWithString)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithString).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); /** * This is a model with one property containing a dictionary */ export const zModelWithDictionary = z.object({ - prop: z.optional(z.record(z.string(), z.string())) + prop: z.record(z.string(), z.string()).optional() }); /** @@ -387,41 +369,39 @@ export const zModelWithDictionary = z.object({ * @deprecated */ export const zDeprecatedModel = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); /** * This is a model with one property containing a circular reference */ export const zModelWithCircularReference = z.object({ - get prop() { - return z.optional(z.lazy((): any => zModelWithCircularReference)); - } + prop: z.lazy((): any => zModelWithCircularReference).optional() }); /** * This is a model with one property with a 'one of' relationship */ export const zCompositionWithOneOf = z.object({ - propA: z.optional(z.union([ + propA: z.union([ zModelWithString, zModelWithEnum, zModelWithArray, zModelWithDictionary - ])) + ]).optional() }); /** * This is a model with one property with a 'one of' relationship where the options are not $ref */ export const zCompositionWithOneOfAnonymous = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - propA: z.optional(z.string()) + propA: z.string().optional() }), z.string(), z.int() - ])) + ]).optional() }); /** @@ -429,7 +409,7 @@ export const zCompositionWithOneOfAnonymous = z.object({ */ export const zModelCircle = z.object({ kind: z.string(), - radius: z.optional(z.number()) + radius: z.number().optional() }); /** @@ -437,7 +417,7 @@ export const zModelCircle = z.object({ */ export const zModelSquare = z.object({ kind: z.string(), - sideLength: z.optional(z.number()) + sideLength: z.number().optional() }); /** @@ -456,35 +436,35 @@ export const zCompositionWithOneOfDiscriminator = z.union([ * This is a model with one property with a 'any of' relationship */ export const zCompositionWithAnyOf = z.object({ - propA: z.optional(z.union([ + propA: z.union([ zModelWithString, zModelWithEnum, zModelWithArray, zModelWithDictionary - ])) + ]).optional() }); /** * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithAnyOfAnonymous = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - propA: z.optional(z.string()) + propA: z.string().optional() }), z.string(), z.int() - ])) + ]).optional() }); /** * This is a model with nested 'any of' property with a type null */ export const zCompositionWithNestedAnyAndTypeNull = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.array(z.union([zModelWithDictionary, z.null()])), z.array(z.union([zModelWithArray, z.null()])) - ])) + ]).optional() }); export const z3eNum1Период = z.enum(['Bird', 'Dog']); @@ -495,90 +475,82 @@ export const zConstValue = z.literal('ConstValue'); * This is a model with one property with a 'any of' relationship where the options are not $ref */ export const zCompositionWithNestedAnyOfAndNull = z.object({ - propA: z.optional(z.union([ - z.array(z.union([z3eNum1Период, zConstValue])), - z.null() - ])) + propA: z.array(z.union([z3eNum1Период, zConstValue])).nullish() }); /** * This is a model with one property with a 'one of' relationship */ export const zCompositionWithOneOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - boolean: z.optional(z.boolean()) + boolean: z.boolean().optional() }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ])) + zModelWithDictionary + ]).nullish() }); /** * This is a model that contains a simple dictionary within composition */ export const zCompositionWithOneOfAndSimpleDictionary = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.boolean(), z.record(z.string(), z.number()) - ])) + ]).optional() }); /** * This is a model that contains a dictionary of simple arrays within composition */ export const zCompositionWithOneOfAndSimpleArrayDictionary = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.boolean(), z.record(z.string(), z.array(z.boolean())) - ])) + ]).optional() }); /** * This is a model that contains a dictionary of complex arrays (composited) within composition */ export const zCompositionWithOneOfAndComplexArrayDictionary = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.boolean(), z.record(z.string(), z.array(z.union([z.number(), z.string()]))) - ])) + ]).optional() }); /** * This is a model with one property with a 'all of' relationship */ export const zCompositionWithAllOfAndNullable = z.object({ - propA: z.optional(z.union([ - z.object({ - boolean: z.optional(z.boolean()) - }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary), - z.null() - ])) + propA: z.object({ + boolean: z.boolean().optional() + }).and(zModelWithEnum).and(zModelWithArray).and(zModelWithDictionary).nullish() }); /** * This is a model with one property with a 'any of' relationship */ export const zCompositionWithAnyOfAndNullable = z.object({ - propA: z.optional(z.union([ + propA: z.union([ z.object({ - boolean: z.optional(z.boolean()) + boolean: z.boolean().optional() }), zModelWithEnum, zModelWithArray, - zModelWithDictionary, - z.null() - ])) + zModelWithDictionary + ]).nullish() }); /** * This is a base model with two simple optional properties */ export const zCompositionBaseModel = z.object({ - firstName: z.optional(z.string()), - lastname: z.optional(z.string()) + firstName: z.string().optional(), + lastname: z.string().optional() }); /** @@ -596,87 +568,75 @@ export const zCompositionExtendedModel = zCompositionBaseModel.and(z.object({ export const zModelWithProperties = z.object({ required: z.string(), requiredAndReadOnly: z.string().readonly(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), - string: z.optional(z.string()), - number: z.optional(z.number()), - boolean: z.optional(z.boolean()), - reference: z.optional(zModelWithString), - 'property with space': z.optional(z.string()), - default: z.optional(z.string()), - try: z.optional(z.string()), - '@namespace.string': z.optional(z.string().readonly()), - '@namespace.integer': z.optional(z.int().readonly()) + requiredAndNullable: z.string().nullable(), + string: z.string().optional(), + number: z.number().optional(), + boolean: z.boolean().optional(), + reference: zModelWithString.optional(), + 'property with space': z.string().optional(), + default: z.string().optional(), + try: z.string().optional(), + '@namespace.string': z.string().readonly().optional(), + '@namespace.integer': z.int().readonly().optional() }); /** * This is a model with one property containing a reference */ export const zModelWithReference = z.object({ - prop: z.optional(zModelWithProperties) + prop: zModelWithProperties.optional() }); /** * This is a model with one nested property */ export const zModelWithNestedProperties = z.object({ - first: z.union([ - z.object({ - second: z.union([ - z.object({ - third: z.union([ - z.string().readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() - }).readonly(), - z.null() - ]).readonly() + first: z.object({ + second: z.object({ + third: z.string().readonly().nullable() + }).readonly().nullable() + }).readonly().nullable() }); /** * This is a model with duplicated properties */ export const zModelWithDuplicateProperties = z.object({ - prop: z.optional(zModelWithString) + prop: zModelWithString.optional() }); /** * This is a model with ordered properties */ export const zModelWithOrderedProperties = z.object({ - zebra: z.optional(z.string()), - apple: z.optional(z.string()), - hawaii: z.optional(z.string()) + zebra: z.string().optional(), + apple: z.string().optional(), + hawaii: z.string().optional() }); /** * This is a model with duplicated imports */ export const zModelWithDuplicateImports = z.object({ - propA: z.optional(zModelWithString), - propB: z.optional(zModelWithString), - propC: z.optional(zModelWithString) + propA: zModelWithString.optional(), + propB: zModelWithString.optional(), + propC: zModelWithString.optional() }); /** * This is a model that extends another model */ export const zModelThatExtends = zModelWithString.and(z.object({ - propExtendsA: z.optional(z.string()), - propExtendsB: z.optional(zModelWithString) + propExtendsA: z.string().optional(), + propExtendsB: zModelWithString.optional() })); /** * This is a model that extends another model */ export const zModelThatExtendsExtends = zModelWithString.and(zModelThatExtends).and(z.object({ - propExtendsC: z.optional(z.string()), - propExtendsD: z.optional(zModelWithString) + propExtendsC: z.string().optional(), + propExtendsD: zModelWithString.optional() })); /** @@ -685,31 +645,31 @@ export const zModelThatExtendsExtends = zModelWithString.and(zModelThatExtends). export const zModelWithPattern = z.object({ key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), name: z.string().max(255), - enabled: z.optional(z.boolean().readonly()), - modified: z.optional(z.iso.datetime().readonly()), - id: z.optional(z.string().regex(/^\d{2}-\d{3}-\d{4}$/)), - text: z.optional(z.string().regex(/^\w+$/)), - patternWithSingleQuotes: z.optional(z.string().regex(/^[a-zA-Z0-9']*$/)), - patternWithNewline: z.optional(z.string().regex(/aaa\nbbb/)), - patternWithBacktick: z.optional(z.string().regex(/aaa`bbb/)) + enabled: z.boolean().readonly().optional(), + modified: z.iso.datetime().readonly().optional(), + id: z.string().regex(/^\d{2}-\d{3}-\d{4}$/).optional(), + text: z.string().regex(/^\w+$/).optional(), + patternWithSingleQuotes: z.string().regex(/^[a-zA-Z0-9']*$/).optional(), + patternWithNewline: z.string().regex(/aaa\nbbb/).optional(), + patternWithBacktick: z.string().regex(/aaa`bbb/).optional() }); export const zFile = z.object({ - id: z.optional(z.string().min(1).readonly()), - updated_at: z.optional(z.iso.datetime().readonly()), - created_at: z.optional(z.iso.datetime().readonly()), + id: z.string().min(1).readonly().optional(), + updated_at: z.iso.datetime().readonly().optional(), + created_at: z.iso.datetime().readonly().optional(), mime: z.string().min(1).max(24), - file: z.optional(z.url().readonly()) + file: z.url().readonly().optional() }); export const zDefault = z.object({ - name: z.optional(z.string()) + name: z.string().optional() }); export const zPageable = z.object({ - page: z.optional(z.int().gte(0).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })).default(0), - size: z.optional(z.int().gte(1).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })), - sort: z.optional(z.array(z.string())) + page: z.int().gte(0).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional().default(0), + size: z.int().gte(1).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional(), + sort: z.array(z.string()).optional() }); /** @@ -728,35 +688,29 @@ export const zFreeFormObjectWithAdditionalPropertiesEqTrue = z.record(z.string() export const zFreeFormObjectWithAdditionalPropertiesEqEmptyObject = z.record(z.string(), z.unknown()); export const zModelWithConst = z.object({ - String: z.optional(z.literal('String')), - number: z.optional(z.literal(0)), - null: z.optional(z.null()), - withType: z.optional(z.literal('Some string')) + String: z.literal('String').optional(), + number: z.literal(0).optional(), + null: z.null().optional(), + withType: z.literal('Some string').optional() }); /** * This is a model with one property and additionalProperties: true */ export const zModelWithAdditionalPropertiesEqTrue = z.object({ - prop: z.optional(z.string()) + prop: z.string().optional() }); export const zNestedAnyOfArraysNullable = z.object({ - nullableArray: z.optional(z.union([ - z.array(z.union([z.string(), z.boolean()])), - z.null() - ])) + nullableArray: z.array(z.union([z.string(), z.boolean()])).nullish() }); /** * An object that can be null */ -export const zNullableObject = z.union([ - z.object({ - foo: z.optional(z.string()) - }), - z.null() -]).default(null); +export const zNullableObject = z.object({ + foo: z.string().optional() +}).nullable().default(null); /** * Some % character @@ -764,7 +718,7 @@ export const zNullableObject = z.union([ export const zCharactersInDescription = z.string(); export const zModelWithNullableObject = z.object({ - data: z.optional(zNullableObject) + data: zNullableObject.optional() }); export const zModelWithOneOfEnum = z.union([ @@ -792,17 +746,17 @@ export const zModelWithNestedArrayEnumsDataFoo = z.enum(['foo', 'bar']); export const zModelWithNestedArrayEnumsDataBar = z.enum(['baz', 'qux']); export const zModelWithNestedArrayEnumsData = z.object({ - foo: z.optional(z.array(zModelWithNestedArrayEnumsDataFoo)), - bar: z.optional(z.array(zModelWithNestedArrayEnumsDataBar)) + foo: z.array(zModelWithNestedArrayEnumsDataFoo).optional(), + bar: z.array(zModelWithNestedArrayEnumsDataBar).optional() }); export const zModelWithNestedArrayEnums = z.object({ - array_strings: z.optional(z.array(z.string())), - data: z.optional(zModelWithNestedArrayEnumsData) + array_strings: z.array(z.string()).optional(), + data: zModelWithNestedArrayEnumsData.optional() }); export const zModelWithNestedCompositionEnums = z.object({ - foo: z.optional(zModelWithNestedArrayEnumsDataFoo) + foo: zModelWithNestedArrayEnumsDataFoo.optional() }); export const zModelWithReadOnlyAndWriteOnly = z.object({ @@ -814,9 +768,9 @@ export const zModelWithReadOnlyAndWriteOnly = z.object({ * This is a model with one property containing an array */ export const zModelWithArrayReadOnlyAndWriteOnly = z.object({ - prop: z.optional(z.array(zModelWithReadOnlyAndWriteOnly)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithReadOnlyAndWriteOnly).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); export const zModelWithConstantSizeArray = z.tuple([z.number(), z.number()]); @@ -848,25 +802,22 @@ export const zModelWithPrefixItemsConstantSizeArray = z.tuple([ export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([ z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]), + ]).nullable(), z.union([ z.number(), - z.null(), z.string() - ]) + ]).nullable() ]); export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([z.intersection(z.number(), z.string()), z.intersection(z.number(), z.string())]); export const zModelWithNumericEnumUnion = z.object({ - value: z.optional(z.union([ + value: z.union([ z.literal(-10), z.literal(-1), z.literal(0), @@ -874,14 +825,14 @@ export const zModelWithNumericEnumUnion = z.object({ z.literal(3), z.literal(6), z.literal(12) - ])) + ]).optional() }); /** * Some description with `back ticks` */ export const zModelWithBackticksInDescription = z.object({ - template: z.optional(z.string()) + template: z.string().optional() }); /** @@ -923,40 +874,40 @@ export const zModelWithAnyOfConstantSizeArrayWithNSizeAndOptions = z.tuple([z.un ])]); export const zSchemaWithFormRestrictedKeys = z.object({ - description: z.optional(z.string()), - 'x-enum-descriptions': z.optional(z.string()), - 'x-enum-varnames': z.optional(z.string()), - 'x-enumNames': z.optional(z.string()), - title: z.optional(z.string()), - object: z.optional(z.object({ - description: z.optional(z.string()), - 'x-enum-descriptions': z.optional(z.string()), - 'x-enum-varnames': z.optional(z.string()), - 'x-enumNames': z.optional(z.string()), - title: z.optional(z.string()) - })), - array: z.optional(z.array(z.object({ - description: z.optional(z.string()), - 'x-enum-descriptions': z.optional(z.string()), - 'x-enum-varnames': z.optional(z.string()), - 'x-enumNames': z.optional(z.string()), - title: z.optional(z.string()) - }))) + description: z.string().optional(), + 'x-enum-descriptions': z.string().optional(), + 'x-enum-varnames': z.string().optional(), + 'x-enumNames': z.string().optional(), + title: z.string().optional(), + object: z.object({ + description: z.string().optional(), + 'x-enum-descriptions': z.string().optional(), + 'x-enum-varnames': z.string().optional(), + 'x-enumNames': z.string().optional(), + title: z.string().optional() + }).optional(), + array: z.array(z.object({ + description: z.string().optional(), + 'x-enum-descriptions': z.string().optional(), + 'x-enum-varnames': z.string().optional(), + 'x-enumNames': z.string().optional(), + title: z.string().optional() + })).optional() }); /** * This schema was giving PascalCase transformations a hard time */ export const zIoK8sApimachineryPkgApisMetaV1Preconditions = z.object({ - resourceVersion: z.optional(z.string()), - uid: z.optional(z.string()) + resourceVersion: z.string().optional(), + uid: z.string().optional() }); /** * This schema was giving PascalCase transformations a hard time */ export const zIoK8sApimachineryPkgApisMetaV1DeleteOptions = z.object({ - preconditions: z.optional(zIoK8sApimachineryPkgApisMetaV1Preconditions) + preconditions: zIoK8sApimachineryPkgApisMetaV1Preconditions.optional() }); export const zAdditionalPropertiesUnknownIssue = z.record(z.string(), z.union([ @@ -978,25 +929,16 @@ export const zAdditionalPropertiesIntegerIssue = z.object({ }); export const zGenericSchemaDuplicateIssue1SystemBoolean = z.object({ - item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), - hasError: z.optional(z.boolean().readonly()), - data: z.optional(z.record(z.string(), z.never())) + item: z.boolean().optional(), + error: z.string().nullish(), + hasError: z.boolean().readonly().optional(), + data: z.record(z.string(), z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemString = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])), - hasError: z.optional(z.boolean().readonly()) + item: z.string().nullish(), + error: z.string().nullish(), + hasError: z.boolean().readonly().optional() }); export const zOneOfAllOfIssue = z.union([ @@ -1009,7 +951,7 @@ export const zOneOfAllOfIssue = z.union([ export const zExternalSharedExternalSharedModel = z.object({ id: z.string(), - name: z.optional(z.string()) + name: z.string().optional() }); /** @@ -1027,24 +969,21 @@ export const zExternalRefB = zExternalSharedExternalSharedModel; */ export const zModelWithPropertiesWritable = z.object({ required: z.string(), - requiredAndNullable: z.union([ - z.string(), - z.null() - ]), - string: z.optional(z.string()), - number: z.optional(z.number()), - boolean: z.optional(z.boolean()), - reference: z.optional(zModelWithString), - 'property with space': z.optional(z.string()), - default: z.optional(z.string()), - try: z.optional(z.string()) + requiredAndNullable: z.string().nullable(), + string: z.string().optional(), + number: z.number().optional(), + boolean: z.boolean().optional(), + reference: zModelWithString.optional(), + 'property with space': z.string().optional(), + default: z.string().optional(), + try: z.string().optional() }); /** * This is a model with one property containing a reference */ export const zModelWithReferenceWritable = z.object({ - prop: z.optional(zModelWithPropertiesWritable) + prop: zModelWithPropertiesWritable.optional() }); /** @@ -1053,11 +992,11 @@ export const zModelWithReferenceWritable = z.object({ export const zModelWithPatternWritable = z.object({ key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/), name: z.string().max(255), - id: z.optional(z.string().regex(/^\d{2}-\d{3}-\d{4}$/)), - text: z.optional(z.string().regex(/^\w+$/)), - patternWithSingleQuotes: z.optional(z.string().regex(/^[a-zA-Z0-9']*$/)), - patternWithNewline: z.optional(z.string().regex(/aaa\nbbb/)), - patternWithBacktick: z.optional(z.string().regex(/aaa`bbb/)) + id: z.string().regex(/^\d{2}-\d{3}-\d{4}$/).optional(), + text: z.string().regex(/^\w+$/).optional(), + patternWithSingleQuotes: z.string().regex(/^[a-zA-Z0-9']*$/).optional(), + patternWithNewline: z.string().regex(/aaa\nbbb/).optional(), + patternWithBacktick: z.string().regex(/aaa`bbb/).optional() }); export const zFileWritable = z.object({ @@ -1073,9 +1012,9 @@ export const zModelWithReadOnlyAndWriteOnlyWritable = z.object({ * This is a model with one property containing an array */ export const zModelWithArrayReadOnlyAndWriteOnlyWritable = z.object({ - prop: z.optional(z.array(zModelWithReadOnlyAndWriteOnlyWritable)), - propWithFile: z.optional(z.array(z.string())), - propWithNumber: z.optional(z.array(z.number())) + prop: z.array(zModelWithReadOnlyAndWriteOnlyWritable).optional(), + propWithFile: z.array(z.string()).optional(), + propWithNumber: z.array(z.number()).optional() }); export const zModelWithAnyOfConstantSizeArrayWithNSizeAndOptionsWritable = z.tuple([z.union([ @@ -1100,23 +1039,14 @@ export const zOneOfAllOfIssueWritable = z.union([ ]); export const zGenericSchemaDuplicateIssue1SystemBooleanWritable = z.object({ - item: z.optional(z.boolean()), - error: z.optional(z.union([ - z.string(), - z.null() - ])), - data: z.optional(z.record(z.string(), z.never())) + item: z.boolean().optional(), + error: z.string().nullish(), + data: z.record(z.string(), z.never()).optional() }); export const zGenericSchemaDuplicateIssue1SystemStringWritable = z.object({ - item: z.optional(z.union([ - z.string(), - z.null() - ])), - error: z.optional(z.union([ - z.string(), - z.null() - ])) + item: z.string().nullish(), + error: z.string().nullish() }); /** @@ -1132,10 +1062,7 @@ export const zCompositionWithOneOfAndProperties = z.intersection(z.union([ bar: zNonAsciiStringæøåÆøÅöôêÊ字符串 }) ]), z.object({ - baz: z.union([ - z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.int().gte(0).max(255, { error: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1143,10 +1070,7 @@ export const zModelWithOneOfAndProperties = z.intersection(z.union([ zSimpleParameter, zNonAsciiStringæøåÆøÅöôêÊ字符串 ]), z.object({ - baz: z.union([ - z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }), - z.null() - ]), + baz: z.int().gte(0).max(65535, { error: 'Invalid value: Expected uint16 to be <= 65535' }).nullable(), qux: z.int().gte(0).max(255, { error: 'Invalid value: Expected uint8 to be <= 255' }) })); @@ -1166,15 +1090,15 @@ export const zSimpleRequestBody = zModelWithString; export const zSimpleFormData = zModelWithString; export const zExportData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zImportData = z.object({ @@ -1182,8 +1106,8 @@ export const zImportData = z.object({ zModelWithReadOnlyAndWriteOnlyWritable, zModelWithArrayReadOnlyAndWriteOnlyWritable ]), - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); export const zImportResponse = z.union([ @@ -1192,15 +1116,15 @@ export const zImportResponse = z.union([ ]); export const zFooWowData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zApiVVersionODataControllerCountData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -1209,14 +1133,14 @@ export const zApiVVersionODataControllerCountData = z.object({ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ foo_param: z.union([ z.string(), z.uuid() ]) }), - query: z.optional(z.never()) + query: z.never().optional() }); /** @@ -1225,160 +1149,127 @@ export const zGetApiVbyApiVersionSimpleOperationData = z.object({ export const zGetApiVbyApiVersionSimpleOperationResponse = z.number(); export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDeleteFooData3 = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ foo_param: z.string(), BarParam: z.string() }), - query: z.optional(z.never()), + query: z.never().optional(), headers: z.object({ 'x-Foo-Bar': zModelWithString }) }); export const zCallWithDescriptionsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterWithBreaks: z.optional(z.string()), - parameterWithBackticks: z.optional(z.string()), - parameterWithSlashes: z.optional(z.string()), - parameterWithExpressionPlaceholders: z.optional(z.string()), - parameterWithQuotes: z.optional(z.string()), - parameterWithReservedCharacters: z.optional(z.string()) - })) + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterWithBreaks: z.string().optional(), + parameterWithBackticks: z.string().optional(), + parameterWithSlashes: z.string().optional(), + parameterWithExpressionPlaceholders: z.string().optional(), + parameterWithQuotes: z.string().optional(), + parameterWithReservedCharacters: z.string().optional() + }).optional() }); export const zDeprecatedCallData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional(), headers: z.object({ - parameter: z.union([ - zDeprecatedModel, - z.null() - ]) + parameter: zDeprecatedModel.nullable() }) }); export const zCallWithParametersData = z.object({ - body: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + body: z.record(z.string(), z.unknown()).nullable(), path: z.object({ - parameterPath: z.union([ - z.string(), - z.null() - ]), - 'api-version': z.union([ - z.string(), - z.null() - ]) + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }), query: z.object({ - foo_ref_enum: z.optional(zModelWithNestedArrayEnumsDataFoo), + foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.union([ - z.string(), - z.null() - ]) + cursor: z.string().nullable() }), headers: z.object({ - parameterHeader: z.union([ - z.string(), - z.null() - ]) + parameterHeader: z.string().nullable() }) }); export const zCallWithWeirdParameterNamesData = z.object({ - body: z.union([ - zModelWithString, - z.null() - ]), + body: zModelWithString.nullable(), path: z.object({ - 'parameter.path.1': z.optional(z.string()), - 'parameter-path-2': z.optional(z.string()), - 'PARAMETER-PATH-3': z.optional(z.string()), - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string().nullable() }), query: z.object({ - default: z.optional(z.string()), - 'parameter-query': z.union([ - z.string(), - z.null() - ]) + default: z.string().optional(), + 'parameter-query': z.string().nullable() }), headers: z.object({ - 'parameter.header': z.union([ - z.string(), - z.null() - ]) + 'parameter.header': z.string().nullable() }) }); export const zGetCallWithOptionalParamData = z.object({ body: zModelWithOneOfEnum, - path: z.optional(z.never()), - query: z.optional(z.object({ - page: z.optional(z.number()) - })) + path: z.never().optional(), + query: z.object({ + page: z.number().optional() + }).optional() }); export const zPostCallWithOptionalParamData = z.object({ - body: z.optional(z.object({ - offset: z.optional(z.union([ - z.number(), - z.null() - ])) - })), - path: z.optional(z.never()), + body: z.object({ + offset: z.number().nullish() + }).optional(), + path: z.never().optional(), query: z.object({ parameter: zPageable }) @@ -1390,114 +1281,96 @@ export const zPostCallWithOptionalParamResponse = z.union([ ]); export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: z.optional(zSimpleRequestBody), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) + body: zSimpleRequestBody.optional(), + path: z.never().optional(), + query: z.object({ + parameter: z.string().optional() + }).optional() }); export const zPostApiVbyApiVersionFormDataData = z.object({ - body: z.optional(zSimpleFormData), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) + body: zSimpleFormData.optional(), + path: z.never().optional(), + query: z.object({ + parameter: z.string().optional() + }).optional() }); export const zCallWithDefaultParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z.optional(z.union([ - z.string().default('Hello World!'), - z.null() - ])).default('Hello World!'), - parameterNumber: z.optional(z.union([ - z.number().default(123), - z.null() - ])).default(123), - parameterBoolean: z.optional(z.union([ - z.boolean().default(true), - z.null() - ])).default(true), - parameterEnum: z.optional(z.enum([ + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterString: z.string().nullish().default('Hello World!'), + parameterNumber: z.number().nullish().default(123), + parameterBoolean: z.boolean().nullish().default(true), + parameterEnum: z.enum([ 'Success', 'Warning', 'Error' - ])), - parameterModel: z.optional(z.union([ - zModelWithString.default({ prop: 'Hello World!' }), - z.null() - ])) - })) + ]).optional(), + parameterModel: zModelWithString.nullish() + }).optional() }); export const zCallWithDefaultOptionalParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z.optional(z.string()).default('Hello World!'), - parameterNumber: z.optional(z.number()).default(123), - parameterBoolean: z.optional(z.boolean()).default(true), - parameterEnum: z.optional(z.enum([ + body: z.never().optional(), + path: z.never().optional(), + query: z.object({ + parameterString: z.string().optional().default('Hello World!'), + parameterNumber: z.number().optional().default(123), + parameterBoolean: z.boolean().optional().default(true), + parameterEnum: z.enum([ 'Success', 'Warning', 'Error' - ])), - parameterModel: z.optional(zModelWithString).default({ prop: 'Hello World!' }) - })) + ]).optional(), + parameterModel: zModelWithString.optional().default({ prop: 'Hello World!' }) + }).optional() }); export const zCallToTestOrderOfParamsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ - parameterOptionalStringWithDefault: z.optional(z.string()).default('Hello World!'), - parameterOptionalStringWithEmptyDefault: z.optional(z.string()).default(''), - parameterOptionalStringWithNoDefault: z.optional(z.string()), + parameterOptionalStringWithDefault: z.string().optional().default('Hello World!'), + parameterOptionalStringWithEmptyDefault: z.string().optional().default(''), + parameterOptionalStringWithNoDefault: z.string().optional(), parameterStringWithDefault: z.string().default('Hello World!'), parameterStringWithEmptyDefault: z.string().default(''), parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.optional(z.union([ - z.string(), - z.null() - ])), - parameterStringNullableWithDefault: z.optional(z.union([ - z.string(), - z.null() - ])).default(null) + parameterStringNullableWithNoDefault: z.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }) }); export const zDuplicateNameData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName2Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName3Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDuplicateName4Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -1506,9 +1379,9 @@ export const zCallWithNoContentResponseData = z.object({ export const zCallWithNoContentResponseResponse = z.void(); export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseAndNoContentResponseResponse = z.union([ @@ -1517,17 +1390,17 @@ export const zCallWithResponseAndNoContentResponseResponse = z.union([ ]); export const zDummyAData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zDummyAResponse = z400; export const zDummyBData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** @@ -1536,17 +1409,17 @@ export const zDummyBData = z.object({ export const zDummyBResponse = z.void(); export const zCallWithResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponseResponse = zImport; export const zCallWithDuplicateResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithDuplicateResponsesResponse = z.union([ @@ -1555,81 +1428,50 @@ export const zCallWithDuplicateResponsesResponse = z.union([ ]); export const zCallWithResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zCallWithResponsesResponse = z.union([ z.object({ - '@namespace.string': z.optional(z.string().readonly()), - '@namespace.integer': z.optional(z.int().readonly()), - value: z.optional(z.array(zModelWithString).readonly()) + '@namespace.string': z.string().readonly().optional(), + '@namespace.integer': z.int().readonly().optional(), + value: z.array(zModelWithString).readonly().optional() }), zModelThatExtends, zModelThatExtendsExtends ]); export const zCollectionFormatData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ - parameterArrayCSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArraySSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayTSV: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayPipes: z.union([ - z.array(z.string()), - z.null() - ]), - parameterArrayMulti: z.union([ - z.array(z.string()), - z.null() - ]) + parameterArrayCSV: z.array(z.string()).nullable(), + parameterArraySSV: z.array(z.string()).nullable(), + parameterArrayTSV: z.array(z.string()).nullable(), + parameterArrayPipes: z.array(z.string()).nullable(), + parameterArrayMulti: z.array(z.string()).nullable() }) }); export const zTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.object({ - id: z.optional(z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })) - })), + body: z.never().optional(), + path: z.object({ + id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).optional() + }).optional(), query: z.object({ parameterNumber: z.number().default(123), - parameterString: z.union([ - z.string().default('default'), - z.null() - ]).default('default'), - parameterBoolean: z.union([ - z.boolean().default(true), - z.null() - ]).default(true), - parameterObject: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]).default(null), - parameterArray: z.union([ - z.array(z.string()), - z.null() - ]), - parameterDictionary: z.union([ - z.record(z.string(), z.unknown()), - z.null() - ]), + parameterString: z.string().nullable().default('default'), + parameterBoolean: z.boolean().nullable().default(true), + parameterObject: z.record(z.string(), z.unknown()).nullable().default(null), + parameterArray: z.array(z.string()).nullable(), + parameterDictionary: z.record(z.string(), z.unknown()).nullable(), parameterEnum: z.union([ z.literal('Success'), z.literal('Warning'), - z.literal('Error'), - z.null() - ]) + z.literal('Error') + ]).nullable() }) }); @@ -1643,23 +1485,20 @@ export const zTypesResponse = z.union([ export const zUploadFileData = z.object({ body: z.string(), path: z.object({ - 'api-version': z.union([ - z.string(), - z.null() - ]) + 'api-version': z.string().nullable() }), - query: z.optional(z.never()) + query: z.never().optional() }); export const zUploadFileResponse = z.boolean(); export const zFileResponseData = z.object({ - body: z.optional(z.never()), + body: z.never().optional(), path: z.object({ id: z.string(), 'api-version': z.string() }), - query: z.optional(z.never()) + query: z.never().optional() }); /** @@ -1668,15 +1507,15 @@ export const zFileResponseData = z.object({ export const zFileResponseResponse = z.string(); export const zComplexTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ parameterObject: z.object({ - first: z.optional(z.object({ - second: z.optional(z.object({ - third: z.optional(z.string()) - })) - })) + first: z.object({ + second: z.object({ + third: z.string().optional() + }).optional() + }).optional() }), parameterReference: zModelWithString }) @@ -1688,77 +1527,59 @@ export const zComplexTypesData = z.object({ export const zComplexTypesResponse = z.array(zModelWithString); export const zMultipartResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** * OK */ export const zMultipartResponseResponse = z.object({ - file: z.optional(z.string()), - metadata: z.optional(z.object({ - foo: z.optional(z.string()), - bar: z.optional(z.string()) - })) + file: z.string().optional(), + metadata: z.object({ + foo: z.string().optional(), + bar: z.string().optional() + }).optional() }); export const zMultipartRequestData = z.object({ - body: z.optional(z.object({ - content: z.optional(z.string()), - data: z.optional(z.union([ - zModelWithString, - z.null() - ])) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.object({ + content: z.string().optional(), + data: zModelWithString.nullish() + }).optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zComplexParamsData = z.object({ - body: z.optional(z.object({ - key: z.union([ - z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly(), - z.null() - ]).readonly(), - name: z.union([ - z.string().max(255), - z.null() - ]), - enabled: z.optional(z.boolean()).default(true), + body: z.object({ + key: z.string().max(64).regex(/^[a-zA-Z0-9_]*$/).readonly().nullable(), + name: z.string().max(255).nullable(), + enabled: z.boolean().optional().default(true), type: z.enum([ 'Monkey', 'Horse', 'Bird' ]), - listOfModels: z.optional(z.union([ - z.array(zModelWithString), - z.null() - ])), - listOfStrings: z.optional(z.union([ - z.array(z.string()), - z.null() - ])), + listOfModels: z.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), parameters: z.union([ zModelWithString, zModelWithEnum, zModelWithArray, zModelWithDictionary ]), - user: z.optional(z.object({ - id: z.optional(z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).readonly()), - name: z.optional(z.union([ - z.string().readonly(), - z.null() - ]).readonly()) - }).readonly()) - })), + user: z.object({ + id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }).readonly().optional(), + name: z.string().readonly().nullish() + }).readonly().optional() + }).optional(), path: z.object({ id: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }), 'api-version': z.string() }), - query: z.optional(z.never()) + query: z.never().optional() }); /** @@ -1767,22 +1588,22 @@ export const zComplexParamsData = z.object({ export const zComplexParamsResponse = zModelWithString; export const zCallWithResultFromHeaderData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); export const zTestErrorCodeData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ status: z.int() }) }); export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), + body: z.never().optional(), + path: z.never().optional(), query: z.object({ nonAsciiParamæøåÆØÅöôêÊ: z.int() }) @@ -1795,6 +1616,6 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiS export const zPutWithFormUrlEncodedData = z.object({ body: zArrayWithStrings, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/defaults-with-ref-and-anyof/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/defaults-with-ref-and-anyof/zod.gen.ts index 2fe0a3019..c546b3aa9 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/defaults-with-ref-and-anyof/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/defaults-with-ref-and-anyof/zod.gen.ts @@ -19,16 +19,7 @@ export const zTestSchema = z.object({ primitiveDefault: z.number().default(42), refWithPrimitiveDefault: zAudioFormat.default('pcm_16bit_44.1khz'), refWithObjectDefault: zNestedConfig.default({ model: 'gpt-4', temperature: 1 }), - anyOfWithNullDefault: z.union([ - z.number(), - z.null() - ]).default(null), - anyOfWithRefAndNullDefault: z.union([ - zLanguage, - z.null() - ]).default(null), - optionalAnyOfWithDefault: z.optional(z.union([ - z.string(), - z.null() - ])).default(null) + anyOfWithNullDefault: z.number().nullable().default(null), + anyOfWithRefAndNullDefault: zLanguage.nullable().default(null), + optionalAnyOfWithDefault: z.string().nullish().default(null) }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/enum-null/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/enum-null/zod.gen.ts index 75b7a3bf7..991382570 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/enum-null/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/enum-null/zod.gen.ts @@ -2,7 +2,7 @@ import * as z from 'zod'; -export const zFoo = z.nullable(z.enum(['foo', 'bar'])); +export const zFoo = z.enum(['foo', 'bar']).nullable(); export const zBar = z.enum(['foo', 'bar']); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/enum-resolver-permissive/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/enum-resolver-permissive/zod.gen.ts index 76bf417b2..8e742f44e 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/enum-resolver-permissive/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/enum-resolver-permissive/zod.gen.ts @@ -2,7 +2,7 @@ import * as z from 'zod'; -export const zFoo = z.union([z.enum(['foo', 'bar']), z.string()]); +export const zFoo = z.union([z.enum(['foo', 'bar']), z.string()]).nullable(); export const zBar = z.union([z.enum(['foo', 'bar']), z.string()]); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts index 90862440d..cc881e866 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/schema-const/zod.gen.ts @@ -3,35 +3,35 @@ import * as z from 'zod'; export const zFoo = z.object({ - foo: z.optional(z.literal('foo')), - bar: z.optional(z.literal(3.2)), - baz: z.optional(z.literal(-1)), - qux: z.optional(z.literal(true)), - quux: z.optional(z.tuple([ + foo: z.literal('foo').optional(), + bar: z.literal(3.2).optional(), + baz: z.literal(-1).optional(), + qux: z.literal(true).optional(), + quux: z.tuple([ z.literal(1), z.literal(2), z.literal(3), z.literal('foo'), z.literal(true) - ])), - corge: z.optional(z.record(z.string(), z.unknown())), - garply: z.optional(z.literal(BigInt('10'))), - numberInt8: z.optional(z.literal(100)), - numberInt16: z.optional(z.literal(1000)), - numberInt32: z.optional(z.literal(100000)), - numberInt64: z.optional(z.literal(BigInt(1000000000000))), - numberUint8: z.optional(z.literal(200)), - numberUint16: z.optional(z.literal(50000)), - numberUint32: z.optional(z.literal(3000000000)), - numberUint64: z.optional(z.literal(BigInt(18000000000000000000))), - integerInt8: z.optional(z.literal(-100)), - integerInt16: z.optional(z.literal(-1000)), - integerInt32: z.optional(z.literal(-100000)), - integerInt64: z.optional(z.literal(BigInt(-1000000000000))), - integerUint8: z.optional(z.literal(255)), - integerUint16: z.optional(z.literal(65535)), - integerUint32: z.optional(z.literal(4294967295)), - integerUint64: z.optional(z.literal(BigInt('18446744073709551615'))), - stringInt64: z.optional(z.literal(BigInt('-9223372036854775808'))), - stringUint64: z.optional(z.literal(BigInt('18446744073709551615'))) + ]).optional(), + corge: z.record(z.string(), z.unknown()).optional(), + garply: z.literal(BigInt('10')).optional(), + numberInt8: z.literal(100).optional(), + numberInt16: z.literal(1000).optional(), + numberInt32: z.literal(100000).optional(), + numberInt64: z.literal(BigInt(1000000000000)).optional(), + numberUint8: z.literal(200).optional(), + numberUint16: z.literal(50000).optional(), + numberUint32: z.literal(3000000000).optional(), + numberUint64: z.literal(BigInt(18000000000000000000)).optional(), + integerInt8: z.literal(-100).optional(), + integerInt16: z.literal(-1000).optional(), + integerInt32: z.literal(-100000).optional(), + integerInt64: z.literal(BigInt(-1000000000000)).optional(), + integerUint8: z.literal(255).optional(), + integerUint16: z.literal(65535).optional(), + integerUint32: z.literal(4294967295).optional(), + integerUint64: z.literal(BigInt('18446744073709551615')).optional(), + stringInt64: z.literal(BigInt('-9223372036854775808')).optional(), + stringUint64: z.literal(BigInt('18446744073709551615')).optional() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/type-format-zod/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/type-format-zod/zod.gen.ts index b4eb8a8ef..bb1956f79 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/type-format-zod/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/type-format-zod/zod.gen.ts @@ -3,7 +3,7 @@ import * as z from 'zod'; export const zFoo = z.object({ - bar: z.optional(z.int()), + bar: z.int().optional(), foo: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).default(BigInt(0)), id: z.string() }); @@ -13,9 +13,9 @@ export const zBar = z.object({ }); export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() }); /** diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-bigint-min-max/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-bigint-min-max/zod.gen.ts index 89a650cbb..df6a412ac 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-bigint-min-max/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-bigint-min-max/zod.gen.ts @@ -3,5 +3,5 @@ import * as z from 'zod'; export const zFoo = z.object({ - foo: z.optional(z.coerce.bigint().gte(BigInt(0)).lte(BigInt(100))) + foo: z.coerce.bigint().gte(BigInt(0)).lte(BigInt(100)).optional() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-circular-ref-2/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-circular-ref-2/zod.gen.ts index 8762c33e4..7f27bf16c 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-circular-ref-2/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-circular-ref-2/zod.gen.ts @@ -3,10 +3,7 @@ import * as z from 'zod'; export const zBar = z.object({ - bar: z.union([ - z.array(z.lazy((): any => zBar)), - z.null() - ]) + bar: z.array(z.lazy((): any => zBar)).nullable() }); export const zFoo = z.object({ diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-circular-ref/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-circular-ref/zod.gen.ts index 17d574229..bb9072294 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-circular-ref/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-circular-ref/zod.gen.ts @@ -3,13 +3,11 @@ import * as z from 'zod'; export const zBar = z.object({ - get bar() { - return z.optional(z.array(z.lazy((): any => zBar))); - } + bar: z.array(z.lazy((): any => zBar)).optional() }); export const zFoo = z.object({ - foo: z.optional(zBar) + foo: zBar.optional() }); export const zBaz = z.lazy((): any => zQux); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-dates/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-dates/zod.gen.ts index c0332c774..cc4b41933 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-dates/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-dates/zod.gen.ts @@ -5,31 +5,24 @@ import * as z from 'zod'; export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz'); export const zQux = z.record(z.string(), z.object({ - qux: z.optional(z.string()) + qux: z.string().optional() })); /** * This is Foo schema. */ -export const zFoo = z.union([ - z.object({ - foo: z.optional(z.string().regex(/^\d{3}-\d{2}-\d{4}$/)), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z.optional(z.int().gt(0)).default(0) - }), - z.null() -]).default(null); +export const zFoo = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy((): any => zBar).optional(), + baz: z.array(z.lazy((): any => zFoo)).optional(), + qux: z.int().gt(0).optional().default(0) +}).nullable().default(null); /** * This is Bar schema. */ export const zBar = z.object({ - foo: z.optional(zFoo) + foo: zFoo.optional() }); /** @@ -38,27 +31,27 @@ export const zBar = z.object({ export const zFoo2 = z.string(); export const zFoo3 = z.object({ - foo: z.optional(zBar) + foo: zBar.optional() }); export const zPatchFooData = z.object({ body: z.object({ - foo: z.optional(z.string()) + foo: z.string().optional() }), - path: z.optional(z.never()), - query: z.optional(z.object({ - foo: z.optional(z.string()), - bar: z.optional(zBar), - baz: z.optional(z.object({ - baz: z.optional(z.string()) - })), - qux: z.optional(z.iso.date()), - quux: z.optional(z.iso.datetime({ offset: true })) - })) + path: z.never().optional(), + query: z.object({ + foo: z.string().optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.iso.date().optional(), + quux: z.iso.datetime({ offset: true }).optional() + }).optional() }); export const zPostFooData = z.object({ body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-metadata/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-metadata/zod.gen.ts index 4f634ac6e..ebee5444a 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-metadata/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-metadata/zod.gen.ts @@ -5,37 +5,30 @@ import * as z from 'zod'; export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz'); export const zQux = z.record(z.string(), z.object({ - qux: z.optional(z.string()) + qux: z.string().optional() })); /** * This is Foo schema. */ -export const zFoo = z.union([ - z.object({ - foo: z.optional(z.string().regex(/^\d{3}-\d{2}-\d{4}$/).register(z.globalRegistry, { - description: 'This is foo property.' - })), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo)).register(z.globalRegistry, { - description: 'This is baz property.' - })); - }, - qux: z.optional(z.int().gt(0).register(z.globalRegistry, { - description: 'This is qux property.' - })).default(0) - }), - z.null() -]).default(null); +export const zFoo = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).register(z.globalRegistry, { + description: 'This is foo property.' + }).optional(), + bar: z.lazy((): any => zBar).optional(), + baz: z.array(z.lazy((): any => zFoo)).register(z.globalRegistry, { + description: 'This is baz property.' + }).optional(), + qux: z.int().gt(0).register(z.globalRegistry, { + description: 'This is qux property.' + }).optional().default(0) +}).nullable().default(null); /** * This is Bar schema. */ export const zBar = z.object({ - foo: z.optional(zFoo) + foo: zFoo.optional() }).register(z.globalRegistry, { description: 'This is Bar schema.' }); @@ -48,29 +41,29 @@ export const zFoo2 = z.string().register(z.globalRegistry, { }); export const zFoo3 = z.object({ - foo: z.optional(zBar) + foo: zBar.optional() }); export const zPatchFooData = z.object({ body: z.object({ - foo: z.optional(z.string()) + foo: z.string().optional() }), - path: z.optional(z.never()), - query: z.optional(z.object({ - foo: z.optional(z.string().register(z.globalRegistry, { + path: z.never().optional(), + query: z.object({ + foo: z.string().register(z.globalRegistry, { description: 'This is Foo parameter.' - })), - bar: z.optional(zBar), - baz: z.optional(z.object({ - baz: z.optional(z.string()) - })), - qux: z.optional(z.iso.date()), - quux: z.optional(z.iso.datetime()) - })) + }).optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.iso.date().optional(), + quux: z.iso.datetime().optional() + }).optional() }); export const zPostFooData = z.object({ body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-types/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-types/zod.gen.ts index 8950aeab2..75fc6f38a 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-types/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-types/zod.gen.ts @@ -7,7 +7,7 @@ export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz'); export type BazZodType = z.infer; export const zQux = z.record(z.string(), z.object({ - qux: z.optional(z.string()) + qux: z.string().optional() })); export type QuxZodType = z.infer; @@ -15,19 +15,12 @@ export type QuxZodType = z.infer; /** * This is Foo schema. */ -export const zFoo = z.union([ - z.object({ - foo: z.optional(z.string().regex(/^\d{3}-\d{2}-\d{4}$/)), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z.optional(z.int().gt(0)).default(0) - }), - z.null() -]).default(null); +export const zFoo = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy((): any => zBar).optional(), + baz: z.array(z.lazy((): any => zFoo)).optional(), + qux: z.int().gt(0).optional().default(0) +}).nullable().default(null); export type FooZodType = z.infer; @@ -35,7 +28,7 @@ export type FooZodType = z.infer; * This is Bar schema. */ export const zBar = z.object({ - foo: z.optional(zFoo) + foo: zFoo.optional() }); export type BarZodType = z.infer; @@ -48,33 +41,33 @@ export const zFoo2 = z.string(); export type FooZodType2 = z.infer; export const zFoo3 = z.object({ - foo: z.optional(zBar) + foo: zBar.optional() }); export type FooZodType3 = z.infer; export const zPatchFooData = z.object({ body: z.object({ - foo: z.optional(z.string()) + foo: z.string().optional() }), - path: z.optional(z.never()), - query: z.optional(z.object({ - foo: z.optional(z.string()), - bar: z.optional(zBar), - baz: z.optional(z.object({ - baz: z.optional(z.string()) - })), - qux: z.optional(z.iso.date()), - quux: z.optional(z.iso.datetime()) - })) + path: z.never().optional(), + query: z.object({ + foo: z.string().optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.iso.date().optional(), + quux: z.iso.datetime().optional() + }).optional() }); export type PatchFooDataZodType = z.infer; export const zPostFooData = z.object({ body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); export type PostFooDataZodType = z.infer; diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-union-merge/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-union-merge/zod.gen.ts index ede17a854..2531cfc11 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-union-merge/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-union-merge/zod.gen.ts @@ -32,7 +32,7 @@ export const zCatDetails = z.object({ export const zPetStore = z.object({ animals: z.array(z.object({ name: z.string(), - type: z.optional(z.enum(['dog', 'cat'])), + type: z.enum(['dog', 'cat']).optional(), details: z.union([ zDogDetails, zCatDetails diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators/zod.gen.ts index 7f171ef13..7c70ac7f1 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators/zod.gen.ts @@ -5,31 +5,24 @@ import * as z from 'zod'; export const zBaz = z.string().regex(/foo\nbar/).readonly().default('baz'); export const zQux = z.record(z.string(), z.object({ - qux: z.optional(z.string()) + qux: z.string().optional() })); /** * This is Foo schema. */ -export const zFoo = z.union([ - z.object({ - foo: z.optional(z.string().regex(/^\d{3}-\d{2}-\d{4}$/)), - get bar() { - return z.optional(z.lazy((): any => zBar)); - }, - get baz() { - return z.optional(z.array(z.lazy((): any => zFoo))); - }, - qux: z.optional(z.int().gt(0)).default(0) - }), - z.null() -]).default(null); +export const zFoo = z.object({ + foo: z.string().regex(/^\d{3}-\d{2}-\d{4}$/).optional(), + bar: z.lazy((): any => zBar).optional(), + baz: z.array(z.lazy((): any => zFoo)).optional(), + qux: z.int().gt(0).optional().default(0) +}).nullable().default(null); /** * This is Bar schema. */ export const zBar = z.object({ - foo: z.optional(zFoo) + foo: zFoo.optional() }); /** @@ -38,27 +31,27 @@ export const zBar = z.object({ export const zFoo2 = z.string(); export const zFoo3 = z.object({ - foo: z.optional(zBar) + foo: zBar.optional() }); export const zPatchFooData = z.object({ body: z.object({ - foo: z.optional(z.string()) + foo: z.string().optional() }), - path: z.optional(z.never()), - query: z.optional(z.object({ - foo: z.optional(z.string()), - bar: z.optional(zBar), - baz: z.optional(z.object({ - baz: z.optional(z.string()) - })), - qux: z.optional(z.iso.date()), - quux: z.optional(z.iso.datetime()) - })) + path: z.never().optional(), + query: z.object({ + foo: z.string().optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.iso.date().optional(), + quux: z.iso.datetime().optional() + }).optional() }); export const zPostFooData = z.object({ body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) + path: z.never().optional(), + query: z.never().optional() }); diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/array.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/array.ts index ce5dd3bc9..36eecacf2 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/array.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/array.ts @@ -7,13 +7,13 @@ import { $ } from '../../../../../ts-dsl'; import type { IrSchemaToAstOptions } from '../../shared/types'; import { irSchemaToAst } from '../plugin'; -export const arrayToAst = ({ +export function arrayToAst({ plugin, schema, state, }: IrSchemaToAstOptions & { schema: SchemaWithType<'array'>; -}): TypeTsDsl => { +}): TypeTsDsl { if (!schema.items) { return $.type('Array').generic($.type(plugin.config.topType)); } @@ -43,4 +43,4 @@ export const arrayToAst = ({ return schema.logicalOperator === 'and' ? $.type('Array').generic($.type.and(...itemTypes)) : $.type('Array').generic($.type.or(...itemTypes)); -}; +} diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/enum.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/enum.ts index bf1151cb5..d47831e10 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/enum.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/enum.ts @@ -4,13 +4,13 @@ import type { MaybeTsDsl, TypeTsDsl } from '../../../../../ts-dsl'; import type { IrSchemaToAstOptions } from '../../shared/types'; import { irSchemaToAst } from '../plugin'; -export const enumToAst = ({ +export function enumToAst({ plugin, schema, state, }: IrSchemaToAstOptions & { schema: SchemaWithType<'enum'>; -}): MaybeTsDsl => { +}): MaybeTsDsl { const type = irSchemaToAst({ plugin, schema: { @@ -20,4 +20,4 @@ export const enumToAst = ({ state, }); return type; -}; +} diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/object.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/object.ts index c06359350..b8f31cf37 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/object.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/object.ts @@ -8,13 +8,13 @@ import { $ } from '../../../../../ts-dsl'; import type { IrSchemaToAstOptions } from '../../shared/types'; import { irSchemaToAst } from '../plugin'; -export const objectToAst = ({ +export function objectToAst({ plugin, schema, state, }: IrSchemaToAstOptions & { schema: SchemaWithType<'object'>; -}): TypeTsDsl => { +}): TypeTsDsl { // TODO: parser - handle constants const shape = $.type.object(); const required = schema.required ?? []; @@ -110,4 +110,4 @@ export const objectToAst = ({ } return shape; -}; +} diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/tuple.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/tuple.ts index e7be8d462..f8e9be260 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/tuple.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/tuple.ts @@ -6,13 +6,13 @@ import { $ } from '../../../../../ts-dsl'; import type { IrSchemaToAstOptions } from '../../shared/types'; import { irSchemaToAst } from '../plugin'; -export const tupleToAst = ({ +export function tupleToAst({ plugin, schema, state, }: IrSchemaToAstOptions & { schema: SchemaWithType<'tuple'>; -}): MaybeTsDsl => { +}): MaybeTsDsl { let itemTypes: Array> = []; if (schema.const && Array.isArray(schema.const)) { @@ -32,4 +32,4 @@ export const tupleToAst = ({ } return $.type.tuple(...itemTypes); -}; +} diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/unknown.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/unknown.ts index 2150895ba..43b6f006a 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/unknown.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/unknown.ts @@ -4,11 +4,11 @@ import type { TypeTsDsl } from '../../../../../ts-dsl'; import { $ } from '../../../../../ts-dsl'; import type { IrSchemaToAstOptions } from '../../shared/types'; -export const unknownToAst = ({ +export function unknownToAst({ plugin, }: IrSchemaToAstOptions & { schema: SchemaWithType<'unknown'>; -}): TypeTsDsl => { +}): TypeTsDsl { const node = $.type(plugin.config.topType); return node; -}; +} diff --git a/packages/openapi-ts/src/plugins/arktype/v2/toAst/object.ts b/packages/openapi-ts/src/plugins/arktype/v2/toAst/object.ts index 817937c1f..eac0fb7f6 100644 --- a/packages/openapi-ts/src/plugins/arktype/v2/toAst/object.ts +++ b/packages/openapi-ts/src/plugins/arktype/v2/toAst/object.ts @@ -6,13 +6,13 @@ import { $ } from '../../../../ts-dsl'; import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; import { irSchemaToAst } from '../plugin'; -export const objectToAst = ({ +export function objectToAst({ plugin, schema, state, }: IrSchemaToAstOptions & { schema: SchemaWithType<'object'>; -}): Omit => { +}): Omit { const result: Partial> = {}; // TODO: parser - handle constants @@ -106,4 +106,4 @@ export const objectToAst = ({ } return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/valibot/resolvers/types.ts b/packages/openapi-ts/src/plugins/valibot/resolvers/types.ts index edd0b4a00..384ab5082 100644 --- a/packages/openapi-ts/src/plugins/valibot/resolvers/types.ts +++ b/packages/openapi-ts/src/plugins/valibot/resolvers/types.ts @@ -1,18 +1,11 @@ import type { Refs, Symbol } from '@hey-api/codegen-core'; -import type { - IR, - Plugin, - SchemaResult, - SchemaVisitorContext, - SchemaWithType, - Walker, -} from '@hey-api/shared'; +import type { IR, Plugin, SchemaVisitorContext, SchemaWithType, Walker } from '@hey-api/shared'; import type { MaybeBigInt, ShouldCoerceToBigInt } from '../../../plugins/shared/utils/coerce'; import type { GetIntegerLimit } from '../../../plugins/shared/utils/formats'; import type { $, DollarTsDsl } from '../../../ts-dsl'; import type { Pipe, PipeResult, Pipes, PipesUtils } from '../shared/pipes'; -import type { Ast, IrSchemaToAstOptions, PluginState } from '../shared/types'; +import type { Ast, IrSchemaToAstOptions, PluginState, ValibotSchemaResult } from '../shared/types'; import type { ValibotPlugin } from '../types'; export type Resolvers = Plugin.Resolvers<{ @@ -156,7 +149,7 @@ export interface NumberResolverContext extends BaseContext { } export interface ObjectResolverContext extends BaseContext { - applyModifiers: (result: SchemaResult, opts: { optional?: boolean }) => Ast; + applyModifiers: (result: ValibotSchemaResult, opts: { optional?: boolean }) => Ast; /** * Nodes used to build different parts of the object schema. */ @@ -177,7 +170,7 @@ export interface ObjectResolverContext extends BaseContext { ast: Partial>; state: Refs; }; - walk: Walker; + walk: Walker; walkerCtx: SchemaVisitorContext; } diff --git a/packages/openapi-ts/src/plugins/valibot/shared/types.ts b/packages/openapi-ts/src/plugins/valibot/shared/types.ts index aba45dc5a..6ac39925b 100644 --- a/packages/openapi-ts/src/plugins/valibot/shared/types.ts +++ b/packages/openapi-ts/src/plugins/valibot/shared/types.ts @@ -16,7 +16,7 @@ export type IrSchemaToAstOptions = { plugin: ValibotPlugin['Instance']; /** The plugin state references. */ state: Refs; - walk: Walker; + walk: Walker; }; export type PluginState = Pick, 'path'> & @@ -28,3 +28,28 @@ export type ValidatorArgs = { operation: IR.OperationObject; plugin: ValibotPlugin['Instance']; }; + +/** + * The result from schema walking. + */ +export interface ValibotSchemaResult { + /** Default value from schema, if any. */ + default?: unknown; + /** The Valibot pipes AST. */ + expression: { pipes: Pipes }; + /** The original schema format (for BigInt coercion). */ + format?: string; + /** Whether any child contains a lazy expression. */ + hasLazyExpression?: boolean; + /** Does this schema explicitly allow null? */ + nullable: boolean; + /** Is this schema read-only? */ + readonly: boolean; +} + +/** + * The finalized expression after applyModifiers. + */ +export interface ValibotAppliedResult { + pipes: Pipes; +} diff --git a/packages/openapi-ts/src/plugins/valibot/v1/processor.ts b/packages/openapi-ts/src/plugins/valibot/v1/processor.ts index f9713342c..8c0073140 100644 --- a/packages/openapi-ts/src/plugins/valibot/v1/processor.ts +++ b/packages/openapi-ts/src/plugins/valibot/v1/processor.ts @@ -4,7 +4,7 @@ import { createSchemaProcessor, createSchemaWalker, pathToJsonPointer } from '@h import { exportAst } from '../shared/export'; import type { ProcessorContext, ProcessorResult } from '../shared/processor'; -import type { PluginState } from '../shared/types'; +import type { PluginState, ValibotAppliedResult } from '../shared/types'; import type { ValibotPlugin } from '../types'; import { createVisitor } from './walker'; @@ -54,10 +54,10 @@ export function createProcessor(plugin: ValibotPlugin['Instance']): ProcessorRes plugin, }); const ast = - visitor.applyModifiers(result, { + (visitor.applyModifiers(result, { path: ref(ctx.path), plugin, - }) ?? result.expression; + }) as ValibotAppliedResult) ?? result.expression; if (result.hasLazyExpression) { state.hasLazyExpression['~ref'] = true; } diff --git a/packages/openapi-ts/src/plugins/valibot/v1/toAst/array.ts b/packages/openapi-ts/src/plugins/valibot/v1/toAst/array.ts index 639c33cb0..c4e453a93 100644 --- a/packages/openapi-ts/src/plugins/valibot/v1/toAst/array.ts +++ b/packages/openapi-ts/src/plugins/valibot/v1/toAst/array.ts @@ -1,15 +1,23 @@ -import type { SchemaResult, SchemaWithType } from '@hey-api/shared'; +import type { SchemaWithType } from '@hey-api/shared'; import { childContext, deduplicateSchema } from '@hey-api/shared'; import { $ } from '../../../../ts-dsl'; import { pipesToNode } from '../../shared/pipes'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; +import type { + Ast, + IrSchemaToAstOptions, + ValibotAppliedResult, + ValibotSchemaResult, +} from '../../shared/types'; import { identifiers } from '../constants'; import { unknownToAst } from './unknown'; export function arrayToAst( options: IrSchemaToAstOptions & { - applyModifiers: (result: SchemaResult, opts: { optional?: boolean }) => Ast; + applyModifiers: ( + result: ValibotSchemaResult, + opts: { optional?: boolean }, + ) => ValibotAppliedResult; schema: SchemaWithType<'array'>; }, ): Omit { diff --git a/packages/openapi-ts/src/plugins/valibot/v1/toAst/object.ts b/packages/openapi-ts/src/plugins/valibot/v1/toAst/object.ts index ea88b4400..33b6abdb1 100644 --- a/packages/openapi-ts/src/plugins/valibot/v1/toAst/object.ts +++ b/packages/openapi-ts/src/plugins/valibot/v1/toAst/object.ts @@ -1,20 +1,28 @@ -import type { SchemaResult, SchemaVisitorContext, SchemaWithType, Walker } from '@hey-api/shared'; +import type { SchemaVisitorContext, SchemaWithType, Walker } from '@hey-api/shared'; import { childContext } from '@hey-api/shared'; import { $ } from '../../../../ts-dsl'; import type { ObjectResolverContext } from '../../resolvers'; import type { Pipe, PipeResult } from '../../shared/pipes'; import { pipes } from '../../shared/pipes'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; +import type { + Ast, + IrSchemaToAstOptions, + ValibotAppliedResult, + ValibotSchemaResult, +} from '../../shared/types'; import type { ValibotPlugin } from '../../types'; import { identifiers } from '../constants'; type WalkerCtx = SchemaVisitorContext; interface ObjectToAstOptions extends IrSchemaToAstOptions { - applyModifiers: (result: SchemaResult, opts: { optional?: boolean }) => Ast; + applyModifiers: ( + result: ValibotSchemaResult, + opts: { optional?: boolean }, + ) => ValibotAppliedResult; schema: SchemaWithType<'object'>; - walk: Walker; + walk: Walker; walkerCtx: WalkerCtx; } @@ -89,11 +97,10 @@ function shapeNode(ctx: ExtendedContext): ReturnType { } export function objectToAst(options: ObjectToAstOptions): Omit { - const { applyModifiers, plugin, walk, walkerCtx } = options; + const { plugin } = options; const ctx: ExtendedContext = { ...options, $, - applyModifiers, nodes: { additionalProperties: additionalPropertiesNode, base: baseNode, @@ -110,8 +117,6 @@ export function objectToAst(options: ObjectToAstOptions): Omit ast: {}, state: options.state, }, - walk, - walkerCtx, }; const resolver = plugin.config['~resolvers']?.object; const node = resolver?.(ctx) ?? objectResolver(ctx); diff --git a/packages/openapi-ts/src/plugins/valibot/v1/toAst/tuple.ts b/packages/openapi-ts/src/plugins/valibot/v1/toAst/tuple.ts index 4eb99a28d..ba3a2e7d7 100644 --- a/packages/openapi-ts/src/plugins/valibot/v1/toAst/tuple.ts +++ b/packages/openapi-ts/src/plugins/valibot/v1/toAst/tuple.ts @@ -1,15 +1,23 @@ -import type { SchemaResult, SchemaWithType } from '@hey-api/shared'; +import type { SchemaWithType } from '@hey-api/shared'; import { childContext } from '@hey-api/shared'; import { $ } from '../../../../ts-dsl'; import { pipesToNode } from '../../shared/pipes'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; +import type { + Ast, + IrSchemaToAstOptions, + ValibotAppliedResult, + ValibotSchemaResult, +} from '../../shared/types'; import { identifiers } from '../constants'; import { unknownToAst } from './unknown'; export function tupleToAst( options: IrSchemaToAstOptions & { - applyModifiers: (result: SchemaResult, opts: { optional?: boolean }) => Ast; + applyModifiers: ( + result: ValibotSchemaResult, + opts: { optional?: boolean }, + ) => ValibotAppliedResult; schema: SchemaWithType<'tuple'>; }, ): Omit { diff --git a/packages/openapi-ts/src/plugins/valibot/v1/walker.ts b/packages/openapi-ts/src/plugins/valibot/v1/walker.ts index 7498c3056..739bbf394 100644 --- a/packages/openapi-ts/src/plugins/valibot/v1/walker.ts +++ b/packages/openapi-ts/src/plugins/valibot/v1/walker.ts @@ -1,13 +1,13 @@ import type { Refs, SymbolMeta } from '@hey-api/codegen-core'; import { fromRef } from '@hey-api/codegen-core'; -import type { IR, SchemaExtractor, SchemaResult, SchemaVisitor } from '@hey-api/shared'; +import type { SchemaExtractor, SchemaVisitor } from '@hey-api/shared'; import { pathToJsonPointer } from '@hey-api/shared'; import { $ } from '../../../ts-dsl'; import { maybeBigInt, shouldCoerceToBigInt } from '../../shared/utils/coerce'; import { pipesToNode } from '../shared/pipes'; import type { ProcessorContext } from '../shared/processor'; -import type { Ast, PluginState } from '../shared/types'; +import type { PluginState, ValibotAppliedResult, ValibotSchemaResult } from '../shared/types'; import type { ValibotPlugin } from '../types'; import { identifiers } from './constants'; import { arrayToAst } from './toAst/array'; @@ -30,16 +30,16 @@ export interface VisitorConfig { state: Refs; } -function getDefaultValue(result: SchemaResult) { +function getDefaultValue(result: ValibotSchemaResult) { return result.format ? maybeBigInt(result.default, result.format) : $.fromValue(result.default); } export function createVisitor( config: VisitorConfig, -): SchemaVisitor { +): SchemaVisitor { const { schemaExtractor, state } = config; return { - applyModifiers(result, ctx, options = {}) { + applyModifiers(result, ctx, options = {}): ValibotAppliedResult { const { optional } = options; const v = ctx.plugin.external('valibot.v'); const pipes = [...result.expression.pipes]; @@ -82,8 +82,8 @@ export function createVisitor( return { pipes }; }, array(schema, ctx, walk) { - const applyModifiers = (result: SchemaResult, opts: { optional?: boolean }) => - this.applyModifiers(result, ctx, opts); + const applyModifiers = (result: ValibotSchemaResult, opts: { optional?: boolean }) => + this.applyModifiers(result, ctx, opts) as ValibotAppliedResult; const ast = arrayToAst({ ...ctx, applyModifiers, @@ -92,18 +92,20 @@ export function createVisitor( walk, }); return { + default: schema.default, expression: ast, hasLazyExpression: state.hasLazyExpression['~ref'], nullable: false, - readonly: false, + readonly: schema.accessScope === 'read', }; }, boolean(schema, ctx) { const pipe = booleanToAst({ ...ctx, schema }); return { + default: schema.default, expression: { pipes: [pipe] }, nullable: false, - readonly: false, + readonly: schema.accessScope === 'read', }; }, enum(schema, ctx) { @@ -111,18 +113,20 @@ export function createVisitor( const hasNull = schema.items?.some((item) => item.type === 'null' || item.const === null) ?? false; return { + default: schema.default, expression: { pipes: [pipe] }, nullable: hasNull, - readonly: false, + readonly: schema.accessScope === 'read', }; }, integer(schema, ctx) { const pipe = numberToNode({ ...ctx, schema }); return { + default: schema.default, expression: { pipes: [pipe] }, format: schema.format, nullable: false, - readonly: false, + readonly: schema.accessScope === 'read', }; }, intercept(schema, ctx, walk) { @@ -142,12 +146,13 @@ export function createVisitor( } } }, - intersection(items, schemas, ctx) { + intersection(items, schemas, parentSchema, ctx) { const v = ctx.plugin.external('valibot.v'); const hasAnyLazy = items.some((item) => item.hasLazyExpression); const itemNodes = items.map((item) => pipesToNode(item.expression.pipes, ctx.plugin)); return { + default: parentSchema.default, expression: { pipes: [ $(v) @@ -163,6 +168,7 @@ export function createVisitor( never(schema, ctx) { const pipe = neverToAst({ ...ctx, schema }); return { + default: schema.default, expression: { pipes: [pipe] }, nullable: false, readonly: false, @@ -171,6 +177,7 @@ export function createVisitor( null(schema, ctx) { const pipe = nullToAst({ ...ctx, schema }); return { + default: schema.default, expression: { pipes: [pipe] }, nullable: false, readonly: false, @@ -179,15 +186,16 @@ export function createVisitor( number(schema, ctx) { const pipe = numberToNode({ ...ctx, schema }); return { + default: schema.default, expression: { pipes: [pipe] }, format: schema.format, nullable: false, - readonly: false, + readonly: schema.accessScope === 'read', }; }, object(schema, ctx, walk) { - const applyModifiers = (result: SchemaResult, opts: { optional?: boolean }) => - this.applyModifiers(result, ctx, opts); + const applyModifiers = (result: ValibotSchemaResult, opts: { optional?: boolean }) => + this.applyModifiers(result, ctx, opts) as ValibotAppliedResult; const ast = objectToAst({ applyModifiers, plugin: ctx.plugin, @@ -197,10 +205,11 @@ export function createVisitor( walkerCtx: ctx, }); return { + default: schema.default, expression: ast, - hasLazyExpression: ast.hasLazyExpression ?? false, + hasLazyExpression: state.hasLazyExpression['~ref'], nullable: false, - readonly: false, + readonly: schema.accessScope === 'read', }; }, postProcess(result, schema, ctx) { @@ -229,14 +238,16 @@ export function createVisitor( if (ctx.plugin.isSymbolRegistered(query)) { return { + default: schema.default, expression: { pipes: [$(refSymbol)] }, nullable: false, - readonly: false, + readonly: schema.accessScope === 'read', }; } state.hasLazyExpression['~ref'] = true; return { + default: schema.default, expression: { pipes: [ $(v) @@ -246,7 +257,7 @@ export function createVisitor( }, hasLazyExpression: true, nullable: false, - readonly: false, + readonly: schema.accessScope === 'read', }; }, string(schema, ctx) { @@ -256,22 +267,24 @@ export function createVisitor( schema: { ...schema, type: 'number' }, }); return { + default: schema.default, expression: { pipes: [pipe] }, nullable: false, - readonly: false, + readonly: schema.accessScope === 'read', }; } const pipe = stringToNode({ ...ctx, schema }); return { + default: schema.default, expression: { pipes: [pipe] }, nullable: false, - readonly: false, + readonly: schema.accessScope === 'read', }; }, tuple(schema, ctx, walk) { - const applyModifiers = (result: SchemaResult, opts: { optional?: boolean }) => - this.applyModifiers(result, ctx, opts); + const applyModifiers = (result: ValibotSchemaResult, opts: { optional?: boolean }) => + this.applyModifiers(result, ctx, opts) as ValibotAppliedResult; const ast = tupleToAst({ ...ctx, applyModifiers, @@ -280,47 +293,43 @@ export function createVisitor( walk, }); return { + default: schema.default, expression: ast, hasLazyExpression: state.hasLazyExpression['~ref'], nullable: false, - readonly: false, + readonly: schema.accessScope === 'read', }; }, undefined(schema, ctx) { const pipe = undefinedToAst({ ...ctx, schema }); return { + default: schema.default, expression: { pipes: [pipe] }, nullable: false, readonly: false, }; }, - union(items, schemas, ctx) { + union(items, schemas, parentSchema, ctx) { const v = ctx.plugin.external('valibot.v'); const hasAnyLazy = items.some((item) => item.hasLazyExpression); const hasNull = schemas.some((s) => s.type === 'null') || items.some((i) => i.nullable); const nonNullItems: typeof items = []; - const nonNullSchemas: Array = []; items.forEach((item, index) => { const schema = schemas[index]!; if (schema.type !== 'null') { nonNullItems.push(item); - nonNullSchemas.push(schema); } }); - // Build union expression WITHOUT null - null is tracked via nullable flag - let expression: Ast; + let expression: ValibotSchemaResult['expression']; if (nonNullItems.length === 0) { - // Union was only null expression = { pipes: [$(v).attr(identifiers.schemas.null).call()] }; } else if (nonNullItems.length === 1) { - // Single non-null item expression = nonNullItems[0]!.expression; } else { - // Multiple non-null items const itemNodes = nonNullItems.map((i) => pipesToNode(i.expression.pipes, ctx.plugin)); expression = { pipes: [ @@ -332,15 +341,17 @@ export function createVisitor( } return { + default: parentSchema.default, expression, hasLazyExpression: hasAnyLazy, nullable: hasNull, - readonly: false, + readonly: items.some((i) => i.readonly), }; }, unknown(schema, ctx) { const pipe = unknownToAst({ ...ctx, schema }); return { + default: schema.default, expression: { pipes: [pipe] }, nullable: false, readonly: false, @@ -349,6 +360,7 @@ export function createVisitor( void(schema, ctx) { const pipe = voidToAst({ ...ctx, schema }); return { + default: schema.default, expression: { pipes: [pipe] }, nullable: false, readonly: false, diff --git a/packages/openapi-ts/src/plugins/zod/constants.ts b/packages/openapi-ts/src/plugins/zod/constants.ts index 8acc57bf8..0fa9a60e2 100644 --- a/packages/openapi-ts/src/plugins/zod/constants.ts +++ b/packages/openapi-ts/src/plugins/zod/constants.ts @@ -1,7 +1,9 @@ // TODO: this is inaccurate, it combines identifiers for all supported versions export const identifiers = { + AnyZodObject: 'AnyZodObject', ZodMiniOptional: 'ZodMiniOptional', ZodOptional: 'ZodOptional', + ZodTypeAny: 'ZodTypeAny', _default: '_default', and: 'and', array: 'array', diff --git a/packages/openapi-ts/src/plugins/zod/mini/plugin.ts b/packages/openapi-ts/src/plugins/zod/mini/plugin.ts index fa1a823c2..002c11748 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/plugin.ts @@ -1,174 +1,10 @@ -import type { SymbolMeta } from '@hey-api/codegen-core'; -import { fromRef, ref } from '@hey-api/codegen-core'; -import type { IR, SchemaWithType } from '@hey-api/shared'; -import { deduplicateSchema, pathToJsonPointer } from '@hey-api/shared'; +import { pathToJsonPointer } from '@hey-api/shared'; -import { maybeBigInt } from '../../../plugins/shared/utils/coerce'; -import { $ } from '../../../ts-dsl'; -import { identifiers } from '../constants'; import { getZodModule } from '../shared/module'; import { irOperationToAst } from '../shared/operation'; -import type { Ast, IrSchemaToAstOptions } from '../shared/types'; import { irWebhookToAst } from '../shared/webhook'; import type { ZodPlugin } from '../types'; import { createProcessor } from './processor'; -import { irSchemaWithTypeToAst } from './toAst'; - -export function irSchemaToAst({ - optional, - plugin, - schema, - schemaExtractor, - state, -}: IrSchemaToAstOptions & { - /** - * Accept `optional` to handle optional object properties. We can't handle - * this inside the object function because `.optional()` must come before - * `.default()` which is handled in this function. - */ - optional?: boolean; - schema: IR.SchemaObject; -}): Ast { - if (schemaExtractor && !schema.$ref) { - const extracted = schemaExtractor({ - meta: { - resource: 'definition', - resourceId: pathToJsonPointer(fromRef(state.path)), - }, - naming: plugin.config.definitions, - path: fromRef(state.path), - plugin, - schema, - }); - if (extracted !== schema) schema = extracted; - } - - let ast: Partial = {}; - - const z = plugin.external('zod.z'); - - if (schema.$ref) { - const query: SymbolMeta = { - category: 'schema', - resource: 'definition', - resourceId: schema.$ref, - tool: 'zod', - }; - const refSymbol = plugin.referenceSymbol(query); - if (plugin.isSymbolRegistered(query)) { - ast.expression = $(refSymbol); - } else { - ast.expression = $(z) - .attr(identifiers.lazy) - .call($.func().returns('any').do($(refSymbol).return())); - ast.hasLazyExpression = true; - state.hasLazyExpression['~ref'] = true; - } - } else if (schema.type) { - const typeAst = irSchemaWithTypeToAst({ - plugin, - schema: schema as SchemaWithType, - state, - }); - ast.expression = typeAst.expression; - ast.hasLazyExpression = typeAst.hasLazyExpression; - - if (plugin.config.metadata && schema.description) { - ast.expression = ast.expression - .attr(identifiers.register) - .call( - $(z).attr(identifiers.globalRegistry), - $.object().pretty().prop('description', $.literal(schema.description)), - ); - } - } else if (schema.items) { - schema = deduplicateSchema({ schema }); - - if (schema.items) { - const itemSchemas = schema.items.map((item, index) => - irSchemaToAst({ - plugin, - schema: item, - state: { - ...state, - path: ref([...fromRef(state.path), 'items', index]), - }, - }), - ); - - if (schema.logicalOperator === 'and') { - const firstSchema = schema.items[0]!; - // we want to add an intersection, but not every schema can use the same API. - // if the first item contains another array or not an object, we cannot use - // `.merge()` as that does not exist on `.union()` and non-object schemas. - if ( - firstSchema.logicalOperator === 'or' || - (firstSchema.type && firstSchema.type !== 'object') - ) { - ast.expression = $(z) - .attr(identifiers.intersection) - .call(...itemSchemas.map((schema) => schema.expression)); - } else { - ast.expression = itemSchemas[0]!.expression; - itemSchemas.slice(1).forEach((schema) => { - ast.expression = $(z) - .attr(identifiers.intersection) - .call( - ast.expression, - schema.hasLazyExpression - ? $(z).attr(identifiers.lazy).call($.func().do(schema.expression.return())) - : schema.expression, - ); - }); - } - } else { - ast.expression = $(z) - .attr(identifiers.union) - .call( - $.array() - .pretty() - .elements(...itemSchemas.map((schema) => schema.expression)), - ); - } - } else { - ast = irSchemaToAst({ plugin, schema, state }); - } - } else { - // catch-all fallback for failed schemas - const typeAst = irSchemaWithTypeToAst({ - plugin, - schema: { - type: 'unknown', - }, - state, - }); - ast.expression = typeAst.expression; - } - - if (ast.expression) { - if (schema.accessScope === 'read') { - ast.expression = $(z).attr(identifiers.readonly).call(ast.expression); - } - - if (optional) { - ast.expression = $(z).attr(identifiers.optional).call(ast.expression); - ast.typeName = identifiers.ZodMiniOptional; - } - - if (schema.default !== undefined) { - ast.expression = $(z) - .attr(identifiers._default) - .call( - ast.expression, - schema.type === 'integer' || schema.type === 'number' - ? maybeBigInt(schema.default, schema.format) - : $.fromValue(schema.default), - ); - } - } - - return ast as Ast; -} export const handlerMini: ZodPlugin['Handler'] = ({ plugin }) => { plugin.symbol('z', { diff --git a/packages/openapi-ts/src/plugins/zod/mini/processor.ts b/packages/openapi-ts/src/plugins/zod/mini/processor.ts index 5b4364774..9868559f1 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/processor.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/processor.ts @@ -1,12 +1,12 @@ -import { refs } from '@hey-api/codegen-core'; +import { ref, refs } from '@hey-api/codegen-core'; import type { IR } from '@hey-api/shared'; -import { createSchemaProcessor, pathToJsonPointer } from '@hey-api/shared'; +import { createSchemaProcessor, createSchemaWalker, pathToJsonPointer } from '@hey-api/shared'; import { exportAst } from '../shared/export'; import type { ProcessorContext, ProcessorResult } from '../shared/processor'; -import type { PluginState } from '../shared/types'; +import type { PluginState, ZodAppliedResult } from '../shared/types'; import type { ZodPlugin } from '../types'; -import { irSchemaToAst } from './plugin'; +import { createVisitor } from './walker'; export function createProcessor(plugin: ZodPlugin['Instance']): ProcessorResult { const processor = createSchemaProcessor(); @@ -43,12 +43,24 @@ export function createProcessor(plugin: ZodPlugin['Instance']): ProcessorResult tags: ctx.tags, }); - const ast = irSchemaToAst({ - plugin, - schema: ctx.schema, + const visitor = createVisitor({ schemaExtractor: extractor, state, }); + const walk = createSchemaWalker(visitor); + + const result = walk(ctx.schema, { + path: ref(ctx.path), + plugin, + }); + const ast = + (visitor.applyModifiers(result, { + path: ref(ctx.path), + plugin, + }) as ZodAppliedResult) ?? result.expression; + if (result.hasLazyExpression) { + state.hasLazyExpression['~ref'] = true; + } exportAst({ ...ctx, ast, plugin, state }); }); diff --git a/packages/openapi-ts/src/plugins/zod/mini/toAst/array.ts b/packages/openapi-ts/src/plugins/zod/mini/toAst/array.ts index c71b88df7..809a6c69f 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/toAst/array.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/toAst/array.ts @@ -1,34 +1,37 @@ -import { fromRef, ref } from '@hey-api/codegen-core'; import type { SchemaWithType } from '@hey-api/shared'; -import { deduplicateSchema } from '@hey-api/shared'; +import { childContext, deduplicateSchema } from '@hey-api/shared'; import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -import { irSchemaToAst } from '../plugin'; +import type { + Ast, + IrSchemaToAstOptions, + ZodAppliedResult, + ZodSchemaResult, +} from '../../shared/types'; import { unknownToAst } from './unknown'; -export const arrayToAst = ({ - plugin, - schema, - state, -}: IrSchemaToAstOptions & { - schema: SchemaWithType<'array'>; -}): Omit => { - const z = plugin.external('zod.z'); +export function arrayToAst( + options: IrSchemaToAstOptions & { + applyModifiers: (result: ZodSchemaResult, opts: { optional?: boolean }) => ZodAppliedResult; + schema: SchemaWithType<'array'>; + }, +): Omit { + const { applyModifiers, plugin, walk } = options; + let { schema } = options; const result: Partial> = {}; + const z = plugin.external('zod.z'); const functionName = $(z).attr(identifiers.array); if (!schema.items) { result.expression = functionName.call( unknownToAst({ - plugin, + ...options, schema: { type: 'unknown', }, - state, }).expression, ); } else { @@ -36,18 +39,23 @@ export const arrayToAst = ({ // at least one item is guaranteed const itemExpressions = schema.items!.map((item, index) => { - const itemAst = irSchemaToAst({ - plugin, - schema: item, - state: { - ...state, - path: ref([...fromRef(state.path), 'items', index]), - }, - }); - if (itemAst.hasLazyExpression) { + const itemResult = walk( + item, + childContext( + { + path: options.state.path, + plugin: options.plugin, + }, + 'items', + index, + ), + ); + if (itemResult.hasLazyExpression) { result.hasLazyExpression = true; } - return itemAst.expression; + + const finalExpr = applyModifiers(itemResult, { optional: false }); + return finalExpr.expression; }); if (itemExpressions.length === 1) { @@ -107,4 +115,4 @@ export const arrayToAst = ({ } return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/mini/toAst/boolean.ts b/packages/openapi-ts/src/plugins/zod/mini/toAst/boolean.ts index 8f13b8335..4abdfe633 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/toAst/boolean.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/toAst/boolean.ts @@ -7,7 +7,7 @@ import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; export function booleanToAst({ plugin, schema, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'boolean'>; }): Omit { const result: Partial> = {}; diff --git a/packages/openapi-ts/src/plugins/zod/mini/toAst/enum.ts b/packages/openapi-ts/src/plugins/zod/mini/toAst/enum.ts index f40ea631e..a78949a6b 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/toAst/enum.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/toAst/enum.ts @@ -64,14 +64,6 @@ function baseNode(ctx: EnumResolverContext): Chain { } } -function nullableNode(ctx: EnumResolverContext): Chain | undefined { - const { chain, symbols } = ctx; - const { z } = symbols; - const { isNullable } = ctx.nodes.items(ctx); - if (!isNullable) return; - return $(z).attr(identifiers.nullable).call(chain.current); -} - function enumResolver(ctx: EnumResolverContext): Chain { const { literalMembers } = ctx.nodes.items(ctx); @@ -82,27 +74,22 @@ function enumResolver(ctx: EnumResolverContext): Chain { const baseExpression = ctx.nodes.base(ctx); ctx.chain.current = baseExpression; - const nullableExpression = ctx.nodes.nullable(ctx); - if (nullableExpression) { - ctx.chain.current = nullableExpression; - } - return ctx.chain.current; } -export const enumToAst = ({ +export function enumToAst({ plugin, schema, state, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'enum'>; -}): Omit => { +}): Omit { const z = plugin.external('zod.z'); const { literalMembers } = itemsNode({ $, chain: { current: $(z) }, - nodes: { base: baseNode, items: itemsNode, nullable: nullableNode }, + nodes: { base: baseNode, items: itemsNode }, plugin, schema, symbols: { z }, @@ -115,7 +102,6 @@ export const enumToAst = ({ schema: { type: 'unknown', }, - state, }); } @@ -127,7 +113,6 @@ export const enumToAst = ({ nodes: { base: baseNode, items: itemsNode, - nullable: nullableNode, }, plugin, schema, @@ -146,4 +131,4 @@ export const enumToAst = ({ return { expression: node, }; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/mini/toAst/index.ts b/packages/openapi-ts/src/plugins/zod/mini/toAst/index.ts deleted file mode 100644 index f4962c0ee..000000000 --- a/packages/openapi-ts/src/plugins/zod/mini/toAst/index.ts +++ /dev/null @@ -1,92 +0,0 @@ -import type { SchemaWithType } from '@hey-api/shared'; - -import { shouldCoerceToBigInt } from '../../../../plugins/shared/utils/coerce'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -import { arrayToAst } from './array'; -import { booleanToAst } from './boolean'; -import { enumToAst } from './enum'; -import { neverToAst } from './never'; -import { nullToAst } from './null'; -import { numberToNode } from './number'; -import { objectToAst } from './object'; -import { stringToNode } from './string'; -import { tupleToAst } from './tuple'; -import { undefinedToAst } from './undefined'; -import { unknownToAst } from './unknown'; -import { voidToAst } from './void'; - -export function irSchemaWithTypeToAst({ - schema, - ...args -}: IrSchemaToAstOptions & { - schema: SchemaWithType; -}): Omit { - switch (schema.type) { - case 'array': - return arrayToAst({ - ...args, - schema: schema as SchemaWithType<'array'>, - }); - case 'boolean': - return booleanToAst({ - ...args, - schema: schema as SchemaWithType<'boolean'>, - }); - case 'enum': - return enumToAst({ - ...args, - schema: schema as SchemaWithType<'enum'>, - }); - case 'integer': - case 'number': - return numberToNode({ - ...args, - schema: schema as SchemaWithType<'integer' | 'number'>, - }); - case 'never': - return neverToAst({ - ...args, - schema: schema as SchemaWithType<'never'>, - }); - case 'null': - return nullToAst({ - ...args, - schema: schema as SchemaWithType<'null'>, - }); - case 'object': - return objectToAst({ - ...args, - schema: schema as SchemaWithType<'object'>, - }); - case 'string': - return shouldCoerceToBigInt(schema.format) - ? numberToNode({ - ...args, - schema: { ...schema, type: 'number' }, - }) - : stringToNode({ - ...args, - schema: schema as SchemaWithType<'string'>, - }); - case 'tuple': - return tupleToAst({ - ...args, - schema: schema as SchemaWithType<'tuple'>, - }); - case 'undefined': - return undefinedToAst({ - ...args, - schema: schema as SchemaWithType<'undefined'>, - }); - case 'unknown': - return unknownToAst({ - ...args, - schema: schema as SchemaWithType<'unknown'>, - }); - case 'void': - return voidToAst({ - ...args, - schema: schema as SchemaWithType<'void'>, - }); - } -} diff --git a/packages/openapi-ts/src/plugins/zod/mini/toAst/never.ts b/packages/openapi-ts/src/plugins/zod/mini/toAst/never.ts index faa0793e0..f890dcfc9 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/toAst/never.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/toAst/never.ts @@ -4,13 +4,13 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -export const neverToAst = ({ +export function neverToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'never'>; -}): Omit => { +}): Omit { const z = plugin.external('zod.z'); const result: Partial> = {}; result.expression = $(z).attr(identifiers.never).call(); return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/mini/toAst/null.ts b/packages/openapi-ts/src/plugins/zod/mini/toAst/null.ts index 09f3e4373..dfbfad11c 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/toAst/null.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/toAst/null.ts @@ -4,13 +4,13 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -export const nullToAst = ({ +export function nullToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'null'>; -}): Omit => { +}): Omit { const z = plugin.external('zod.z'); const result: Partial> = {}; result.expression = $(z).attr(identifiers.null).call(); return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/mini/toAst/number.ts b/packages/openapi-ts/src/plugins/zod/mini/toAst/number.ts index 5a47145f3..f3af724d8 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/toAst/number.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/toAst/number.ts @@ -99,13 +99,13 @@ function numberResolver(ctx: NumberResolverContext): Chain { return ctx.chain.current; } -export const numberToNode = ({ +export function numberToNode({ plugin, schema, state, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'integer' | 'number'>; -}): Omit => { +}): Omit { const ast: Partial> = {}; const z = plugin.external('zod.z'); const ctx: NumberResolverContext = { @@ -136,4 +136,4 @@ export const numberToNode = ({ const node = resolver?.(ctx) ?? numberResolver(ctx); ast.expression = node; return ast as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/mini/toAst/object.ts b/packages/openapi-ts/src/plugins/zod/mini/toAst/object.ts index 89fc16a2d..1de13fb14 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/toAst/object.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/toAst/object.ts @@ -1,35 +1,52 @@ -import { fromRef, ref } from '@hey-api/codegen-core'; -import type { SchemaWithType } from '@hey-api/shared'; +import type { SchemaVisitorContext, SchemaWithType, Walker } from '@hey-api/shared'; +import { childContext } from '@hey-api/shared'; import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { ObjectResolverContext } from '../../resolvers'; import type { Chain } from '../../shared/chain'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -import { irSchemaToAst } from '../plugin'; +import type { + Ast, + IrSchemaToAstOptions, + ZodAppliedResult, + ZodSchemaResult, +} from '../../shared/types'; +import type { ZodPlugin } from '../../types'; -function additionalPropertiesNode(ctx: ObjectResolverContext): Chain | null | undefined { - const { plugin, schema } = ctx; +type WalkerCtx = SchemaVisitorContext; + +interface ObjectToAstOptions extends IrSchemaToAstOptions { + applyModifiers: (result: ZodSchemaResult, opts: { optional?: boolean }) => ZodAppliedResult; + schema: SchemaWithType<'object'>; + walk: Walker; + walkerCtx: WalkerCtx; +} + +type ExtendedContext = ObjectResolverContext & { + applyModifiers: ObjectToAstOptions['applyModifiers']; + walk: ObjectToAstOptions['walk']; + walkerCtx: ObjectToAstOptions['walkerCtx']; +}; + +function additionalPropertiesNode(ctx: ExtendedContext): Chain | null | undefined { + const { schema, walk, walkerCtx } = ctx; if ( !schema.additionalProperties || (schema.properties && Object.keys(schema.properties).length > 0) - ) + ) { return; + } - const additionalAst = irSchemaToAst({ - plugin, - schema: schema.additionalProperties, - state: { - ...ctx.utils.state, - path: ref([...fromRef(ctx.utils.state.path), 'additionalProperties']), - }, - }); - if (additionalAst.hasLazyExpression) ctx.utils.ast.hasLazyExpression = true; - return additionalAst.expression; + const additionalResult = walk( + schema.additionalProperties, + childContext(walkerCtx, 'additionalProperties'), + ); + if (additionalResult.hasLazyExpression) ctx.utils.ast.hasLazyExpression = true; + return additionalResult.expression.expression; } -function baseNode(ctx: ObjectResolverContext): Chain { +function baseNode(ctx: ExtendedContext): Chain { const { nodes, symbols } = ctx; const { z } = symbols; @@ -43,48 +60,43 @@ function baseNode(ctx: ObjectResolverContext): Chain { return $(z).attr(identifiers.object).call(shape); } -function objectResolver(ctx: ObjectResolverContext): Chain { +function objectResolver(ctx: ExtendedContext): Chain { // TODO: parser - handle constants return ctx.nodes.base(ctx); } -function shapeNode(ctx: ObjectResolverContext): ReturnType { - const { plugin, schema } = ctx; +function shapeNode(ctx: ExtendedContext): ReturnType { + const { applyModifiers, schema, walk, walkerCtx } = ctx; const shape = $.object().pretty(); for (const name in schema.properties) { const property = schema.properties[name]!; + const isOptional = !schema.required?.includes(name); - const propertyAst = irSchemaToAst({ - optional: !schema.required?.includes(name), - plugin, - schema: property, - state: { - ...ctx.utils.state, - path: ref([...fromRef(ctx.utils.state.path), 'properties', name]), - }, + const propertyResult = walk(property, childContext(walkerCtx, 'properties', name)); + if (propertyResult.hasLazyExpression) ctx.utils.ast.hasLazyExpression = true; + + const ast = applyModifiers(propertyResult, { + optional: isOptional, }); - if (propertyAst.hasLazyExpression) { + + if (ast.hasLazyExpression) { ctx.utils.ast.hasLazyExpression = true; - shape.getter(name, propertyAst.expression.return()); + shape.getter(name, ast.expression.return()); } else { - shape.prop(name, propertyAst.expression); + shape.prop(name, ast.expression); } } return shape; } -export const objectToAst = ({ - plugin, - schema, - state, -}: IrSchemaToAstOptions & { - schema: SchemaWithType<'object'>; -}): Omit => { +export function objectToAst(options: ObjectToAstOptions): Omit { + const { plugin } = options; const ast: Partial> = {}; const z = plugin.external('zod.z'); - const ctx: ObjectResolverContext = { + const ctx: ExtendedContext = { + ...options, $, chain: { current: $(z), @@ -95,17 +107,16 @@ export const objectToAst = ({ shape: shapeNode, }, plugin, - schema, symbols: { z, }, utils: { ast, - state, + state: options.state, }, }; const resolver = plugin.config['~resolvers']?.object; const node = resolver?.(ctx) ?? objectResolver(ctx); ast.expression = node; return ast as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/mini/toAst/string.ts b/packages/openapi-ts/src/plugins/zod/mini/toAst/string.ts index d6c3ff3fb..199c370ff 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/toAst/string.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/toAst/string.ts @@ -115,12 +115,12 @@ function stringResolver(ctx: StringResolverContext): Chain { return ctx.chain.current; } -export const stringToNode = ({ +export function stringToNode({ plugin, schema, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'string'>; -}): Omit => { +}): Omit { const z = plugin.external('zod.z'); const ctx: StringResolverContext = { $, @@ -147,4 +147,4 @@ export const stringToNode = ({ return { expression: node, }; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/mini/toAst/tuple.ts b/packages/openapi-ts/src/plugins/zod/mini/toAst/tuple.ts index 6b6ba3e19..b18c1b664 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/toAst/tuple.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/toAst/tuple.ts @@ -1,22 +1,27 @@ -import { fromRef, ref } from '@hey-api/codegen-core'; import type { SchemaWithType } from '@hey-api/shared'; +import { childContext } from '@hey-api/shared'; import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -import { irSchemaToAst } from '../plugin'; - -export const tupleToAst = ({ - plugin, - schema, - state, -}: IrSchemaToAstOptions & { - schema: SchemaWithType<'tuple'>; -}): Omit => { - const z = plugin.external('zod.z'); +import type { + Ast, + IrSchemaToAstOptions, + ZodAppliedResult, + ZodSchemaResult, +} from '../../shared/types'; + +export function tupleToAst( + options: IrSchemaToAstOptions & { + applyModifiers: (result: ZodSchemaResult, opts: { optional?: boolean }) => ZodAppliedResult; + schema: SchemaWithType<'tuple'>; + }, +): Omit { + const { applyModifiers, plugin, schema, walk } = options; const result: Partial> = {}; + const z = plugin.external('zod.z'); + if (schema.const && Array.isArray(schema.const)) { const tupleElements = schema.const.map((value) => $(z).attr(identifiers.literal).call($.fromValue(value)), @@ -31,18 +36,23 @@ export const tupleToAst = ({ if (schema.items) { schema.items.forEach((item, index) => { - const itemSchema = irSchemaToAst({ - plugin, - schema: item, - state: { - ...state, - path: ref([...fromRef(state.path), 'items', index]), - }, - }); - tupleElements.push(itemSchema.expression); - if (itemSchema.hasLazyExpression) { + const itemResult = walk( + item, + childContext( + { + path: options.state.path, + plugin: options.plugin, + }, + 'items', + index, + ), + ); + if (itemResult.hasLazyExpression) { result.hasLazyExpression = true; } + + const finalExpr = applyModifiers(itemResult, { optional: false }); + tupleElements.push(finalExpr.expression); }); } @@ -51,4 +61,4 @@ export const tupleToAst = ({ .call($.array(...tupleElements)); return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/mini/toAst/undefined.ts b/packages/openapi-ts/src/plugins/zod/mini/toAst/undefined.ts index f6c650cb7..5713da531 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/toAst/undefined.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/toAst/undefined.ts @@ -4,13 +4,13 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -export const undefinedToAst = ({ +export function undefinedToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'undefined'>; -}): Omit => { +}): Omit { const z = plugin.external('zod.z'); const result: Partial> = {}; result.expression = $(z).attr(identifiers.undefined).call(); return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/mini/toAst/unknown.ts b/packages/openapi-ts/src/plugins/zod/mini/toAst/unknown.ts index c3897754f..722a472eb 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/toAst/unknown.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/toAst/unknown.ts @@ -4,13 +4,13 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -export const unknownToAst = ({ +export function unknownToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'unknown'>; -}): Omit => { +}): Omit { const z = plugin.external('zod.z'); const result: Partial> = {}; result.expression = $(z).attr(identifiers.unknown).call(); return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/mini/toAst/void.ts b/packages/openapi-ts/src/plugins/zod/mini/toAst/void.ts index 9a2505303..710057712 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/toAst/void.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/toAst/void.ts @@ -4,13 +4,13 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -export const voidToAst = ({ +export function voidToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'void'>; -}): Omit => { +}): Omit { const z = plugin.external('zod.z'); const result: Partial> = {}; result.expression = $(z).attr(identifiers.void).call(); return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/mini/walker.ts b/packages/openapi-ts/src/plugins/zod/mini/walker.ts new file mode 100644 index 000000000..c17e77a7a --- /dev/null +++ b/packages/openapi-ts/src/plugins/zod/mini/walker.ts @@ -0,0 +1,369 @@ +import type { Refs, SymbolMeta } from '@hey-api/codegen-core'; +import { fromRef } from '@hey-api/codegen-core'; +import type { SchemaExtractor, SchemaVisitor } from '@hey-api/shared'; +import { pathToJsonPointer } from '@hey-api/shared'; + +import { $ } from '../../../ts-dsl'; +import { maybeBigInt, shouldCoerceToBigInt } from '../../shared/utils/coerce'; +import { identifiers } from '../constants'; +import type { ProcessorContext } from '../shared/processor'; +import type { Ast, PluginState, ZodAppliedResult, ZodSchemaResult } from '../shared/types'; +import type { ZodPlugin } from '../types'; +import { arrayToAst } from './toAst/array'; +import { booleanToAst } from './toAst/boolean'; +import { enumToAst } from './toAst/enum'; +import { neverToAst } from './toAst/never'; +import { nullToAst } from './toAst/null'; +import { numberToNode } from './toAst/number'; +import { objectToAst } from './toAst/object'; +import { stringToNode } from './toAst/string'; +import { tupleToAst } from './toAst/tuple'; +import { undefinedToAst } from './toAst/undefined'; +import { unknownToAst } from './toAst/unknown'; +import { voidToAst } from './toAst/void'; + +export interface VisitorConfig { + /** Optional schema extractor function. */ + schemaExtractor?: SchemaExtractor; + /** The plugin state references. */ + state: Refs; +} + +export function createVisitor( + config: VisitorConfig, +): SchemaVisitor { + const { schemaExtractor, state } = config; + return { + applyModifiers(result, ctx, options = {}): ZodAppliedResult { + const { optional } = options; + const z = ctx.plugin.external('zod.z'); + let expression = result.expression.expression; + + if (result.readonly) { + expression = $(z).attr(identifiers.readonly).call(expression); + } + + const hasDefault = result.default !== undefined; + const needsNullable = result.nullable; + + if (optional && needsNullable) { + expression = $(z).attr(identifiers.nullish).call(expression); + } else if (optional) { + expression = $(z).attr(identifiers.optional).call(expression); + } else if (needsNullable) { + expression = $(z).attr(identifiers.nullable).call(expression); + } + + if (hasDefault) { + expression = $(z) + .attr(identifiers._default) + .call( + expression, + result.format + ? maybeBigInt(result.default, result.format) + : $.fromValue(result.default), + ); + } + + return { expression }; + }, + array(schema, ctx, walk) { + const applyModifiers = (result: ZodSchemaResult, opts: { optional?: boolean }) => + this.applyModifiers(result, ctx, opts) as ZodAppliedResult; + const ast = arrayToAst({ + ...ctx, + applyModifiers, + schema, + state, + walk, + }); + return { + default: schema.default, + expression: ast, + hasLazyExpression: state.hasLazyExpression['~ref'], + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + boolean(schema, ctx) { + const ast = booleanToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + enum(schema, ctx) { + const ast = enumToAst({ ...ctx, schema, state }); + const hasNull = + schema.items?.some((item) => item.type === 'null' || item.const === null) ?? false; + return { + default: schema.default, + expression: ast, + nullable: hasNull, + readonly: schema.accessScope === 'read', + }; + }, + integer(schema, ctx) { + const ast = numberToNode({ ...ctx, schema, state }); + return { + default: schema.default, + expression: ast, + format: schema.format, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + intercept(schema, ctx, walk) { + if (schemaExtractor && !schema.$ref) { + const extracted = schemaExtractor({ + meta: { + resource: 'definition', + resourceId: pathToJsonPointer(fromRef(ctx.path)), + }, + naming: ctx.plugin.config.definitions, + path: fromRef(ctx.path), + plugin: ctx.plugin, + schema, + }); + if (extracted !== schema) { + return walk(extracted, ctx); + } + } + }, + intersection(items, schemas, parentSchema, ctx) { + const z = ctx.plugin.external('zod.z'); + const hasAnyLazy = items.some((item) => item.hasLazyExpression); + + let expression = items[0]!.expression.expression; + items.slice(1).forEach((item) => { + expression = $(z) + .attr(identifiers.intersection) + .call( + expression, + item.hasLazyExpression + ? $(z).attr(identifiers.lazy).call($.func().do(item.expression.expression.return())) + : item.expression.expression, + ); + }); + + return { + default: parentSchema.default, + expression: { expression }, + hasLazyExpression: hasAnyLazy, + nullable: items.some((i) => i.nullable), + readonly: items.some((i) => i.readonly), + }; + }, + never(schema, ctx) { + const ast = neverToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: false, + }; + }, + null(schema, ctx) { + const ast = nullToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: false, + }; + }, + number(schema, ctx) { + const ast = numberToNode({ ...ctx, schema, state }); + return { + default: schema.default, + expression: ast, + format: schema.format, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + object(schema, ctx, walk) { + const applyModifiers = (result: ZodSchemaResult, opts: { optional?: boolean }) => + this.applyModifiers(result, ctx, opts) as ZodAppliedResult; + const ast = objectToAst({ + applyModifiers, + plugin: ctx.plugin, + schema, + state, + walk, + walkerCtx: ctx, + }); + return { + default: schema.default, + expression: ast, + hasLazyExpression: state.hasLazyExpression['~ref'], + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + postProcess(result, schema, ctx) { + if (ctx.plugin.config.metadata && schema.description) { + const z = ctx.plugin.external('zod.z'); + return { + ...result, + expression: { + expression: result.expression.expression + .attr(identifiers.register) + .call( + $(z).attr(identifiers.globalRegistry), + $.object().pretty().prop('description', $.literal(schema.description)), + ), + }, + }; + } + return result; + }, + reference($ref, schema, ctx) { + const z = ctx.plugin.external('zod.z'); + const query: SymbolMeta = { + category: 'schema', + resource: 'definition', + resourceId: $ref, + tool: 'zod', + }; + + const refSymbol = ctx.plugin.referenceSymbol(query); + + if (ctx.plugin.isSymbolRegistered(query)) { + return { + default: schema.default, + expression: { + expression: $(refSymbol), + }, + nullable: false, + readonly: schema.accessScope === 'read', + }; + } + + state.hasLazyExpression['~ref'] = true; + return { + default: schema.default, + expression: { + expression: $(z) + .attr(identifiers.lazy) + .call($.func().returns('any').do($(refSymbol).return())), + }, + hasLazyExpression: true, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + string(schema, ctx) { + if (shouldCoerceToBigInt(schema.format)) { + const ast = numberToNode({ + plugin: ctx.plugin, + schema: { ...schema, type: 'number' }, + state, + }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: schema.accessScope === 'read', + }; + } + + const ast = stringToNode({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + tuple(schema, ctx, walk) { + const applyModifiers = (result: ZodSchemaResult, opts: { optional?: boolean }) => + this.applyModifiers(result, ctx, opts) as ZodAppliedResult; + const ast = tupleToAst({ + ...ctx, + applyModifiers, + schema, + state, + walk, + }); + return { + default: schema.default, + expression: ast, + hasLazyExpression: state.hasLazyExpression['~ref'], + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + undefined(schema, ctx) { + const ast = undefinedToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: false, + }; + }, + union(items, schemas, parentSchema, ctx) { + const z = ctx.plugin.external('zod.z'); + const hasAnyLazy = items.some((item) => item.hasLazyExpression); + + const hasNull = schemas.some((s) => s.type === 'null') || items.some((i) => i.nullable); + + const nonNullItems: typeof items = []; + + items.forEach((item, index) => { + const schema = schemas[index]!; + if (schema.type !== 'null') { + nonNullItems.push(item); + } + }); + + let expression: Ast; + if (nonNullItems.length === 0) { + expression = { + expression: $(z).attr(identifiers.null).call(), + }; + } else if (nonNullItems.length === 1) { + expression = nonNullItems[0]!.expression; + } else { + expression = { + expression: $(z) + .attr(identifiers.union) + .call( + $.array() + .pretty() + .elements(...nonNullItems.map((item) => item.expression.expression)), + ), + }; + } + + return { + default: parentSchema.default, + expression, + hasLazyExpression: hasAnyLazy, + nullable: hasNull, + readonly: items.some((i) => i.readonly), + }; + }, + unknown(schema, ctx) { + const ast = unknownToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: false, + }; + }, + void(schema, ctx) { + const ast = voidToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: false, + }; + }, + }; +} diff --git a/packages/openapi-ts/src/plugins/zod/resolvers/types.ts b/packages/openapi-ts/src/plugins/zod/resolvers/types.ts index 6de7ffaa5..2983b35da 100644 --- a/packages/openapi-ts/src/plugins/zod/resolvers/types.ts +++ b/packages/openapi-ts/src/plugins/zod/resolvers/types.ts @@ -1,5 +1,5 @@ import type { Refs, Symbol } from '@hey-api/codegen-core'; -import type { IR, Plugin, SchemaWithType } from '@hey-api/shared'; +import type { IR, Plugin, SchemaVisitorContext, SchemaWithType, Walker } from '@hey-api/shared'; import type { MaybeArray } from '@hey-api/types'; import type ts from 'typescript'; @@ -7,7 +7,7 @@ import type { MaybeBigInt, ShouldCoerceToBigInt } from '../../../plugins/shared/ import type { GetIntegerLimit } from '../../../plugins/shared/utils/formats'; import type { $, DollarTsDsl, TsDsl } from '../../../ts-dsl'; import type { Chain } from '../shared/chain'; -import type { Ast, PluginState } from '../shared/types'; +import type { Ast, IrSchemaToAstOptions, PluginState, ZodSchemaResult } from '../shared/types'; import type { ZodPlugin } from '../types'; export type Resolvers = Plugin.Resolvers<{ @@ -74,33 +74,30 @@ type ValidatorResolver = ( ctx: ValidatorResolverContext, ) => MaybeArray> | null | undefined; -interface BaseContext extends DollarTsDsl { - /** - * Functions for working with chains. - */ - chain: { +type BaseContext = DollarTsDsl & + Pick & { /** - * The current chain. - * - * In Zod, this represents a chain of call expressions ("chains") - * being assembled to form a schema definition. - * - * Each chain can be extended, modified, or replaced to customize - * the resulting schema. + * Functions for working with chains. */ - current: Chain; - }; - /** - * The plugin instance. - */ - plugin: ZodPlugin['Instance']; - /** - * Provides access to commonly used symbols within the plugin. - */ - symbols: { - z: Symbol; + chain: { + /** + * The current chain. + * + * In Zod, this represents a chain of call expressions ("chains") + * being assembled to form a schema definition. + * + * Each chain can be extended, modified, or replaced to customize + * the resulting schema. + */ + current: Chain; + }; + /** + * Provides access to commonly used symbols within the plugin. + */ + symbols: { + z: Symbol; + }; }; -} export interface EnumResolverContext extends BaseContext { /** @@ -132,10 +129,6 @@ export interface EnumResolverContext extends BaseContext { */ literalMembers: Array; }; - /** - * Returns a nullable wrapper if the enum includes null, undefined otherwise. - */ - nullable: (ctx: EnumResolverContext) => Chain | undefined; }; schema: SchemaWithType<'enum'>; /** @@ -171,6 +164,7 @@ export interface NumberResolverContext extends BaseContext { } export interface ObjectResolverContext extends BaseContext { + applyModifiers: (result: ZodSchemaResult, opts: { optional?: boolean }) => Ast; /** * Nodes used to build different parts of the object schema. */ @@ -191,6 +185,8 @@ export interface ObjectResolverContext extends BaseContext { ast: Partial>; state: Refs; }; + walk: Walker; + walkerCtx: SchemaVisitorContext; } export interface StringResolverContext extends BaseContext { diff --git a/packages/openapi-ts/src/plugins/zod/shared/export.ts b/packages/openapi-ts/src/plugins/zod/shared/export.ts index 6ea280d11..9fd5295e1 100644 --- a/packages/openapi-ts/src/plugins/zod/shared/export.ts +++ b/packages/openapi-ts/src/plugins/zod/shared/export.ts @@ -14,6 +14,7 @@ export function exportAst({ path, plugin, schema, + state, tags, }: Pick & ProcessorContext & { @@ -48,7 +49,9 @@ export function exportAst({ const statement = $.const(symbol) .export() .$if(plugin.config.comments && createSchemaComment(schema), (c, v) => c.doc(v)) - .$if(ast.typeName, (c, v) => c.type($.type(z).attr(v))) + .$if(state.hasLazyExpression['~ref'] && state.anyType?.['~ref'], (c, v) => + c.type($.type(z).attr(v)), + ) .assign(ast.expression); plugin.node(statement); diff --git a/packages/openapi-ts/src/plugins/zod/shared/types.ts b/packages/openapi-ts/src/plugins/zod/shared/types.ts index 10081009f..923386ec6 100644 --- a/packages/openapi-ts/src/plugins/zod/shared/types.ts +++ b/packages/openapi-ts/src/plugins/zod/shared/types.ts @@ -1,12 +1,12 @@ import type { Refs, SymbolMeta } from '@hey-api/codegen-core'; -import type { FeatureToggle, IR, NamingOptions, SchemaExtractor } from '@hey-api/shared'; +import type { FeatureToggle, IR, NamingOptions, Walker } from '@hey-api/shared'; import type ts from 'typescript'; import type { $ } from '../../../ts-dsl'; import type { ZodPlugin } from '../types'; -import type { ProcessorContext } from './processor'; export type Ast = { + anyType?: string; expression: ReturnType; hasLazyExpression?: boolean; typeName?: string | ts.Identifier; @@ -15,14 +15,14 @@ export type Ast = { export type IrSchemaToAstOptions = { /** The plugin instance. */ plugin: ZodPlugin['Instance']; - /** Optional schema extractor function. */ - schemaExtractor?: SchemaExtractor; /** The plugin state references. */ state: Refs; + walk: Walker; }; export type PluginState = Pick, 'path'> & Pick, 'tags'> & { + anyType?: string; hasLazyExpression: boolean; }; @@ -38,3 +38,30 @@ export type ValidatorArgs = { operation: IR.OperationObject; plugin: ZodPlugin['Instance']; }; + +/** + * The result from schema walking. + */ +export interface ZodSchemaResult { + /** Default value from schema, if any. */ + default?: unknown; + /** The Zod expression AST. */ + expression: { expression: ReturnType }; + /** The original schema format (for BigInt coercion). */ + format?: string; + /** Whether any child contains a lazy expression. */ + hasLazyExpression?: boolean; + /** Whether THIS result is itself lazy (not just inherited). */ + isLazy?: boolean; + /** Does this schema explicitly allow null? */ + nullable: boolean; + /** Is this schema read-only? */ + readonly: boolean; +} + +/** + * The finalized expression after applyModifiers. + */ +export interface ZodAppliedResult { + expression: ReturnType; +} diff --git a/packages/openapi-ts/src/plugins/zod/v3/plugin.ts b/packages/openapi-ts/src/plugins/zod/v3/plugin.ts index 500807bd1..8dc72f613 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/plugin.ts @@ -1,172 +1,10 @@ -import type { SymbolMeta } from '@hey-api/codegen-core'; -import { fromRef, ref } from '@hey-api/codegen-core'; -import type { IR, SchemaWithType } from '@hey-api/shared'; -import { deduplicateSchema, pathToJsonPointer } from '@hey-api/shared'; +import { pathToJsonPointer } from '@hey-api/shared'; -import { maybeBigInt } from '../../../plugins/shared/utils/coerce'; -import { $ } from '../../../ts-dsl'; -import { identifiers } from '../constants'; import { getZodModule } from '../shared/module'; import { irOperationToAst } from '../shared/operation'; -import type { Ast, IrSchemaToAstOptions } from '../shared/types'; import { irWebhookToAst } from '../shared/webhook'; import type { ZodPlugin } from '../types'; import { createProcessor } from './processor'; -import { irSchemaWithTypeToAst } from './toAst'; - -export function irSchemaToAst({ - optional, - plugin, - schema, - schemaExtractor, - state, -}: IrSchemaToAstOptions & { - /** - * Accept `optional` to handle optional object properties. We can't handle - * this inside the object function because `.optional()` must come before - * `.default()` which is handled in this function. - */ - optional?: boolean; - schema: IR.SchemaObject; -}): Ast { - if (schemaExtractor && !schema.$ref) { - const extracted = schemaExtractor({ - meta: { - resource: 'definition', - resourceId: pathToJsonPointer(fromRef(state.path)), - }, - naming: plugin.config.definitions, - path: fromRef(state.path), - plugin, - schema, - }); - if (extracted !== schema) schema = extracted; - } - - let ast: Partial = {}; - - const z = plugin.external('zod.z'); - - if (schema.$ref) { - const query: SymbolMeta = { - category: 'schema', - resource: 'definition', - resourceId: schema.$ref, - tool: 'zod', - }; - const refSymbol = plugin.referenceSymbol(query); - if (plugin.isSymbolRegistered(query)) { - ast.expression = $(refSymbol); - } else { - ast.expression = $(z) - .attr(identifiers.lazy) - .call($.func().do($(refSymbol).return())); - ast.hasLazyExpression = true; - state.hasLazyExpression['~ref'] = true; - } - } else if (schema.type) { - const typeAst = irSchemaWithTypeToAst({ - plugin, - schema: schema as SchemaWithType, - state, - }); - ast.expression = typeAst.expression; - ast.typeName = typeAst.anyType; - - if (plugin.config.metadata && schema.description) { - ast.expression = ast.expression - .attr(identifiers.describe) - .call($.literal(schema.description)); - } - } else if (schema.items) { - schema = deduplicateSchema({ schema }); - - if (schema.items) { - const itemTypes = schema.items.map((item, index) => { - const typeAst = irSchemaToAst({ - plugin, - schema: item, - state: { - ...state, - path: ref([...fromRef(state.path), 'items', index]), - }, - }); - return typeAst.expression; - }); - - if (schema.logicalOperator === 'and') { - const firstSchema = schema.items[0]!; - // we want to add an intersection, but not every schema can use the same API. - // if the first item contains another array or not an object, we cannot use - // `.merge()` as that does not exist on `.union()` and non-object schemas. - if ( - firstSchema.logicalOperator === 'or' || - (firstSchema.type && firstSchema.type !== 'object') - ) { - ast.expression = $(z) - .attr(identifiers.intersection) - .call(...itemTypes); - } else { - ast.expression = itemTypes[0]; - itemTypes.slice(1).forEach((item) => { - ast.expression = ast.expression!.attr(identifiers.and).call(item); - }); - } - } else { - ast.expression = $(z) - .attr(identifiers.union) - .call( - $.array() - .pretty() - .elements(...itemTypes), - ); - } - } else { - ast = irSchemaToAst({ plugin, schema, state }); - } - } else { - // catch-all fallback for failed schemas - const typeAst = irSchemaWithTypeToAst({ - plugin, - schema: { - type: 'unknown', - }, - state, - }); - ast.expression = typeAst.expression; - ast.typeName = typeAst.anyType; - } - - if (ast.expression) { - if (schema.accessScope === 'read') { - ast.expression = ast.expression.attr(identifiers.readonly).call(); - } - - if (optional) { - ast.expression = ast.expression.attr(identifiers.optional).call(); - } - - if (schema.default !== undefined) { - ast.expression = ast.expression - .attr(identifiers.default) - .call( - schema.type === 'integer' || schema.type === 'number' - ? maybeBigInt(schema.default, schema.format) - : $.fromValue(schema.default), - ); - } - } - - if (state.hasLazyExpression['~ref']) { - if (!ast.typeName) { - ast.typeName = 'ZodTypeAny'; - } - } else if (ast.typeName) { - ast.typeName = undefined; - } - - return ast as Ast; -} export const handlerV3: ZodPlugin['Handler'] = ({ plugin }) => { plugin.symbol('z', { diff --git a/packages/openapi-ts/src/plugins/zod/v3/processor.ts b/packages/openapi-ts/src/plugins/zod/v3/processor.ts index 5b4364774..9868559f1 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/processor.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/processor.ts @@ -1,12 +1,12 @@ -import { refs } from '@hey-api/codegen-core'; +import { ref, refs } from '@hey-api/codegen-core'; import type { IR } from '@hey-api/shared'; -import { createSchemaProcessor, pathToJsonPointer } from '@hey-api/shared'; +import { createSchemaProcessor, createSchemaWalker, pathToJsonPointer } from '@hey-api/shared'; import { exportAst } from '../shared/export'; import type { ProcessorContext, ProcessorResult } from '../shared/processor'; -import type { PluginState } from '../shared/types'; +import type { PluginState, ZodAppliedResult } from '../shared/types'; import type { ZodPlugin } from '../types'; -import { irSchemaToAst } from './plugin'; +import { createVisitor } from './walker'; export function createProcessor(plugin: ZodPlugin['Instance']): ProcessorResult { const processor = createSchemaProcessor(); @@ -43,12 +43,24 @@ export function createProcessor(plugin: ZodPlugin['Instance']): ProcessorResult tags: ctx.tags, }); - const ast = irSchemaToAst({ - plugin, - schema: ctx.schema, + const visitor = createVisitor({ schemaExtractor: extractor, state, }); + const walk = createSchemaWalker(visitor); + + const result = walk(ctx.schema, { + path: ref(ctx.path), + plugin, + }); + const ast = + (visitor.applyModifiers(result, { + path: ref(ctx.path), + plugin, + }) as ZodAppliedResult) ?? result.expression; + if (result.hasLazyExpression) { + state.hasLazyExpression['~ref'] = true; + } exportAst({ ...ctx, ast, plugin, state }); }); diff --git a/packages/openapi-ts/src/plugins/zod/v3/toAst/array.ts b/packages/openapi-ts/src/plugins/zod/v3/toAst/array.ts index c75a4d0a0..9794cdfca 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/toAst/array.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/toAst/array.ts @@ -1,22 +1,25 @@ -import { fromRef, ref } from '@hey-api/codegen-core'; import type { SchemaWithType } from '@hey-api/shared'; -import { deduplicateSchema } from '@hey-api/shared'; +import { childContext, deduplicateSchema } from '@hey-api/shared'; import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -import { irSchemaToAst } from '../plugin'; +import type { + Ast, + IrSchemaToAstOptions, + ZodAppliedResult, + ZodSchemaResult, +} from '../../shared/types'; import { unknownToAst } from './unknown'; -export const arrayToAst = ({ - plugin, - schema, - state, -}: IrSchemaToAstOptions & { - schema: SchemaWithType<'array'>; -}): Omit & { - anyType?: string; -} => { +export function arrayToAst( + options: IrSchemaToAstOptions & { + applyModifiers: (result: ZodSchemaResult, opts: { optional?: boolean }) => ZodAppliedResult; + schema: SchemaWithType<'array'>; + }, +): Omit { + const { applyModifiers, plugin, walk } = options; + let { schema } = options; + const z = plugin.external('zod.z'); const functionName = $(z).attr(identifiers.array); @@ -27,11 +30,10 @@ export const arrayToAst = ({ if (!schema.items) { arrayExpression = functionName.call( unknownToAst({ - plugin, + ...options, schema: { type: 'unknown', }, - state, }), ); } else { @@ -39,18 +41,23 @@ export const arrayToAst = ({ // at least one item is guaranteed const itemExpressions = schema.items!.map((item, index) => { - const itemAst = irSchemaToAst({ - plugin, - schema: item, - state: { - ...state, - path: ref([...fromRef(state.path), 'items', index]), - }, - }); - if (itemAst.hasLazyExpression) { + const itemResult = walk( + item, + childContext( + { + path: options.state.path, + plugin: options.plugin, + }, + 'items', + index, + ), + ); + if (itemResult.hasLazyExpression) { hasLazyExpression = true; } - return itemAst.expression; + + const finalExpr = applyModifiers(itemResult, { optional: false }); + return finalExpr.expression; }); if (itemExpressions.length === 1) { @@ -107,4 +114,4 @@ export const arrayToAst = ({ expression: arrayExpression, hasLazyExpression, }; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v3/toAst/boolean.ts b/packages/openapi-ts/src/plugins/zod/v3/toAst/boolean.ts index 86c7dde0e..32ce71ed5 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/toAst/boolean.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/toAst/boolean.ts @@ -7,7 +7,7 @@ import type { IrSchemaToAstOptions } from '../../shared/types'; export function booleanToAst({ plugin, schema, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'boolean'>; }): ReturnType { let chain: ReturnType; diff --git a/packages/openapi-ts/src/plugins/zod/v3/toAst/enum.ts b/packages/openapi-ts/src/plugins/zod/v3/toAst/enum.ts index ee252c4bf..2a5f46446 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/toAst/enum.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/toAst/enum.ts @@ -64,13 +64,6 @@ function baseNode(ctx: EnumResolverContext): Chain { } } -function nullableNode(ctx: EnumResolverContext): Chain | undefined { - const { chain } = ctx; - const { isNullable } = ctx.nodes.items(ctx); - if (!isNullable) return; - return chain.current.attr(identifiers.nullable).call(); -} - function enumResolver(ctx: EnumResolverContext): Chain { const { literalMembers } = ctx.nodes.items(ctx); @@ -81,27 +74,22 @@ function enumResolver(ctx: EnumResolverContext): Chain { const baseExpression = ctx.nodes.base(ctx); ctx.chain.current = baseExpression; - const nullableExpression = ctx.nodes.nullable(ctx); - if (nullableExpression) { - ctx.chain.current = nullableExpression; - } - return ctx.chain.current; } -export const enumToAst = ({ +export function enumToAst({ plugin, schema, state, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'enum'>; -}): Chain => { +}): Chain { const z = plugin.external('zod.z'); const { literalMembers } = itemsNode({ $, chain: { current: $(z) }, - nodes: { base: baseNode, items: itemsNode, nullable: nullableNode }, + nodes: { base: baseNode, items: itemsNode }, plugin, schema, symbols: { z }, @@ -114,7 +102,6 @@ export const enumToAst = ({ schema: { type: 'unknown', }, - state, }); } @@ -126,7 +113,6 @@ export const enumToAst = ({ nodes: { base: baseNode, items: itemsNode, - nullable: nullableNode, }, plugin, schema, @@ -141,4 +127,4 @@ export const enumToAst = ({ const resolver = plugin.config['~resolvers']?.enum; return resolver?.(ctx) ?? enumResolver(ctx); -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v3/toAst/index.ts b/packages/openapi-ts/src/plugins/zod/v3/toAst/index.ts deleted file mode 100644 index 00a1b5fef..000000000 --- a/packages/openapi-ts/src/plugins/zod/v3/toAst/index.ts +++ /dev/null @@ -1,112 +0,0 @@ -import type { SchemaWithType } from '@hey-api/shared'; - -import { shouldCoerceToBigInt } from '../../../../plugins/shared/utils/coerce'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -import { arrayToAst } from './array'; -import { booleanToAst } from './boolean'; -import { enumToAst } from './enum'; -import { neverToAst } from './never'; -import { nullToAst } from './null'; -import { numberToNode } from './number'; -import { objectToAst } from './object'; -import { stringToNode } from './string'; -import { tupleToAst } from './tuple'; -import { undefinedToAst } from './undefined'; -import { unknownToAst } from './unknown'; -import { voidToAst } from './void'; - -export function irSchemaWithTypeToAst({ - schema, - ...args -}: IrSchemaToAstOptions & { - schema: SchemaWithType; -}): Omit & { - anyType?: string; -} { - switch (schema.type) { - case 'array': - return arrayToAst({ - ...args, - schema: schema as SchemaWithType<'array'>, - }); - case 'boolean': - return { - expression: booleanToAst({ - ...args, - schema: schema as SchemaWithType<'boolean'>, - }), - }; - case 'enum': - return { - expression: enumToAst({ - ...args, - schema: schema as SchemaWithType<'enum'>, - }), - }; - case 'integer': - case 'number': - return { - expression: numberToNode({ - ...args, - schema: schema as SchemaWithType<'integer' | 'number'>, - }), - }; - case 'never': - return { - expression: neverToAst({ - ...args, - schema: schema as SchemaWithType<'never'>, - }), - }; - case 'null': - return { - expression: nullToAst({ - ...args, - schema: schema as SchemaWithType<'null'>, - }), - }; - case 'object': - return objectToAst({ - ...args, - schema: schema as SchemaWithType<'object'>, - }); - case 'string': - return { - expression: shouldCoerceToBigInt(schema.format) - ? numberToNode({ - ...args, - schema: { ...schema, type: 'number' }, - }) - : stringToNode({ - ...args, - schema: schema as SchemaWithType<'string'>, - }), - }; - case 'tuple': - return tupleToAst({ - ...args, - schema: schema as SchemaWithType<'tuple'>, - }); - case 'undefined': - return { - expression: undefinedToAst({ - ...args, - schema: schema as SchemaWithType<'undefined'>, - }), - }; - case 'unknown': - return { - expression: unknownToAst({ - ...args, - schema: schema as SchemaWithType<'unknown'>, - }), - }; - case 'void': - return { - expression: voidToAst({ - ...args, - schema: schema as SchemaWithType<'void'>, - }), - }; - } -} diff --git a/packages/openapi-ts/src/plugins/zod/v3/toAst/never.ts b/packages/openapi-ts/src/plugins/zod/v3/toAst/never.ts index 4e2d8cd0b..193cca1c7 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/toAst/never.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/toAst/never.ts @@ -4,12 +4,12 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { IrSchemaToAstOptions } from '../../shared/types'; -export const neverToAst = ({ +export function neverToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'never'>; -}) => { +}) { const z = plugin.external('zod.z'); const expression = $(z).attr(identifiers.never).call(); return expression; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v3/toAst/null.ts b/packages/openapi-ts/src/plugins/zod/v3/toAst/null.ts index 3fca17b54..40049d135 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/toAst/null.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/toAst/null.ts @@ -4,12 +4,12 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { IrSchemaToAstOptions } from '../../shared/types'; -export const nullToAst = ({ +export function nullToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'null'>; -}) => { +}) { const z = plugin.external('zod.z'); const expression = $(z).attr(identifiers.null).call(); return expression; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v3/toAst/number.ts b/packages/openapi-ts/src/plugins/zod/v3/toAst/number.ts index 4dd2472e9..ebcf8fc5a 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/toAst/number.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/toAst/number.ts @@ -95,13 +95,13 @@ function numberResolver(ctx: NumberResolverContext): Chain { return ctx.chain.current; } -export const numberToNode = ({ +export function numberToNode({ plugin, schema, state, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'integer' | 'number'>; -}): Chain => { +}): Chain { const ast: Partial> = {}; const z = plugin.external('zod.z'); const ctx: NumberResolverContext = { @@ -131,4 +131,4 @@ export const numberToNode = ({ const resolver = plugin.config['~resolvers']?.number; const node = resolver?.(ctx) ?? numberResolver(ctx); return node; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v3/toAst/object.ts b/packages/openapi-ts/src/plugins/zod/v3/toAst/object.ts index 2d37b4ea7..c64c1a1a6 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/toAst/object.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/toAst/object.ts @@ -1,35 +1,52 @@ -import { fromRef, ref } from '@hey-api/codegen-core'; -import type { SchemaWithType } from '@hey-api/shared'; +import type { SchemaVisitorContext, SchemaWithType, Walker } from '@hey-api/shared'; +import { childContext } from '@hey-api/shared'; import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { ObjectResolverContext } from '../../resolvers'; import type { Chain } from '../../shared/chain'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -import { irSchemaToAst } from '../plugin'; +import type { + Ast, + IrSchemaToAstOptions, + ZodAppliedResult, + ZodSchemaResult, +} from '../../shared/types'; +import type { ZodPlugin } from '../../types'; -function additionalPropertiesNode(ctx: ObjectResolverContext): Chain | null | undefined { - const { plugin, schema } = ctx; +type WalkerCtx = SchemaVisitorContext; + +interface ObjectToAstOptions extends IrSchemaToAstOptions { + applyModifiers: (result: ZodSchemaResult, opts: { optional?: boolean }) => ZodAppliedResult; + schema: SchemaWithType<'object'>; + walk: Walker; + walkerCtx: WalkerCtx; +} + +type ExtendedContext = ObjectResolverContext & { + applyModifiers: ObjectToAstOptions['applyModifiers']; + walk: ObjectToAstOptions['walk']; + walkerCtx: ObjectToAstOptions['walkerCtx']; +}; + +function additionalPropertiesNode(ctx: ExtendedContext): Chain | null | undefined { + const { schema, walk, walkerCtx } = ctx; if ( !schema.additionalProperties || (schema.properties && Object.keys(schema.properties).length > 0) - ) + ) { return; + } - const additionalAst = irSchemaToAst({ - plugin, - schema: schema.additionalProperties, - state: { - ...ctx.utils.state, - path: ref([...fromRef(ctx.utils.state.path), 'additionalProperties']), - }, - }); - if (additionalAst.hasLazyExpression) ctx.utils.ast.hasLazyExpression = true; - return additionalAst.expression; + const additionalResult = walk( + schema.additionalProperties, + childContext(walkerCtx, 'additionalProperties'), + ); + if (additionalResult.hasLazyExpression) ctx.utils.ast.hasLazyExpression = true; + return additionalResult.expression.expression; } -function baseNode(ctx: ObjectResolverContext): Chain { +function baseNode(ctx: ExtendedContext): Chain { const { nodes, symbols } = ctx; const { z } = symbols; @@ -43,46 +60,39 @@ function baseNode(ctx: ObjectResolverContext): Chain { return $(z).attr(identifiers.object).call(shape); } -function objectResolver(ctx: ObjectResolverContext): Chain { +function objectResolver(ctx: ExtendedContext): Chain { // TODO: parser - handle constants return ctx.nodes.base(ctx); } -function shapeNode(ctx: ObjectResolverContext): ReturnType { - const { plugin, schema } = ctx; +function shapeNode(ctx: ExtendedContext): ReturnType { + const { applyModifiers, schema, walk, walkerCtx } = ctx; const shape = $.object().pretty(); for (const name in schema.properties) { const property = schema.properties[name]!; + const isOptional = !schema.required?.includes(name); + + const propertyResult = walk(property, childContext(walkerCtx, 'properties', name)); + if (propertyResult.hasLazyExpression) ctx.utils.ast.hasLazyExpression = true; - const propertyAst = irSchemaToAst({ - optional: !schema.required?.includes(name), - plugin, - schema: property, - state: { - ...ctx.utils.state, - path: ref([...fromRef(ctx.utils.state.path), 'properties', name]), - }, + const ast = applyModifiers(propertyResult, { + optional: isOptional, }); - if (propertyAst.hasLazyExpression) ctx.utils.ast.hasLazyExpression = true; - shape.prop(name, propertyAst.expression); + + if (ast.hasLazyExpression) ctx.utils.ast.hasLazyExpression = true; + shape.prop(name, ast.expression); } return shape; } -export const objectToAst = ({ - plugin, - schema, - state, -}: IrSchemaToAstOptions & { - schema: SchemaWithType<'object'>; -}): Omit & { - anyType?: string; -} => { +export function objectToAst(options: ObjectToAstOptions): Omit { + const { plugin } = options; const ast: Partial> = {}; const z = plugin.external('zod.z'); - const ctx: ObjectResolverContext = { + const ctx: ExtendedContext = { + ...options, $, chain: { current: $(z), @@ -93,13 +103,12 @@ export const objectToAst = ({ shape: shapeNode, }, plugin, - schema, symbols: { z, }, utils: { ast, - state, + state: options.state, }, }; const resolver = plugin.config['~resolvers']?.object; @@ -107,8 +116,6 @@ export const objectToAst = ({ ast.expression = node; return { ...ast, - anyType: 'AnyZodObject', - } as Omit & { - anyType: string; - }; -}; + anyType: identifiers.AnyZodObject, + } as Omit; +} diff --git a/packages/openapi-ts/src/plugins/zod/v3/toAst/string.ts b/packages/openapi-ts/src/plugins/zod/v3/toAst/string.ts index bb0d90fa8..a8977dc14 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/toAst/string.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/toAst/string.ts @@ -100,12 +100,12 @@ function stringResolver(ctx: StringResolverContext): Chain { return ctx.chain.current; } -export const stringToNode = ({ +export function stringToNode({ plugin, schema, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'string'>; -}): Chain => { +}): Chain { const z = plugin.external('zod.z'); const ctx: StringResolverContext = { $, @@ -130,4 +130,4 @@ export const stringToNode = ({ const resolver = plugin.config['~resolvers']?.string; const node = resolver?.(ctx) ?? stringResolver(ctx); return node; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v3/toAst/tuple.ts b/packages/openapi-ts/src/plugins/zod/v3/toAst/tuple.ts index 59796e793..8950b7933 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/toAst/tuple.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/toAst/tuple.ts @@ -1,20 +1,23 @@ -import { fromRef, ref } from '@hey-api/codegen-core'; import type { SchemaWithType } from '@hey-api/shared'; +import { childContext } from '@hey-api/shared'; import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -import { irSchemaToAst } from '../plugin'; - -export const tupleToAst = ({ - plugin, - schema, - state, -}: IrSchemaToAstOptions & { - schema: SchemaWithType<'tuple'>; -}): Omit & { - anyType?: string; -} => { +import type { + Ast, + IrSchemaToAstOptions, + ZodAppliedResult, + ZodSchemaResult, +} from '../../shared/types'; + +export function tupleToAst( + options: IrSchemaToAstOptions & { + applyModifiers: (result: ZodSchemaResult, opts: { optional?: boolean }) => ZodAppliedResult; + schema: SchemaWithType<'tuple'>; + }, +): Omit { + const { applyModifiers, plugin, schema, walk } = options; + const z = plugin.external('zod.z'); let hasLazyExpression = false; @@ -36,18 +39,23 @@ export const tupleToAst = ({ if (schema.items) { schema.items.forEach((item, index) => { - const itemSchema = irSchemaToAst({ - plugin, - schema: item, - state: { - ...state, - path: ref([...fromRef(state.path), 'items', index]), - }, - }); - tupleElements.push(itemSchema.expression); - if (itemSchema.hasLazyExpression) { + const itemResult = walk( + item, + childContext( + { + path: options.state.path, + plugin: options.plugin, + }, + 'items', + index, + ), + ); + if (itemResult.hasLazyExpression) { hasLazyExpression = true; } + + const finalExpr = applyModifiers(itemResult, { optional: false }); + tupleElements.push(finalExpr.expression); }); } @@ -59,4 +67,4 @@ export const tupleToAst = ({ expression, hasLazyExpression, }; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v3/toAst/undefined.ts b/packages/openapi-ts/src/plugins/zod/v3/toAst/undefined.ts index 39f9c8155..edaa97db4 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/toAst/undefined.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/toAst/undefined.ts @@ -4,12 +4,12 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { IrSchemaToAstOptions } from '../../shared/types'; -export const undefinedToAst = ({ +export function undefinedToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'undefined'>; -}) => { +}) { const z = plugin.external('zod.z'); const expression = $(z).attr(identifiers.undefined).call(); return expression; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v3/toAst/unknown.ts b/packages/openapi-ts/src/plugins/zod/v3/toAst/unknown.ts index 171437bed..4a2b65469 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/toAst/unknown.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/toAst/unknown.ts @@ -4,12 +4,12 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { IrSchemaToAstOptions } from '../../shared/types'; -export const unknownToAst = ({ +export function unknownToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'unknown'>; -}) => { +}) { const z = plugin.external('zod.z'); const expression = $(z).attr(identifiers.unknown).call(); return expression; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v3/toAst/void.ts b/packages/openapi-ts/src/plugins/zod/v3/toAst/void.ts index e52cb85d6..3fa0b7a4c 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/toAst/void.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/toAst/void.ts @@ -4,12 +4,12 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { IrSchemaToAstOptions } from '../../shared/types'; -export const voidToAst = ({ +export function voidToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'void'>; -}) => { +}) { const z = plugin.external('zod.z'); const expression = $(z).attr(identifiers.void).call(); return expression; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v3/walker.ts b/packages/openapi-ts/src/plugins/zod/v3/walker.ts new file mode 100644 index 000000000..39ac82ab9 --- /dev/null +++ b/packages/openapi-ts/src/plugins/zod/v3/walker.ts @@ -0,0 +1,395 @@ +import type { Refs, SymbolMeta } from '@hey-api/codegen-core'; +import { fromRef, ref } from '@hey-api/codegen-core'; +import type { SchemaExtractor, SchemaVisitor } from '@hey-api/shared'; +import { pathToJsonPointer } from '@hey-api/shared'; + +import { $ } from '../../../ts-dsl'; +import { maybeBigInt, shouldCoerceToBigInt } from '../../shared/utils/coerce'; +import { identifiers } from '../constants'; +import type { ProcessorContext } from '../shared/processor'; +import type { PluginState, ZodAppliedResult, ZodSchemaResult } from '../shared/types'; +import type { ZodPlugin } from '../types'; +import { arrayToAst } from './toAst/array'; +import { booleanToAst } from './toAst/boolean'; +import { enumToAst } from './toAst/enum'; +import { neverToAst } from './toAst/never'; +import { nullToAst } from './toAst/null'; +import { numberToNode } from './toAst/number'; +import { objectToAst } from './toAst/object'; +import { stringToNode } from './toAst/string'; +import { tupleToAst } from './toAst/tuple'; +import { undefinedToAst } from './toAst/undefined'; +import { unknownToAst } from './toAst/unknown'; +import { voidToAst } from './toAst/void'; + +export interface VisitorConfig { + /** Optional schema extractor function. */ + schemaExtractor?: SchemaExtractor; + /** The plugin state references. */ + state: Refs; +} + +export function createVisitor( + config: VisitorConfig, +): SchemaVisitor { + const { schemaExtractor, state } = config; + return { + applyModifiers(result, ctx, options = {}): ZodAppliedResult { + const { optional } = options; + let expression = result.expression.expression; + + if (result.readonly) { + expression = expression.attr(identifiers.readonly).call(); + } + + const hasDefault = result.default !== undefined; + const needsNullable = result.nullable; + + if (optional && needsNullable) { + expression = expression.attr(identifiers.nullish).call(); + } else if (optional) { + expression = expression.attr(identifiers.optional).call(); + } else if (needsNullable) { + expression = expression.attr(identifiers.nullable).call(); + } + + if (hasDefault) { + expression = expression + .attr(identifiers.default) + .call( + result.format + ? maybeBigInt(result.default, result.format) + : $.fromValue(result.default), + ); + } + + return { expression }; + }, + array(schema, ctx, walk) { + const applyModifiers = (result: ZodSchemaResult, opts: { optional?: boolean }) => + this.applyModifiers(result, ctx, opts) as ZodAppliedResult; + const ast = arrayToAst({ + ...ctx, + applyModifiers, + schema, + state, + walk, + }); + return { + default: schema.default, + expression: ast, + hasLazyExpression: state.hasLazyExpression['~ref'], + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + boolean(schema, ctx) { + const ast = booleanToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: { expression: ast }, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + enum(schema, ctx) { + const ast = enumToAst({ ...ctx, schema, state }); + const hasNull = + schema.items?.some((item) => item.type === 'null' || item.const === null) ?? false; + return { + default: schema.default, + expression: { expression: ast }, + nullable: hasNull, + readonly: schema.accessScope === 'read', + }; + }, + integer(schema, ctx) { + const ast = numberToNode({ ...ctx, schema, state }); + return { + default: schema.default, + expression: { expression: ast }, + format: schema.format, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + intercept(schema, ctx, walk) { + if (schemaExtractor && !schema.$ref) { + const extracted = schemaExtractor({ + meta: { + resource: 'definition', + resourceId: pathToJsonPointer(fromRef(ctx.path)), + }, + naming: ctx.plugin.config.definitions, + path: fromRef(ctx.path), + plugin: ctx.plugin, + schema, + }); + if (extracted !== schema) { + return walk(extracted, ctx); + } + } + }, + intersection(items, schemas, parentSchema, ctx) { + const z = ctx.plugin.external('zod.z'); + const hasAnyLazy = items.some((item) => item.hasLazyExpression); + + if (hasAnyLazy) { + state.anyType = ref(identifiers.ZodTypeAny); + } + + const firstSchema = schemas[0]; + let expression: ZodSchemaResult['expression']; + + // If first item is a union or non-object, use z.intersection() + // Otherwise use .and() chaining for better type inference + if ( + firstSchema?.logicalOperator === 'or' || + (firstSchema?.type && firstSchema.type !== 'object') + ) { + expression = { + expression: $(z) + .attr(identifiers.intersection) + .call(...items.map((item) => item.expression.expression)), + }; + } else { + expression = items[0]!.expression; + items.slice(1).forEach((item) => { + expression = { + expression: expression.expression + .attr(identifiers.and) + .call( + item.hasLazyExpression && !item.isLazy + ? $(z) + .attr(identifiers.lazy) + .call($.func().do(item.expression.expression.return())) + : item.expression.expression, + ), + }; + }); + } + + return { + default: parentSchema.default, + expression, + hasLazyExpression: hasAnyLazy, + nullable: items.some((i) => i.nullable), + readonly: items.some((i) => i.readonly), + }; + }, + never(schema, ctx) { + const ast = neverToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: { expression: ast }, + nullable: false, + readonly: false, + }; + }, + null(schema, ctx) { + const ast = nullToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: { expression: ast }, + nullable: false, + readonly: false, + }; + }, + number(schema, ctx) { + const ast = numberToNode({ ...ctx, schema, state }); + return { + default: schema.default, + expression: { expression: ast }, + format: schema.format, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + object(schema, ctx, walk) { + const applyModifiers = (result: ZodSchemaResult, opts: { optional?: boolean }) => + this.applyModifiers(result, ctx, opts) as ZodAppliedResult; + const ast = objectToAst({ + applyModifiers, + plugin: ctx.plugin, + schema, + state, + walk, + walkerCtx: ctx, + }); + if (state.hasLazyExpression['~ref'] && ast.anyType) { + state.anyType = ref(ast.anyType); + } + return { + default: schema.default, + expression: ast, + hasLazyExpression: state.hasLazyExpression['~ref'], + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + postProcess(result, schema, ctx) { + if (ctx.plugin.config.metadata && schema.description) { + return { + ...result, + expression: { + expression: result.expression.expression + .attr(identifiers.describe) + .call($.literal(schema.description)), + }, + }; + } + return result; + }, + reference($ref, schema, ctx) { + const z = ctx.plugin.external('zod.z'); + const query: SymbolMeta = { + category: 'schema', + resource: 'definition', + resourceId: $ref, + tool: 'zod', + }; + + const refSymbol = ctx.plugin.referenceSymbol(query); + + if (ctx.plugin.isSymbolRegistered(query)) { + return { + default: schema.default, + expression: { + expression: $(refSymbol), + }, + nullable: false, + readonly: schema.accessScope === 'read', + }; + } + + state.hasLazyExpression['~ref'] = true; + state.anyType = ref(identifiers.ZodTypeAny); + return { + default: schema.default, + expression: { + expression: $(z) + .attr(identifiers.lazy) + .call($.func().do($(refSymbol).return())), + }, + hasLazyExpression: true, + isLazy: true, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + string(schema, ctx) { + if (shouldCoerceToBigInt(schema.format)) { + const ast = numberToNode({ + plugin: ctx.plugin, + schema: { ...schema, type: 'number' }, + state, + }); + return { + default: schema.default, + expression: { expression: ast }, + nullable: false, + readonly: schema.accessScope === 'read', + }; + } + + const ast = stringToNode({ ...ctx, schema }); + return { + default: schema.default, + expression: { expression: ast }, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + tuple(schema, ctx, walk) { + const applyModifiers = (result: ZodSchemaResult, opts: { optional?: boolean }) => + this.applyModifiers(result, ctx, opts) as ZodAppliedResult; + const ast = tupleToAst({ + ...ctx, + applyModifiers, + schema, + state, + walk, + }); + return { + default: schema.default, + expression: ast, + hasLazyExpression: state.hasLazyExpression['~ref'], + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + undefined(schema, ctx) { + const ast = undefinedToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: { expression: ast }, + nullable: false, + readonly: false, + }; + }, + union(items, schemas, parentSchema, ctx) { + const z = ctx.plugin.external('zod.z'); + const hasAnyLazy = items.some((item) => item.hasLazyExpression); + + const hasNull = schemas.some((s) => s.type === 'null') || items.some((i) => i.nullable); + + if (hasAnyLazy) { + state.anyType = ref(identifiers.ZodTypeAny); + } + + const nonNullItems: typeof items = []; + + items.forEach((item, index) => { + const schema = schemas[index]!; + if (schema.type !== 'null') { + nonNullItems.push(item); + } + }); + + let expression: ZodSchemaResult['expression']; + if (nonNullItems.length === 0) { + expression = { + expression: $(z).attr(identifiers.null).call(), + }; + } else if (nonNullItems.length === 1) { + expression = nonNullItems[0]!.expression; + } else { + expression = { + expression: $(z) + .attr(identifiers.union) + .call( + $.array() + .pretty() + .elements(...nonNullItems.map((item) => item.expression.expression)), + ), + }; + } + + return { + default: parentSchema.default, + expression, + hasLazyExpression: hasAnyLazy, + nullable: hasNull, + readonly: items.some((i) => i.readonly), + }; + }, + unknown(schema, ctx) { + const ast = unknownToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: { expression: ast }, + nullable: false, + readonly: false, + }; + }, + void(schema, ctx) { + const ast = voidToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: { expression: ast }, + nullable: false, + readonly: false, + }; + }, + }; +} diff --git a/packages/openapi-ts/src/plugins/zod/v4/plugin.ts b/packages/openapi-ts/src/plugins/zod/v4/plugin.ts index adc6bda38..d8a4aa03a 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/plugin.ts @@ -1,176 +1,10 @@ -import type { SymbolMeta } from '@hey-api/codegen-core'; -import { fromRef, ref } from '@hey-api/codegen-core'; -import type { IR, SchemaWithType } from '@hey-api/shared'; -import { deduplicateSchema, pathToJsonPointer } from '@hey-api/shared'; +import { pathToJsonPointer } from '@hey-api/shared'; -import { maybeBigInt } from '../../../plugins/shared/utils/coerce'; -import { $ } from '../../../ts-dsl'; -import { identifiers } from '../constants'; import { getZodModule } from '../shared/module'; import { irOperationToAst } from '../shared/operation'; -import type { Ast, IrSchemaToAstOptions } from '../shared/types'; import { irWebhookToAst } from '../shared/webhook'; import type { ZodPlugin } from '../types'; import { createProcessor } from './processor'; -import { irSchemaWithTypeToAst } from './toAst'; - -export function irSchemaToAst({ - optional, - plugin, - schema, - schemaExtractor, - state, -}: IrSchemaToAstOptions & { - /** - * Accept `optional` to handle optional object properties. We can't handle - * this inside the object function because `.optional()` must come before - * `.default()` which is handled in this function. - */ - optional?: boolean; - schema: IR.SchemaObject; -}): Ast { - if (schemaExtractor && !schema.$ref) { - const extracted = schemaExtractor({ - meta: { - resource: 'definition', - resourceId: pathToJsonPointer(fromRef(state.path)), - }, - naming: plugin.config.definitions, - path: fromRef(state.path), - plugin, - schema, - }); - if (extracted !== schema) schema = extracted; - } - - let ast: Partial = {}; - - const z = plugin.external('zod.z'); - - if (schema.$ref) { - const query: SymbolMeta = { - category: 'schema', - resource: 'definition', - resourceId: schema.$ref, - tool: 'zod', - }; - const refSymbol = plugin.referenceSymbol(query); - if (plugin.isSymbolRegistered(query)) { - ast.expression = $(refSymbol); - } else { - ast.expression = $(z) - .attr(identifiers.lazy) - .call($.func().returns('any').do($(refSymbol).return())); - ast.hasLazyExpression = true; - state.hasLazyExpression['~ref'] = true; - } - } else if (schema.type) { - const typeAst = irSchemaWithTypeToAst({ - plugin, - schema: schema as SchemaWithType, - state, - }); - ast.expression = typeAst.expression; - ast.hasLazyExpression = typeAst.hasLazyExpression; - - if (plugin.config.metadata && schema.description) { - ast.expression = ast.expression - .attr(identifiers.register) - .call( - $(z).attr(identifiers.globalRegistry), - $.object().pretty().prop('description', $.literal(schema.description)), - ); - } - } else if (schema.items) { - schema = deduplicateSchema({ schema }); - - if (schema.items) { - const itemSchemas = schema.items.map((item, index) => - irSchemaToAst({ - plugin, - schema: item, - state: { - ...state, - path: ref([...fromRef(state.path), 'items', index]), - }, - }), - ); - - if (schema.logicalOperator === 'and') { - const firstSchema = schema.items[0]!; - // we want to add an intersection, but not every schema can use the same API. - // if the first item contains another array or not an object, we cannot use - // `.merge()` as that does not exist on `.union()` and non-object schemas. - if ( - firstSchema.logicalOperator === 'or' || - (firstSchema.type && firstSchema.type !== 'object') - ) { - ast.expression = $(z) - .attr(identifiers.intersection) - .call(...itemSchemas.map((schema) => schema.expression)); - } else { - ast.expression = itemSchemas[0]!.expression; - itemSchemas.slice(1).forEach((schema) => { - ast.expression = ast - .expression!.attr(identifiers.and) - .call( - schema.hasLazyExpression - ? $(z).attr(identifiers.lazy).call($.func().do(schema.expression.return())) - : schema.expression, - ); - }); - } - } else { - ast.expression = $(z) - .attr(identifiers.union) - .call( - $.array() - .pretty() - .elements(...itemSchemas.map((schema) => schema.expression)), - ); - } - } else { - ast = irSchemaToAst({ - plugin, - schema, - state, - }); - } - } else { - // catch-all fallback for failed schemas - const typeAst = irSchemaWithTypeToAst({ - plugin, - schema: { - type: 'unknown', - }, - state, - }); - ast.expression = typeAst.expression; - } - - if (ast.expression) { - if (schema.accessScope === 'read') { - ast.expression = ast.expression.attr(identifiers.readonly).call(); - } - - if (optional) { - ast.expression = $(z).attr(identifiers.optional).call(ast.expression); - ast.typeName = identifiers.ZodOptional; - } - - if (schema.default !== undefined) { - ast.expression = ast.expression - .attr(identifiers.default) - .call( - schema.type === 'integer' || schema.type === 'number' - ? maybeBigInt(schema.default, schema.format) - : $.fromValue(schema.default), - ); - } - } - - return ast as Ast; -} export const handlerV4: ZodPlugin['Handler'] = ({ plugin }) => { plugin.symbol('z', { diff --git a/packages/openapi-ts/src/plugins/zod/v4/processor.ts b/packages/openapi-ts/src/plugins/zod/v4/processor.ts index 5b4364774..9868559f1 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/processor.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/processor.ts @@ -1,12 +1,12 @@ -import { refs } from '@hey-api/codegen-core'; +import { ref, refs } from '@hey-api/codegen-core'; import type { IR } from '@hey-api/shared'; -import { createSchemaProcessor, pathToJsonPointer } from '@hey-api/shared'; +import { createSchemaProcessor, createSchemaWalker, pathToJsonPointer } from '@hey-api/shared'; import { exportAst } from '../shared/export'; import type { ProcessorContext, ProcessorResult } from '../shared/processor'; -import type { PluginState } from '../shared/types'; +import type { PluginState, ZodAppliedResult } from '../shared/types'; import type { ZodPlugin } from '../types'; -import { irSchemaToAst } from './plugin'; +import { createVisitor } from './walker'; export function createProcessor(plugin: ZodPlugin['Instance']): ProcessorResult { const processor = createSchemaProcessor(); @@ -43,12 +43,24 @@ export function createProcessor(plugin: ZodPlugin['Instance']): ProcessorResult tags: ctx.tags, }); - const ast = irSchemaToAst({ - plugin, - schema: ctx.schema, + const visitor = createVisitor({ schemaExtractor: extractor, state, }); + const walk = createSchemaWalker(visitor); + + const result = walk(ctx.schema, { + path: ref(ctx.path), + plugin, + }); + const ast = + (visitor.applyModifiers(result, { + path: ref(ctx.path), + plugin, + }) as ZodAppliedResult) ?? result.expression; + if (result.hasLazyExpression) { + state.hasLazyExpression['~ref'] = true; + } exportAst({ ...ctx, ast, plugin, state }); }); diff --git a/packages/openapi-ts/src/plugins/zod/v4/toAst/array.ts b/packages/openapi-ts/src/plugins/zod/v4/toAst/array.ts index 26ffab156..2672ac90a 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/toAst/array.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/toAst/array.ts @@ -1,34 +1,37 @@ -import { fromRef, ref } from '@hey-api/codegen-core'; import type { SchemaWithType } from '@hey-api/shared'; -import { deduplicateSchema } from '@hey-api/shared'; +import { childContext, deduplicateSchema } from '@hey-api/shared'; import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -import { irSchemaToAst } from '../plugin'; +import type { + Ast, + IrSchemaToAstOptions, + ZodAppliedResult, + ZodSchemaResult, +} from '../../shared/types'; import { unknownToAst } from './unknown'; -export const arrayToAst = ({ - plugin, - schema, - state, -}: IrSchemaToAstOptions & { - schema: SchemaWithType<'array'>; -}): Omit => { +export function arrayToAst( + options: IrSchemaToAstOptions & { + applyModifiers: (result: ZodSchemaResult, opts: { optional?: boolean }) => ZodAppliedResult; + schema: SchemaWithType<'array'>; + }, +): Omit { + const { applyModifiers, plugin, walk } = options; + let { schema } = options; + const result: Partial> = {}; const z = plugin.external('zod.z'); - const functionName = $(z).attr(identifiers.array); if (!schema.items) { result.expression = functionName.call( unknownToAst({ - plugin, + ...options, schema: { type: 'unknown', }, - state, }).expression, ); } else { @@ -36,18 +39,23 @@ export const arrayToAst = ({ // at least one item is guaranteed const itemExpressions = schema.items!.map((item, index) => { - const itemAst = irSchemaToAst({ - plugin, - schema: item, - state: { - ...state, - path: ref([...fromRef(state.path), 'items', index]), - }, - }); - if (itemAst.hasLazyExpression) { + const itemResult = walk( + item, + childContext( + { + path: options.state.path, + plugin: options.plugin, + }, + 'items', + index, + ), + ); + if (itemResult.hasLazyExpression) { result.hasLazyExpression = true; } - return itemAst.expression; + + const finalExpr = applyModifiers(itemResult, { optional: false }); + return finalExpr.expression; }); if (itemExpressions.length === 1) { @@ -107,4 +115,4 @@ export const arrayToAst = ({ } return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v4/toAst/boolean.ts b/packages/openapi-ts/src/plugins/zod/v4/toAst/boolean.ts index 8f13b8335..4abdfe633 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/toAst/boolean.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/toAst/boolean.ts @@ -7,7 +7,7 @@ import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; export function booleanToAst({ plugin, schema, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'boolean'>; }): Omit { const result: Partial> = {}; diff --git a/packages/openapi-ts/src/plugins/zod/v4/toAst/enum.ts b/packages/openapi-ts/src/plugins/zod/v4/toAst/enum.ts index f40ea631e..a78949a6b 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/toAst/enum.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/toAst/enum.ts @@ -64,14 +64,6 @@ function baseNode(ctx: EnumResolverContext): Chain { } } -function nullableNode(ctx: EnumResolverContext): Chain | undefined { - const { chain, symbols } = ctx; - const { z } = symbols; - const { isNullable } = ctx.nodes.items(ctx); - if (!isNullable) return; - return $(z).attr(identifiers.nullable).call(chain.current); -} - function enumResolver(ctx: EnumResolverContext): Chain { const { literalMembers } = ctx.nodes.items(ctx); @@ -82,27 +74,22 @@ function enumResolver(ctx: EnumResolverContext): Chain { const baseExpression = ctx.nodes.base(ctx); ctx.chain.current = baseExpression; - const nullableExpression = ctx.nodes.nullable(ctx); - if (nullableExpression) { - ctx.chain.current = nullableExpression; - } - return ctx.chain.current; } -export const enumToAst = ({ +export function enumToAst({ plugin, schema, state, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'enum'>; -}): Omit => { +}): Omit { const z = plugin.external('zod.z'); const { literalMembers } = itemsNode({ $, chain: { current: $(z) }, - nodes: { base: baseNode, items: itemsNode, nullable: nullableNode }, + nodes: { base: baseNode, items: itemsNode }, plugin, schema, symbols: { z }, @@ -115,7 +102,6 @@ export const enumToAst = ({ schema: { type: 'unknown', }, - state, }); } @@ -127,7 +113,6 @@ export const enumToAst = ({ nodes: { base: baseNode, items: itemsNode, - nullable: nullableNode, }, plugin, schema, @@ -146,4 +131,4 @@ export const enumToAst = ({ return { expression: node, }; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v4/toAst/index.ts b/packages/openapi-ts/src/plugins/zod/v4/toAst/index.ts deleted file mode 100644 index f4962c0ee..000000000 --- a/packages/openapi-ts/src/plugins/zod/v4/toAst/index.ts +++ /dev/null @@ -1,92 +0,0 @@ -import type { SchemaWithType } from '@hey-api/shared'; - -import { shouldCoerceToBigInt } from '../../../../plugins/shared/utils/coerce'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -import { arrayToAst } from './array'; -import { booleanToAst } from './boolean'; -import { enumToAst } from './enum'; -import { neverToAst } from './never'; -import { nullToAst } from './null'; -import { numberToNode } from './number'; -import { objectToAst } from './object'; -import { stringToNode } from './string'; -import { tupleToAst } from './tuple'; -import { undefinedToAst } from './undefined'; -import { unknownToAst } from './unknown'; -import { voidToAst } from './void'; - -export function irSchemaWithTypeToAst({ - schema, - ...args -}: IrSchemaToAstOptions & { - schema: SchemaWithType; -}): Omit { - switch (schema.type) { - case 'array': - return arrayToAst({ - ...args, - schema: schema as SchemaWithType<'array'>, - }); - case 'boolean': - return booleanToAst({ - ...args, - schema: schema as SchemaWithType<'boolean'>, - }); - case 'enum': - return enumToAst({ - ...args, - schema: schema as SchemaWithType<'enum'>, - }); - case 'integer': - case 'number': - return numberToNode({ - ...args, - schema: schema as SchemaWithType<'integer' | 'number'>, - }); - case 'never': - return neverToAst({ - ...args, - schema: schema as SchemaWithType<'never'>, - }); - case 'null': - return nullToAst({ - ...args, - schema: schema as SchemaWithType<'null'>, - }); - case 'object': - return objectToAst({ - ...args, - schema: schema as SchemaWithType<'object'>, - }); - case 'string': - return shouldCoerceToBigInt(schema.format) - ? numberToNode({ - ...args, - schema: { ...schema, type: 'number' }, - }) - : stringToNode({ - ...args, - schema: schema as SchemaWithType<'string'>, - }); - case 'tuple': - return tupleToAst({ - ...args, - schema: schema as SchemaWithType<'tuple'>, - }); - case 'undefined': - return undefinedToAst({ - ...args, - schema: schema as SchemaWithType<'undefined'>, - }); - case 'unknown': - return unknownToAst({ - ...args, - schema: schema as SchemaWithType<'unknown'>, - }); - case 'void': - return voidToAst({ - ...args, - schema: schema as SchemaWithType<'void'>, - }); - } -} diff --git a/packages/openapi-ts/src/plugins/zod/v4/toAst/never.ts b/packages/openapi-ts/src/plugins/zod/v4/toAst/never.ts index efa4d55dc..a8d88a6fd 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/toAst/never.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/toAst/never.ts @@ -4,13 +4,13 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -export const neverToAst = ({ +export function neverToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'never'>; -}): Omit => { +}): Omit { const result: Partial> = {}; const z = plugin.external('zod.z'); result.expression = $(z).attr(identifiers.never).call(); return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v4/toAst/null.ts b/packages/openapi-ts/src/plugins/zod/v4/toAst/null.ts index 467b08d91..aa6a47d18 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/toAst/null.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/toAst/null.ts @@ -4,13 +4,13 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -export const nullToAst = ({ +export function nullToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'null'>; -}): Omit => { +}): Omit { const result: Partial> = {}; const z = plugin.external('zod.z'); result.expression = $(z).attr(identifiers.null).call(); return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v4/toAst/number.ts b/packages/openapi-ts/src/plugins/zod/v4/toAst/number.ts index 76bb67e68..a64e561e8 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/toAst/number.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/toAst/number.ts @@ -95,13 +95,13 @@ function numberResolver(ctx: NumberResolverContext): Chain { return ctx.chain.current; } -export const numberToNode = ({ +export function numberToNode({ plugin, schema, state, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'integer' | 'number'>; -}): Omit => { +}): Omit { const ast: Partial> = {}; const z = plugin.external('zod.z'); const ctx: NumberResolverContext = { @@ -132,4 +132,4 @@ export const numberToNode = ({ const node = resolver?.(ctx) ?? numberResolver(ctx); ast.expression = node; return ast as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v4/toAst/object.ts b/packages/openapi-ts/src/plugins/zod/v4/toAst/object.ts index 89fc16a2d..1de13fb14 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/toAst/object.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/toAst/object.ts @@ -1,35 +1,52 @@ -import { fromRef, ref } from '@hey-api/codegen-core'; -import type { SchemaWithType } from '@hey-api/shared'; +import type { SchemaVisitorContext, SchemaWithType, Walker } from '@hey-api/shared'; +import { childContext } from '@hey-api/shared'; import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { ObjectResolverContext } from '../../resolvers'; import type { Chain } from '../../shared/chain'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -import { irSchemaToAst } from '../plugin'; +import type { + Ast, + IrSchemaToAstOptions, + ZodAppliedResult, + ZodSchemaResult, +} from '../../shared/types'; +import type { ZodPlugin } from '../../types'; -function additionalPropertiesNode(ctx: ObjectResolverContext): Chain | null | undefined { - const { plugin, schema } = ctx; +type WalkerCtx = SchemaVisitorContext; + +interface ObjectToAstOptions extends IrSchemaToAstOptions { + applyModifiers: (result: ZodSchemaResult, opts: { optional?: boolean }) => ZodAppliedResult; + schema: SchemaWithType<'object'>; + walk: Walker; + walkerCtx: WalkerCtx; +} + +type ExtendedContext = ObjectResolverContext & { + applyModifiers: ObjectToAstOptions['applyModifiers']; + walk: ObjectToAstOptions['walk']; + walkerCtx: ObjectToAstOptions['walkerCtx']; +}; + +function additionalPropertiesNode(ctx: ExtendedContext): Chain | null | undefined { + const { schema, walk, walkerCtx } = ctx; if ( !schema.additionalProperties || (schema.properties && Object.keys(schema.properties).length > 0) - ) + ) { return; + } - const additionalAst = irSchemaToAst({ - plugin, - schema: schema.additionalProperties, - state: { - ...ctx.utils.state, - path: ref([...fromRef(ctx.utils.state.path), 'additionalProperties']), - }, - }); - if (additionalAst.hasLazyExpression) ctx.utils.ast.hasLazyExpression = true; - return additionalAst.expression; + const additionalResult = walk( + schema.additionalProperties, + childContext(walkerCtx, 'additionalProperties'), + ); + if (additionalResult.hasLazyExpression) ctx.utils.ast.hasLazyExpression = true; + return additionalResult.expression.expression; } -function baseNode(ctx: ObjectResolverContext): Chain { +function baseNode(ctx: ExtendedContext): Chain { const { nodes, symbols } = ctx; const { z } = symbols; @@ -43,48 +60,43 @@ function baseNode(ctx: ObjectResolverContext): Chain { return $(z).attr(identifiers.object).call(shape); } -function objectResolver(ctx: ObjectResolverContext): Chain { +function objectResolver(ctx: ExtendedContext): Chain { // TODO: parser - handle constants return ctx.nodes.base(ctx); } -function shapeNode(ctx: ObjectResolverContext): ReturnType { - const { plugin, schema } = ctx; +function shapeNode(ctx: ExtendedContext): ReturnType { + const { applyModifiers, schema, walk, walkerCtx } = ctx; const shape = $.object().pretty(); for (const name in schema.properties) { const property = schema.properties[name]!; + const isOptional = !schema.required?.includes(name); - const propertyAst = irSchemaToAst({ - optional: !schema.required?.includes(name), - plugin, - schema: property, - state: { - ...ctx.utils.state, - path: ref([...fromRef(ctx.utils.state.path), 'properties', name]), - }, + const propertyResult = walk(property, childContext(walkerCtx, 'properties', name)); + if (propertyResult.hasLazyExpression) ctx.utils.ast.hasLazyExpression = true; + + const ast = applyModifiers(propertyResult, { + optional: isOptional, }); - if (propertyAst.hasLazyExpression) { + + if (ast.hasLazyExpression) { ctx.utils.ast.hasLazyExpression = true; - shape.getter(name, propertyAst.expression.return()); + shape.getter(name, ast.expression.return()); } else { - shape.prop(name, propertyAst.expression); + shape.prop(name, ast.expression); } } return shape; } -export const objectToAst = ({ - plugin, - schema, - state, -}: IrSchemaToAstOptions & { - schema: SchemaWithType<'object'>; -}): Omit => { +export function objectToAst(options: ObjectToAstOptions): Omit { + const { plugin } = options; const ast: Partial> = {}; const z = plugin.external('zod.z'); - const ctx: ObjectResolverContext = { + const ctx: ExtendedContext = { + ...options, $, chain: { current: $(z), @@ -95,17 +107,16 @@ export const objectToAst = ({ shape: shapeNode, }, plugin, - schema, symbols: { z, }, utils: { ast, - state, + state: options.state, }, }; const resolver = plugin.config['~resolvers']?.object; const node = resolver?.(ctx) ?? objectResolver(ctx); ast.expression = node; return ast as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v4/toAst/string.ts b/packages/openapi-ts/src/plugins/zod/v4/toAst/string.ts index ad579a15a..9e489646d 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/toAst/string.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/toAst/string.ts @@ -105,12 +105,12 @@ function stringResolver(ctx: StringResolverContext): Chain { return ctx.chain.current; } -export const stringToNode = ({ +export function stringToNode({ plugin, schema, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'string'>; -}): Omit => { +}): Omit { const z = plugin.external('zod.z'); const ctx: StringResolverContext = { $, @@ -137,4 +137,4 @@ export const stringToNode = ({ return { expression: node, }; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v4/toAst/tuple.ts b/packages/openapi-ts/src/plugins/zod/v4/toAst/tuple.ts index 962965069..b18c1b664 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/toAst/tuple.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/toAst/tuple.ts @@ -1,18 +1,23 @@ -import { fromRef, ref } from '@hey-api/codegen-core'; import type { SchemaWithType } from '@hey-api/shared'; +import { childContext } from '@hey-api/shared'; import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; -import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -import { irSchemaToAst } from '../plugin'; - -export const tupleToAst = ({ - plugin, - schema, - state, -}: IrSchemaToAstOptions & { - schema: SchemaWithType<'tuple'>; -}): Omit => { +import type { + Ast, + IrSchemaToAstOptions, + ZodAppliedResult, + ZodSchemaResult, +} from '../../shared/types'; + +export function tupleToAst( + options: IrSchemaToAstOptions & { + applyModifiers: (result: ZodSchemaResult, opts: { optional?: boolean }) => ZodAppliedResult; + schema: SchemaWithType<'tuple'>; + }, +): Omit { + const { applyModifiers, plugin, schema, walk } = options; + const result: Partial> = {}; const z = plugin.external('zod.z'); @@ -31,18 +36,23 @@ export const tupleToAst = ({ if (schema.items) { schema.items.forEach((item, index) => { - const itemSchema = irSchemaToAst({ - plugin, - schema: item, - state: { - ...state, - path: ref([...fromRef(state.path), 'items', index]), - }, - }); - tupleElements.push(itemSchema.expression); - if (itemSchema.hasLazyExpression) { + const itemResult = walk( + item, + childContext( + { + path: options.state.path, + plugin: options.plugin, + }, + 'items', + index, + ), + ); + if (itemResult.hasLazyExpression) { result.hasLazyExpression = true; } + + const finalExpr = applyModifiers(itemResult, { optional: false }); + tupleElements.push(finalExpr.expression); }); } @@ -51,4 +61,4 @@ export const tupleToAst = ({ .call($.array(...tupleElements)); return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v4/toAst/undefined.ts b/packages/openapi-ts/src/plugins/zod/v4/toAst/undefined.ts index f52d9fbff..95b3548d3 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/toAst/undefined.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/toAst/undefined.ts @@ -4,13 +4,13 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -export const undefinedToAst = ({ +export function undefinedToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'undefined'>; -}): Omit => { +}): Omit { const result: Partial> = {}; const z = plugin.external('zod.z'); result.expression = $(z).attr(identifiers.undefined).call(); return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v4/toAst/unknown.ts b/packages/openapi-ts/src/plugins/zod/v4/toAst/unknown.ts index d858d60bb..3667ca961 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/toAst/unknown.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/toAst/unknown.ts @@ -4,13 +4,13 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -export const unknownToAst = ({ +export function unknownToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'unknown'>; -}): Omit => { +}): Omit { const result: Partial> = {}; const z = plugin.external('zod.z'); result.expression = $(z).attr(identifiers.unknown).call(); return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v4/toAst/void.ts b/packages/openapi-ts/src/plugins/zod/v4/toAst/void.ts index 76b566a27..269219ace 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/toAst/void.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/toAst/void.ts @@ -4,13 +4,13 @@ import { $ } from '../../../../ts-dsl'; import { identifiers } from '../../constants'; import type { Ast, IrSchemaToAstOptions } from '../../shared/types'; -export const voidToAst = ({ +export function voidToAst({ plugin, -}: IrSchemaToAstOptions & { +}: Pick & { schema: SchemaWithType<'void'>; -}): Omit => { +}): Omit { const result: Partial> = {}; const z = plugin.external('zod.z'); result.expression = $(z).attr(identifiers.void).call(); return result as Omit; -}; +} diff --git a/packages/openapi-ts/src/plugins/zod/v4/walker.ts b/packages/openapi-ts/src/plugins/zod/v4/walker.ts new file mode 100644 index 000000000..28c80111b --- /dev/null +++ b/packages/openapi-ts/src/plugins/zod/v4/walker.ts @@ -0,0 +1,386 @@ +import type { Refs, SymbolMeta } from '@hey-api/codegen-core'; +import { fromRef } from '@hey-api/codegen-core'; +import type { SchemaExtractor, SchemaVisitor } from '@hey-api/shared'; +import { pathToJsonPointer } from '@hey-api/shared'; + +import { $ } from '../../../ts-dsl'; +import { maybeBigInt, shouldCoerceToBigInt } from '../../shared/utils/coerce'; +import { identifiers } from '../constants'; +import type { ProcessorContext } from '../shared/processor'; +import type { Ast, PluginState, ZodAppliedResult, ZodSchemaResult } from '../shared/types'; +import type { ZodPlugin } from '../types'; +import { arrayToAst } from './toAst/array'; +import { booleanToAst } from './toAst/boolean'; +import { enumToAst } from './toAst/enum'; +import { neverToAst } from './toAst/never'; +import { nullToAst } from './toAst/null'; +import { numberToNode } from './toAst/number'; +import { objectToAst } from './toAst/object'; +import { stringToNode } from './toAst/string'; +import { tupleToAst } from './toAst/tuple'; +import { undefinedToAst } from './toAst/undefined'; +import { unknownToAst } from './toAst/unknown'; +import { voidToAst } from './toAst/void'; + +export interface VisitorConfig { + /** Optional schema extractor function. */ + schemaExtractor?: SchemaExtractor; + /** The plugin state references. */ + state: Refs; +} + +export function createVisitor( + config: VisitorConfig, +): SchemaVisitor { + const { schemaExtractor, state } = config; + return { + applyModifiers(result, ctx, options = {}): ZodAppliedResult { + const { optional } = options; + let expression = result.expression.expression; + + if (result.readonly) { + expression = expression.attr(identifiers.readonly).call(); + } + + const hasDefault = result.default !== undefined; + const needsNullable = result.nullable; + + if (optional && needsNullable) { + expression = expression.attr(identifiers.nullish).call(); + } else if (optional) { + expression = expression.attr(identifiers.optional).call(); + } else if (needsNullable) { + expression = expression.attr(identifiers.nullable).call(); + } + + if (hasDefault) { + expression = expression + .attr(identifiers.default) + .call( + result.format + ? maybeBigInt(result.default, result.format) + : $.fromValue(result.default), + ); + } + + return { expression }; + }, + array(schema, ctx, walk) { + const applyModifiers = (result: ZodSchemaResult, opts: { optional?: boolean }) => + this.applyModifiers(result, ctx, opts) as ZodAppliedResult; + const ast = arrayToAst({ + ...ctx, + applyModifiers, + schema, + state, + walk, + }); + return { + default: schema.default, + expression: ast, + hasLazyExpression: state.hasLazyExpression['~ref'], + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + boolean(schema, ctx) { + const ast = booleanToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + enum(schema, ctx) { + const ast = enumToAst({ ...ctx, schema, state }); + const hasNull = + schema.items?.some((item) => item.type === 'null' || item.const === null) ?? false; + return { + default: schema.default, + expression: ast, + nullable: hasNull, + readonly: schema.accessScope === 'read', + }; + }, + integer(schema, ctx) { + const ast = numberToNode({ ...ctx, schema, state }); + return { + default: schema.default, + expression: ast, + format: schema.format, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + intercept(schema, ctx, walk) { + if (schemaExtractor && !schema.$ref) { + const extracted = schemaExtractor({ + meta: { + resource: 'definition', + resourceId: pathToJsonPointer(fromRef(ctx.path)), + }, + naming: ctx.plugin.config.definitions, + path: fromRef(ctx.path), + plugin: ctx.plugin, + schema, + }); + if (extracted !== schema) { + return walk(extracted, ctx); + } + } + }, + intersection(items, schemas, parentSchema, ctx) { + const z = ctx.plugin.external('zod.z'); + const hasAnyLazy = items.some((item) => item.hasLazyExpression); + + const firstSchema = schemas[0]; + let expression: ZodSchemaResult['expression']; + + // If first item is a union or non-object, use z.intersection() + // Otherwise use .and() chaining for better type inference + if ( + firstSchema?.logicalOperator === 'or' || + (firstSchema?.type && firstSchema.type !== 'object') + ) { + expression = { + expression: $(z) + .attr(identifiers.intersection) + .call(...items.map((item) => item.expression.expression)), + }; + } else { + expression = items[0]!.expression; + items.slice(1).forEach((item) => { + expression = { + expression: expression.expression + .attr(identifiers.and) + .call( + item.hasLazyExpression + ? $(z) + .attr(identifiers.lazy) + .call($.func().do(item.expression.expression.return())) + : item.expression.expression, + ), + }; + }); + } + + return { + default: parentSchema.default, + expression, + hasLazyExpression: hasAnyLazy, + nullable: items.some((i) => i.nullable), + readonly: items.some((i) => i.readonly), + }; + }, + never(schema, ctx) { + const ast = neverToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: false, + }; + }, + null(schema, ctx) { + const ast = nullToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: false, + }; + }, + number(schema, ctx) { + const ast = numberToNode({ ...ctx, schema, state }); + return { + default: schema.default, + expression: ast, + format: schema.format, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + object(schema, ctx, walk) { + const applyModifiers = (result: ZodSchemaResult, opts: { optional?: boolean }) => + this.applyModifiers(result, ctx, opts) as ZodAppliedResult; + const ast = objectToAst({ + applyModifiers, + plugin: ctx.plugin, + schema, + state, + walk, + walkerCtx: ctx, + }); + return { + default: schema.default, + expression: ast, + hasLazyExpression: state.hasLazyExpression['~ref'], + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + postProcess(result, schema, ctx) { + if (ctx.plugin.config.metadata && schema.description) { + const z = ctx.plugin.external('zod.z'); + return { + ...result, + expression: { + expression: result.expression.expression + .attr(identifiers.register) + .call( + $(z).attr(identifiers.globalRegistry), + $.object().pretty().prop('description', $.literal(schema.description)), + ), + }, + }; + } + return result; + }, + reference($ref, schema, ctx) { + const z = ctx.plugin.external('zod.z'); + const query: SymbolMeta = { + category: 'schema', + resource: 'definition', + resourceId: $ref, + tool: 'zod', + }; + + const refSymbol = ctx.plugin.referenceSymbol(query); + + if (ctx.plugin.isSymbolRegistered(query)) { + return { + default: schema.default, + expression: { + expression: $(refSymbol), + }, + nullable: false, + readonly: schema.accessScope === 'read', + }; + } + + state.hasLazyExpression['~ref'] = true; + return { + default: schema.default, + expression: { + expression: $(z) + .attr(identifiers.lazy) + .call($.func().returns('any').do($(refSymbol).return())), + }, + hasLazyExpression: true, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + string(schema, ctx) { + if (shouldCoerceToBigInt(schema.format)) { + const ast = numberToNode({ + plugin: ctx.plugin, + schema: { ...schema, type: 'number' }, + state, + }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: schema.accessScope === 'read', + }; + } + + const ast = stringToNode({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + tuple(schema, ctx, walk) { + const applyModifiers = (result: ZodSchemaResult, opts: { optional?: boolean }) => + this.applyModifiers(result, ctx, opts) as ZodAppliedResult; + const ast = tupleToAst({ + ...ctx, + applyModifiers, + schema, + state, + walk, + }); + return { + default: schema.default, + expression: ast, + hasLazyExpression: state.hasLazyExpression['~ref'], + nullable: false, + readonly: schema.accessScope === 'read', + }; + }, + undefined(schema, ctx) { + const ast = undefinedToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: false, + }; + }, + union(items, schemas, parentSchema, ctx) { + const z = ctx.plugin.external('zod.z'); + const hasAnyLazy = items.some((item) => item.hasLazyExpression); + + const hasNull = schemas.some((s) => s.type === 'null') || items.some((i) => i.nullable); + + const nonNullItems: typeof items = []; + + items.forEach((item, index) => { + const schema = schemas[index]!; + if (schema.type !== 'null') { + nonNullItems.push(item); + } + }); + + let expression: Ast; + if (nonNullItems.length === 0) { + expression = { + expression: $(z).attr(identifiers.null).call(), + }; + } else if (nonNullItems.length === 1) { + expression = nonNullItems[0]!.expression; + } else { + expression = { + expression: $(z) + .attr(identifiers.union) + .call( + $.array() + .pretty() + .elements(...nonNullItems.map((item) => item.expression.expression)), + ), + }; + } + + return { + default: parentSchema.default, + expression, + hasLazyExpression: hasAnyLazy, + nullable: hasNull, + readonly: items.some((i) => i.readonly), + }; + }, + unknown(schema, ctx) { + const ast = unknownToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: false, + }; + }, + void(schema, ctx) { + const ast = voidToAst({ ...ctx, schema }); + return { + default: schema.default, + expression: ast, + nullable: false, + readonly: false, + }; + }, + }; +} diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 53d35c6bd..6122573c9 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -65,7 +65,7 @@ export type { SchemaProcessorResult, } from './ir/schema-processor'; export { createSchemaProcessor } from './ir/schema-processor'; -export type { SchemaResult, SchemaVisitor, SchemaVisitorContext, Walker } from './ir/schema-walker'; +export type { SchemaVisitor, SchemaVisitorContext, Walker } from './ir/schema-walker'; export { childContext, createSchemaWalker } from './ir/schema-walker'; export type { IR } from './ir/types'; export { addItemsToSchema } from './ir/utils'; diff --git a/packages/shared/src/ir/schema-walker.ts b/packages/shared/src/ir/schema-walker.ts index 2618fb102..6c2770bf5 100644 --- a/packages/shared/src/ir/schema-walker.ts +++ b/packages/shared/src/ir/schema-walker.ts @@ -5,27 +5,6 @@ import type { SchemaWithType } from '../plugins/shared/types/schema'; import { deduplicateSchema } from './schema'; import type { IR } from './types'; -/** - * Result returned by visitor methods. Contains the expression plus metadata - * needed for modifier application. - */ -export interface SchemaResult { - /** Default value from schema, if any. */ - default?: unknown; - /** The core schema expression, WITHOUT optional/nullable/default applied. */ - expression: TExpr; - /** The original schema format. */ - format?: string; - /** For libraries that need lazy evaluation. */ - hasLazyExpression?: boolean; - /** Plugin-specific metadata bucket. */ - meta?: Record; - /** Does this schema explicitly allow null? */ - nullable: boolean; - /** Is this schema read-only? */ - readonly: boolean; -} - /** * Context passed to all visitor methods. */ @@ -37,47 +16,43 @@ export interface SchemaVisitorContext { } /** - * The walk function signature. + * The walk function signature. Fully generic over TResult. */ -export type Walker = ( +export type Walker = ( schema: IR.SchemaObject, ctx: SchemaVisitorContext, -) => SchemaResult; +) => TResult; /** - * The visitor interface. Plugins implement this to define how schemas - * are transformed into their target representation. + * The visitor interface. Plugins define their own TResult type. + * + * The walker handles orchestration (dispatch, deduplication, path tracking). + * Result shape and semantics are entirely plugin-defined. */ -export interface SchemaVisitor { +export interface SchemaVisitor { /** - * Apply modifiers (optional/nullable/nullish/default) to a schema result. + * Apply modifiers to a result. */ applyModifiers( - result: SchemaResult, + result: TResult, ctx: SchemaVisitorContext, context?: { /** Is this property optional? */ optional?: boolean; }, - ): TExpr; + ): unknown; array( schema: SchemaWithType<'array'>, ctx: SchemaVisitorContext, - walk: Walker, - ): SchemaResult; - boolean( - schema: SchemaWithType<'boolean'>, - ctx: SchemaVisitorContext, - ): SchemaResult; + walk: Walker, + ): TResult; + boolean(schema: SchemaWithType<'boolean'>, ctx: SchemaVisitorContext): TResult; enum( schema: SchemaWithType<'enum'>, ctx: SchemaVisitorContext, - walk: Walker, - ): SchemaResult; - integer( - schema: SchemaWithType<'integer'>, - ctx: SchemaVisitorContext, - ): SchemaResult; + walk: Walker, + ): TResult; + integer(schema: SchemaWithType<'integer'>, ctx: SchemaVisitorContext): TResult; /** * Called before any dispatch logic. Return a result to short-circuit, * or undefined to continue normal dispatch. @@ -85,63 +60,55 @@ export interface SchemaVisitor { intercept?( schema: IR.SchemaObject, ctx: SchemaVisitorContext, - walk: Walker, - ): SchemaResult | undefined; + walk: Walker, + ): TResult | undefined; /** * Handle intersection types. Receives already-walked child results. */ intersection( - items: Array>, + items: Array, schemas: ReadonlyArray, + parentSchema: IR.SchemaObject, ctx: SchemaVisitorContext, - ): SchemaResult; - never(schema: SchemaWithType<'never'>, ctx: SchemaVisitorContext): SchemaResult; - null(schema: SchemaWithType<'null'>, ctx: SchemaVisitorContext): SchemaResult; - number(schema: SchemaWithType<'number'>, ctx: SchemaVisitorContext): SchemaResult; + ): TResult; + never(schema: SchemaWithType<'never'>, ctx: SchemaVisitorContext): TResult; + null(schema: SchemaWithType<'null'>, ctx: SchemaVisitorContext): TResult; + number(schema: SchemaWithType<'number'>, ctx: SchemaVisitorContext): TResult; object( schema: SchemaWithType<'object'>, ctx: SchemaVisitorContext, - walk: Walker, - ): SchemaResult; + walk: Walker, + ): TResult; /** * Called after each typed schema visitor returns. */ postProcess?( - result: SchemaResult, + result: TResult, schema: IR.SchemaObject, ctx: SchemaVisitorContext, - ): SchemaResult; + ): TResult; /** * Handle $ref to another schema. */ - reference( - $ref: string, - schema: IR.SchemaObject, - ctx: SchemaVisitorContext, - ): SchemaResult; - string(schema: SchemaWithType<'string'>, ctx: SchemaVisitorContext): SchemaResult; + reference($ref: string, schema: IR.SchemaObject, ctx: SchemaVisitorContext): TResult; + string(schema: SchemaWithType<'string'>, ctx: SchemaVisitorContext): TResult; tuple( schema: SchemaWithType<'tuple'>, ctx: SchemaVisitorContext, - walk: Walker, - ): SchemaResult; - undefined( - schema: SchemaWithType<'undefined'>, - ctx: SchemaVisitorContext, - ): SchemaResult; + walk: Walker, + ): TResult; + undefined(schema: SchemaWithType<'undefined'>, ctx: SchemaVisitorContext): TResult; /** * Handle union types. Receives already-walked child results. */ union( - items: Array>, + items: Array, schemas: ReadonlyArray, + parentSchema: IR.SchemaObject, ctx: SchemaVisitorContext, - ): SchemaResult; - unknown( - schema: SchemaWithType<'unknown'>, - ctx: SchemaVisitorContext, - ): SchemaResult; - void(schema: SchemaWithType<'void'>, ctx: SchemaVisitorContext): SchemaResult; + ): TResult; + unknown(schema: SchemaWithType<'unknown'>, ctx: SchemaVisitorContext): TResult; + void(schema: SchemaWithType<'void'>, ctx: SchemaVisitorContext): TResult; } /** @@ -151,12 +118,11 @@ export interface SchemaVisitor { * - Dispatch order ($ref → type → items → fallback) * - Deduplication of union/intersection schemas * - Path tracking for child schemas - * - Calling the appropriate visitor method */ -export function createSchemaWalker( - visitor: SchemaVisitor, -): Walker { - const walk: Walker = (schema, ctx) => { +export function createSchemaWalker( + visitor: SchemaVisitor, +): Walker { + const walk: Walker = (schema, ctx) => { // escape hatch if (visitor.intercept) { const intercepted = visitor.intercept(schema, ctx, walk); @@ -165,18 +131,8 @@ export function createSchemaWalker( } } - const baseResult = { - default: schema.default, - readonly: schema.accessScope === 'read', - }; - if (schema.$ref) { - const result = visitor.reference(schema.$ref, schema, ctx); - return { - ...result, - default: result.default ?? baseResult.default, - readonly: result.readonly || baseResult.readonly, - }; + return visitor.reference(schema.$ref, schema, ctx); } if (schema.type) { @@ -184,11 +140,7 @@ export function createSchemaWalker( if (visitor.postProcess) { result = visitor.postProcess(result, schema, ctx); } - return { - ...result, - default: result.default ?? baseResult.default, - readonly: result.readonly || baseResult.readonly, - }; + return result; } if (schema.items) { @@ -206,25 +158,13 @@ export function createSchemaWalker( }), ); - const result = - deduplicated.logicalOperator === 'and' - ? visitor.intersection(itemResults, deduplicated.items, ctx) - : visitor.union(itemResults, deduplicated.items, ctx); - - return { - ...result, - default: result.default ?? baseResult.default, - readonly: result.readonly || baseResult.readonly, - }; + return deduplicated.logicalOperator === 'and' + ? visitor.intersection(itemResults, deduplicated.items, schema, ctx) + : visitor.union(itemResults, deduplicated.items, schema, ctx); } // fallback - const result = visitor.unknown({ type: 'unknown' }, ctx); - return { - ...result, - default: result.default ?? baseResult.default, - readonly: result.readonly || baseResult.readonly, - }; + return visitor.unknown({ type: 'unknown' }, ctx); }; return walk; @@ -233,12 +173,12 @@ export function createSchemaWalker( /** * Dispatch to the appropriate visitor method based on schema type. */ -function visitTyped( +function visitTyped( schema: SchemaWithType, ctx: SchemaVisitorContext, - visitor: SchemaVisitor, - walk: Walker, -): SchemaResult { + visitor: SchemaVisitor, + walk: Walker, +): TResult { switch (schema.type) { case 'array': return visitor.array(schema as SchemaWithType<'array'>, ctx, walk);