diff --git a/.changeset/eighty-suns-fly.md b/.changeset/eighty-suns-fly.md new file mode 100644 index 000000000..6abd1b900 --- /dev/null +++ b/.changeset/eighty-suns-fly.md @@ -0,0 +1,29 @@ +--- +"@hey-api/openapi-ts": minor +--- + +**plugin(valibot)**: remove request data schema + +### Validator request schemas + +Valibot plugin no longer exports composite request `Data` schemas. Instead, each layer is exported as a separate schema. If you're using validators with SDKs, you can preserve the composite schema with `shouldExtract`: + +```js +export default { + input: 'hey-api/backend', // sign up at app.heyapi.dev + output: 'src/client', + plugins: [ + // ...other plugins + { + name: 'sdk', + validator: 'valibot', + }, + { + name: 'valibot', + requests: { + shouldExtract: true, + }, + }, + ], +}; +``` diff --git a/.changeset/every-vans-sleep.md b/.changeset/every-vans-sleep.md new file mode 100644 index 000000000..d4a4a5628 --- /dev/null +++ b/.changeset/every-vans-sleep.md @@ -0,0 +1,10 @@ +--- +"@hey-api/openapi-ts": minor +"@hey-api/shared": minor +--- + +**internal**: remove `plugin.getSymbol()` function + +### Removed `plugin.getSymbol()` function + +This function has been removed. You can use `plugin.querySymbol()` instead. It accepts the same arguments and returns the same result. diff --git a/.changeset/fine-flies-sink.md b/.changeset/fine-flies-sink.md new file mode 100644 index 000000000..3dcecf313 --- /dev/null +++ b/.changeset/fine-flies-sink.md @@ -0,0 +1,29 @@ +--- +"@hey-api/openapi-ts": minor +--- + +**plugin(zod)**: remove request data schema + +### Validator request schemas + +Zod plugin no longer exports composite request `Data` schemas. Instead, each layer is exported as a separate schema. If you're using validators with SDKs, you can preserve the composite schema with `shouldExtract`: + +```js +export default { + input: 'hey-api/backend', // sign up at app.heyapi.dev + output: 'src/client', + plugins: [ + // ...other plugins + { + name: 'sdk', + validator: 'zod', + }, + { + name: 'zod', + requests: { + shouldExtract: true, + }, + }, + ], +}; +``` diff --git a/.changeset/happy-snails-strive.md b/.changeset/happy-snails-strive.md new file mode 100644 index 000000000..9681abc9e --- /dev/null +++ b/.changeset/happy-snails-strive.md @@ -0,0 +1,5 @@ +--- +"@hey-api/openapi-ts": patch +--- + +**plugin(zod)**: export request body, path, query, and headers schemas diff --git a/.changeset/short-things-leave.md b/.changeset/short-things-leave.md new file mode 100644 index 000000000..3fa44fd51 --- /dev/null +++ b/.changeset/short-things-leave.md @@ -0,0 +1,5 @@ +--- +"@hey-api/shared": patch +--- + +**plugins**: add request validator helpers diff --git a/.changeset/small-beds-travel.md b/.changeset/small-beds-travel.md new file mode 100644 index 000000000..952694252 --- /dev/null +++ b/.changeset/small-beds-travel.md @@ -0,0 +1,5 @@ +--- +"@hey-api/openapi-ts": patch +--- + +**plugin(orpc)**: fix: adjust input shape diff --git a/.changeset/thin-islands-happen.md b/.changeset/thin-islands-happen.md new file mode 100644 index 000000000..ed7ef5c7c --- /dev/null +++ b/.changeset/thin-islands-happen.md @@ -0,0 +1,5 @@ +--- +"@hey-api/openapi-ts": patch +--- + +**plugin(valibot)**: export request body, path, query, and headers schemas diff --git a/docs/openapi-ts/migrating.md b/docs/openapi-ts/migrating.md index cab0480f9..e4a3157ea 100644 --- a/docs/openapi-ts/migrating.md +++ b/docs/openapi-ts/migrating.md @@ -7,6 +7,63 @@ description: Migrating to @hey-api/openapi-ts. While we try to avoid breaking changes, sometimes it's unavoidable in order to offer you the latest features. This page lists changes that require updates to your code. If you run into a problem with migration, please [open an issue](https://github.com/hey-api/openapi-ts/issues). +## v0.95.0 + +### Validator request schemas + +Valibot and Zod plugins no longer export composite request `Data` schemas. Instead, each layer is exported as a separate schema. If you're using validators with SDKs, you can preserve the composite schema with `shouldExtract`: + +::: code-group + + +```js [Zod] +export default { + input: 'hey-api/backend', // sign up at app.heyapi.dev + output: 'src/client', + plugins: [ + // ...other plugins + { + name: 'sdk', + validator: 'zod', + }, + { + name: 'zod', + requests: { // [!code ++] + shouldExtract: true, // [!code ++] + }, // [!code ++] + }, + ], +}; +``` + + +```js [Valibot] +export default { + input: 'hey-api/backend', // sign up at app.heyapi.dev + output: 'src/client', + plugins: [ + // ...other plugins + { + name: 'sdk', + validator: 'valibot', + }, + { + name: 'valibot', + requests: { // [!code ++] + shouldExtract: true, // [!code ++] + }, // [!code ++] + }, + ], +}; +``` + + +::: + +### Removed `plugin.getSymbol()` function + +This function has been removed. You can use `plugin.querySymbol()` instead. It accepts the same arguments and returns the same result. + ## v0.93.0 ### Removed resolver node diff --git a/docs/openapi-ts/plugins/orpc.md b/docs/openapi-ts/plugins/orpc.md index f568214a5..66f8a2112 100644 --- a/docs/openapi-ts/plugins/orpc.md +++ b/docs/openapi-ts/plugins/orpc.md @@ -99,7 +99,7 @@ For a more granular approach, manually add a validator plugin and set `validator ```js [example] import { oc } from '@orpc/contract'; -import { vAddPetData, vAddPetResponse } from './valibot.gen'; +import { vAddPetBody, vAddPetResponse } from './valibot.gen'; const addPet = oc .route({ @@ -111,7 +111,7 @@ const addPet = oc summary: 'Add a new pet to the store.', tags: ['pet'], }) - .input(vAddPetData) // [!code ++] + .input(v.object({ body: vAddPetBody })) // [!code ++] .output(vAddPetResponse); // [!code ++] ``` diff --git a/docs/openapi-ts/plugins/valibot.md b/docs/openapi-ts/plugins/valibot.md index 0d6d3fe65..013cff5ca 100644 --- a/docs/openapi-ts/plugins/valibot.md +++ b/docs/openapi-ts/plugins/valibot.md @@ -68,22 +68,21 @@ The Valibot plugin will generate the following artifacts, depending on the input ## Requests -A single request schema is generated for each endpoint. It may contain a request body, parameters, and headers. +A Valibot schema is generated for every request layer of each endpoint. ::: code-group ```ts [example] -const vData = v.object({ - body: v.optional( - v.object({ - foo: v.optional(v.string()), - bar: v.optional(v.union([v.number(), v.null()])), - }), - ), - path: v.object({ - baz: v.string(), - }), - query: v.optional(v.never()), +const vDeletePetHeaders = v.object({ + api_key: v.optional(v.string()), +}); + +const vDeletePetPath = v.object({ + petId: v.number(), +}); + +const vDeletePetQuery = v.object({ + additionalMetadata: v.string(), }); ``` @@ -103,10 +102,6 @@ export default { ::: -::: tip -If you need to access individual fields, you can do so using the [`.entries`](https://valibot.dev/api/object/) API. For example, we can get the request body schema with `vData.entries.body`. -::: - You can customize the naming and casing pattern for `requests` schemas using the `.name` and `.case` options. ## Responses diff --git a/docs/openapi-ts/plugins/zod.md b/docs/openapi-ts/plugins/zod.md index ba8da9c6d..7c471ceef 100644 --- a/docs/openapi-ts/plugins/zod.md +++ b/docs/openapi-ts/plugins/zod.md @@ -68,22 +68,21 @@ The Zod plugin will generate the following artifacts, depending on the input spe ## Requests -A single request schema is generated for each endpoint. It may contain a request body, parameters, and headers. +A Zod schema is generated for every request layer of each endpoint. ::: code-group ```ts [example] -const zData = z.object({ - body: z - .object({ - foo: z.optional(z.string()), - bar: z.optional(z.union([z.number(), z.null()])), - }) - .optional(), - path: z.object({ - baz: z.string(), - }), - query: z.optional(z.never()), +const zDeletePetHeaders = z.object({ + api_key: z.string().optional(), +}); + +const zDeletePetPath = z.object({ + petId: z.number(), +}); + +const zDeletePetQuery = z.object({ + additionalMetadata: z.string(), }); ``` @@ -103,10 +102,6 @@ export default { ::: -::: tip -If you need to access individual fields, you can do so using the [`.shape`](https://zod.dev/api?id=shape) API. For example, we can get the request body schema with `zData.shape.body`. -::: - You can customize the naming and casing pattern for `requests` schemas using the `.name` and `.case` options. ## Responses diff --git a/docs/openapi-ts/plugins/zod/mini.md b/docs/openapi-ts/plugins/zod/mini.md index 5b2684c73..5ad63ee72 100644 --- a/docs/openapi-ts/plugins/zod/mini.md +++ b/docs/openapi-ts/plugins/zod/mini.md @@ -74,22 +74,21 @@ The Zod plugin will generate the following artifacts, depending on the input spe ## Requests -A single request schema is generated for each endpoint. It may contain a request body, parameters, and headers. +A Zod schema is generated for every request layer of each endpoint. ::: code-group ```ts [example] -const zData = z.object({ - body: z - .object({ - foo: z.optional(z.string()), - bar: z.optional(z.union([z.number(), z.null()])), - }) - .optional(), - path: z.object({ - baz: z.string(), - }), - query: z.optional(z.never()), +const zDeletePetHeaders = z.object({ + api_key: z.optional(z.string()), +}); + +const zDeletePetPath = z.object({ + petId: z.number(), +}); + +const zDeletePetQuery = z.object({ + additionalMetadata: z.string(), }); ``` @@ -110,10 +109,6 @@ export default { ::: -::: tip -If you need to access individual fields, you can do so using the [`.def.shape`](https://zod.dev/api?id=shape) API. For example, we can get the request body schema with `zData.def.shape.body`. -::: - You can customize the naming and casing pattern for `requests` schemas using the `.name` and `.case` options. ## Responses diff --git a/docs/openapi-ts/plugins/zod/v3.md b/docs/openapi-ts/plugins/zod/v3.md index 33bc1a397..416902d5e 100644 --- a/docs/openapi-ts/plugins/zod/v3.md +++ b/docs/openapi-ts/plugins/zod/v3.md @@ -74,22 +74,21 @@ The Zod plugin will generate the following artifacts, depending on the input spe ## Requests -A single request schema is generated for each endpoint. It may contain a request body, parameters, and headers. +A Zod schema is generated for every request layer of each endpoint. ::: code-group ```ts [example] -const zData = z.object({ - body: z - .object({ - foo: z.string().optional(), - bar: z.union([z.number(), z.null()]).optional(), - }) - .optional(), - path: z.object({ - baz: z.string(), - }), - query: z.never().optional(), +const zDeletePetHeaders = z.object({ + api_key: z.string().optional(), +}); + +const zDeletePetPath = z.object({ + petId: z.number(), +}); + +const zDeletePetQuery = z.object({ + additionalMetadata: z.string(), }); ``` @@ -110,10 +109,6 @@ export default { ::: -::: tip -If you need to access individual fields, you can do so using the [`.shape`](https://v3.zod.dev/?id=shape) API. For example, we can get the request body schema with `zData.shape.body`. -::: - You can customize the naming and casing pattern for `requests` schemas using the `.name` and `.case` options. ## Responses diff --git a/packages/openapi-python/src/plugins/pydantic/shared/processor.ts b/packages/openapi-python/src/plugins/pydantic/shared/processor.ts index d95ebf915..a0e9840f3 100644 --- a/packages/openapi-python/src/plugins/pydantic/shared/processor.ts +++ b/packages/openapi-python/src/plugins/pydantic/shared/processor.ts @@ -1,4 +1,4 @@ -import type { IR, NamingConfig, SchemaProcessorContext } from '@hey-api/shared'; +import type { NamingConfig, SchemaProcessorContext } from '@hey-api/shared'; import type { PydanticPlugin } from '../types'; import type { PydanticFinal } from './types'; @@ -9,7 +9,6 @@ export type ProcessorContext = SchemaProcessorContext & { naming: NamingConfig; /** The plugin instance. */ plugin: PydanticPlugin['Instance']; - schema: IR.SchemaObject; }; export type ProcessorResult = { diff --git a/packages/openapi-python/src/plugins/pydantic/v2/processor.ts b/packages/openapi-python/src/plugins/pydantic/v2/processor.ts index 23de6f1a2..e67227acc 100644 --- a/packages/openapi-python/src/plugins/pydantic/v2/processor.ts +++ b/packages/openapi-python/src/plugins/pydantic/v2/processor.ts @@ -30,7 +30,7 @@ export function createProcessor(plugin: PydanticPlugin['Instance']): ProcessorRe } for (const hook of extractorHooks) { - const result = hook?.(ctx); + const result = typeof hook === 'boolean' ? hook : (hook?.(ctx) ?? false); if (result) { process({ namingAnchor: processor.context.anchor, diff --git a/packages/openapi-python/src/plugins/pydantic/v2/walker.ts b/packages/openapi-python/src/plugins/pydantic/v2/walker.ts index fb49c9f71..e4799eb24 100644 --- a/packages/openapi-python/src/plugins/pydantic/v2/walker.ts +++ b/packages/openapi-python/src/plugins/pydantic/v2/walker.ts @@ -29,7 +29,7 @@ export interface VisitorConfig { } export function createVisitor( - config: VisitorConfig, + config: VisitorConfig = {}, ): SchemaVisitor { const { schemaExtractor } = config; diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/custom-names/orpc.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/custom-names/orpc.gen.ts index 92b5ebf1d..d36cc48df 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/custom-names/orpc.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/custom-names/orpc.gen.ts @@ -1,8 +1,9 @@ // This file is auto-generated by @hey-api/openapi-ts import { oc } from '@orpc/contract'; +import * as v from 'valibot'; -import { vCreatePostData, vCreatePostResponse, vCreateUserData, vCreateUserResponse, vDeleteUserData, vGetPostByIdData, vGetPostByIdResponse, vGetPostsData, vGetPostsResponse, vGetUserByIdData, vGetUserByIdResponse, vGetUsersData, vGetUsersResponse, vUpdateUserData, vUpdateUserResponse } from './valibot.gen'; +import { vCreatePostBody, vCreatePostHeaders, vCreatePostResponse, vCreateUserBody, vCreateUserResponse, vDeleteUserHeaders, vDeleteUserPath, vGetPostByIdPath, vGetPostByIdQuery, vGetPostByIdResponse, vGetPostsQuery, vGetPostsResponse, vGetUserByIdPath, vGetUserByIdResponse, vGetUsersQuery, vGetUsersResponse, vUpdateUserBody, vUpdateUserPath, vUpdateUserResponse } from './valibot.gen'; /** * Get all users @@ -14,7 +15,7 @@ export const getUsersRpc = oc.route({ path: '/users', summary: 'Get all users', tags: ['users'] -}).input(vGetUsersData).output(vGetUsersResponse); +}).input(v.object({ query: v.optional(vGetUsersQuery) })).output(vGetUsersResponse); /** * Create a new user @@ -27,7 +28,7 @@ export const createUserRpc = oc.route({ successStatus: 201, summary: 'Create a new user', tags: ['users'] -}).input(vCreateUserData).output(vCreateUserResponse); +}).input(v.object({ body: vCreateUserBody })).output(vCreateUserResponse); /** * Delete a user @@ -39,7 +40,7 @@ export const deleteUserRpc = oc.route({ path: '/users/{userId}', summary: 'Delete a user', tags: ['users'] -}).input(vDeleteUserData); +}).input(v.object({ headers: v.optional(vDeleteUserHeaders), params: vDeleteUserPath })); /** * Get a user by ID @@ -51,7 +52,7 @@ export const getUserByIdRpc = oc.route({ path: '/users/{userId}', summary: 'Get a user by ID', tags: ['users'] -}).input(vGetUserByIdData).output(vGetUserByIdResponse); +}).input(v.object({ params: vGetUserByIdPath })).output(vGetUserByIdResponse); /** * Update a user @@ -63,7 +64,7 @@ export const updateUserRpc = oc.route({ path: '/users/{userId}', summary: 'Update a user', tags: ['users'] -}).input(vUpdateUserData).output(vUpdateUserResponse); +}).input(v.object({ body: vUpdateUserBody, params: vUpdateUserPath })).output(vUpdateUserResponse); /** * Get all posts @@ -75,7 +76,7 @@ export const getPostsRpc = oc.route({ path: '/posts', summary: 'Get all posts', tags: ['posts'] -}).input(vGetPostsData).output(vGetPostsResponse); +}).input(v.object({ query: v.optional(vGetPostsQuery) })).output(vGetPostsResponse); /** * Create a new post @@ -88,7 +89,7 @@ export const createPostRpc = oc.route({ successStatus: 201, summary: 'Create a new post', tags: ['posts'] -}).input(vCreatePostData).output(vCreatePostResponse); +}).input(v.object({ body: vCreatePostBody, headers: vCreatePostHeaders })).output(vCreatePostResponse); /** * Get a post by ID @@ -100,7 +101,7 @@ export const getPostByIdRpc = oc.route({ path: '/posts/{postId}', summary: 'Get a post by ID', tags: ['posts'] -}).input(vGetPostByIdData).output(vGetPostByIdResponse); +}).input(v.object({ params: vGetPostByIdPath, query: v.optional(vGetPostByIdQuery) })).output(vGetPostByIdResponse); export const rpcContract = { getUsersRpc, diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/custom-names/valibot.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/custom-names/valibot.gen.ts index 9f5c64637..2a058ce74 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/custom-names/valibot.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/custom-names/valibot.gen.ts @@ -39,13 +39,9 @@ export const vCreatePostInput = v.object({ status: v.optional(v.picklist(['draft', 'published'])) }); -export const vGetUsersData = v.object({ - body: v.optional(v.never()), - path: v.optional(v.never()), - query: v.optional(v.object({ - limit: v.optional(v.pipe(v.number(), v.integer()), 10), - offset: v.optional(v.pipe(v.number(), v.integer()), 0) - })) +export const vGetUsersQuery = v.object({ + limit: v.optional(v.pipe(v.number(), v.integer()), 10), + offset: v.optional(v.pipe(v.number(), v.integer()), 0) }); /** @@ -53,26 +49,19 @@ export const vGetUsersData = v.object({ */ export const vGetUsersResponse = v.array(vUser); -export const vCreateUserData = v.object({ - body: vCreateUserInput, - path: v.optional(v.never()), - query: v.optional(v.never()) -}); +export const vCreateUserBody = vCreateUserInput; /** * User created */ export const vCreateUserResponse = vUser; -export const vDeleteUserData = v.object({ - body: v.optional(v.never()), - path: v.object({ - userId: v.string() - }), - query: v.optional(v.never()), - headers: v.optional(v.object({ - 'X-Request-Id': v.optional(v.string()) - })) +export const vDeleteUserHeaders = v.object({ + 'X-Request-Id': v.optional(v.string()) +}); + +export const vDeleteUserPath = v.object({ + userId: v.string() }); /** @@ -80,12 +69,8 @@ export const vDeleteUserData = v.object({ */ export const vDeleteUserResponse = v.void(); -export const vGetUserByIdData = v.object({ - body: v.optional(v.never()), - path: v.object({ - userId: v.string() - }), - query: v.optional(v.never()) +export const vGetUserByIdPath = v.object({ + userId: v.string() }); /** @@ -93,12 +78,10 @@ export const vGetUserByIdData = v.object({ */ export const vGetUserByIdResponse = vUser; -export const vUpdateUserData = v.object({ - body: vUpdateUserInput, - path: v.object({ - userId: v.string() - }), - query: v.optional(v.never()) +export const vUpdateUserBody = vUpdateUserInput; + +export const vUpdateUserPath = v.object({ + userId: v.string() }); /** @@ -106,17 +89,13 @@ export const vUpdateUserData = v.object({ */ export const vUpdateUserResponse = vUser; -export const vGetPostsData = v.object({ - body: v.optional(v.never()), - path: v.optional(v.never()), - query: v.optional(v.object({ - authorId: v.optional(v.string()), - status: v.optional(v.picklist([ - 'draft', - 'published', - 'archived' - ])) - })) +export const vGetPostsQuery = v.object({ + authorId: v.optional(v.string()), + status: v.optional(v.picklist([ + 'draft', + 'published', + 'archived' + ])) }); /** @@ -124,13 +103,10 @@ export const vGetPostsData = v.object({ */ export const vGetPostsResponse = v.array(vPost); -export const vCreatePostData = v.object({ - body: vCreatePostInput, - path: v.optional(v.never()), - query: v.optional(v.never()), - headers: v.object({ - 'X-Author-Id': v.string() - }) +export const vCreatePostBody = vCreatePostInput; + +export const vCreatePostHeaders = v.object({ + 'X-Author-Id': v.string() }); /** @@ -138,14 +114,12 @@ export const vCreatePostData = v.object({ */ export const vCreatePostResponse = vPost; -export const vGetPostByIdData = v.object({ - body: v.optional(v.never()), - path: v.object({ - postId: v.string() - }), - query: v.optional(v.object({ - includeComments: v.optional(v.boolean(), false) - })) +export const vGetPostByIdPath = v.object({ + postId: v.string() +}); + +export const vGetPostByIdQuery = v.object({ + includeComments: v.optional(v.boolean(), false) }); /** diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/default/orpc.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/default/orpc.gen.ts index 6e9637158..6df6e41ab 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/default/orpc.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/default/orpc.gen.ts @@ -1,8 +1,9 @@ // This file is auto-generated by @hey-api/openapi-ts import { oc } from '@orpc/contract'; +import * as z from 'zod'; -import { zCreatePostData, zCreatePostResponse, zCreateUserData, zCreateUserResponse, zDeleteUserData, zGetPostByIdData, zGetPostByIdResponse, zGetPostsData, zGetPostsResponse, zGetUserByIdData, zGetUserByIdResponse, zGetUsersData, zGetUsersResponse, zUpdateUserData, zUpdateUserResponse } from './zod.gen'; +import { zCreatePostBody, zCreatePostHeaders, zCreatePostResponse, zCreateUserBody, zCreateUserResponse, zDeleteUserHeaders, zDeleteUserPath, zGetPostByIdPath, zGetPostByIdQuery, zGetPostByIdResponse, zGetPostsQuery, zGetPostsResponse, zGetUserByIdPath, zGetUserByIdResponse, zGetUsersQuery, zGetUsersResponse, zUpdateUserBody, zUpdateUserPath, zUpdateUserResponse } from './zod.gen'; /** * Get all users @@ -14,7 +15,7 @@ export const getUsers = oc.route({ path: '/users', summary: 'Get all users', tags: ['users'] -}).input(zGetUsersData).output(zGetUsersResponse); +}).input(z.object({ query: zGetUsersQuery.optional() })).output(zGetUsersResponse); /** * Create a new user @@ -27,7 +28,7 @@ export const createUser = oc.route({ successStatus: 201, summary: 'Create a new user', tags: ['users'] -}).input(zCreateUserData).output(zCreateUserResponse); +}).input(z.object({ body: zCreateUserBody })).output(zCreateUserResponse); /** * Delete a user @@ -39,7 +40,7 @@ export const deleteUser = oc.route({ path: '/users/{userId}', summary: 'Delete a user', tags: ['users'] -}).input(zDeleteUserData); +}).input(z.object({ headers: zDeleteUserHeaders.optional(), params: zDeleteUserPath })); /** * Get a user by ID @@ -51,7 +52,7 @@ export const getUserById = oc.route({ path: '/users/{userId}', summary: 'Get a user by ID', tags: ['users'] -}).input(zGetUserByIdData).output(zGetUserByIdResponse); +}).input(z.object({ params: zGetUserByIdPath })).output(zGetUserByIdResponse); /** * Update a user @@ -63,7 +64,7 @@ export const updateUser = oc.route({ path: '/users/{userId}', summary: 'Update a user', tags: ['users'] -}).input(zUpdateUserData).output(zUpdateUserResponse); +}).input(z.object({ body: zUpdateUserBody, params: zUpdateUserPath })).output(zUpdateUserResponse); /** * Get all posts @@ -75,7 +76,7 @@ export const getPosts = oc.route({ path: '/posts', summary: 'Get all posts', tags: ['posts'] -}).input(zGetPostsData).output(zGetPostsResponse); +}).input(z.object({ query: zGetPostsQuery.optional() })).output(zGetPostsResponse); /** * Create a new post @@ -88,7 +89,7 @@ export const createPost = oc.route({ successStatus: 201, summary: 'Create a new post', tags: ['posts'] -}).input(zCreatePostData).output(zCreatePostResponse); +}).input(z.object({ body: zCreatePostBody, headers: zCreatePostHeaders })).output(zCreatePostResponse); /** * Get a post by ID @@ -100,7 +101,7 @@ export const getPostById = oc.route({ path: '/posts/{postId}', summary: 'Get a post by ID', tags: ['posts'] -}).input(zGetPostByIdData).output(zGetPostByIdResponse); +}).input(z.object({ params: zGetPostByIdPath, query: zGetPostByIdQuery.optional() })).output(zGetPostByIdResponse); export const contract = { getUsers, diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/default/zod.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/default/zod.gen.ts index f43f854eb..449df619c 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/default/zod.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.0.x/default/zod.gen.ts @@ -39,13 +39,9 @@ export const zCreatePostInput = z.object({ status: z.enum(['draft', 'published']).optional() }); -export const zGetUsersData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - limit: z.int().optional().default(10), - offset: z.int().optional().default(0) - }).optional() +export const zGetUsersQuery = z.object({ + limit: z.int().optional().default(10), + offset: z.int().optional().default(0) }); /** @@ -53,26 +49,19 @@ export const zGetUsersData = z.object({ */ export const zGetUsersResponse = z.array(zUser); -export const zCreateUserData = z.object({ - body: zCreateUserInput, - path: z.never().optional(), - query: z.never().optional() -}); +export const zCreateUserBody = zCreateUserInput; /** * User created */ export const zCreateUserResponse = zUser; -export const zDeleteUserData = z.object({ - body: z.never().optional(), - path: z.object({ - userId: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'X-Request-Id': z.string().optional() - }).optional() +export const zDeleteUserHeaders = z.object({ + 'X-Request-Id': z.string().optional() +}); + +export const zDeleteUserPath = z.object({ + userId: z.string() }); /** @@ -80,12 +69,8 @@ export const zDeleteUserData = z.object({ */ export const zDeleteUserResponse = z.void(); -export const zGetUserByIdData = z.object({ - body: z.never().optional(), - path: z.object({ - userId: z.string() - }), - query: z.never().optional() +export const zGetUserByIdPath = z.object({ + userId: z.string() }); /** @@ -93,12 +78,10 @@ export const zGetUserByIdData = z.object({ */ export const zGetUserByIdResponse = zUser; -export const zUpdateUserData = z.object({ - body: zUpdateUserInput, - path: z.object({ - userId: z.string() - }), - query: z.never().optional() +export const zUpdateUserBody = zUpdateUserInput; + +export const zUpdateUserPath = z.object({ + userId: z.string() }); /** @@ -106,17 +89,13 @@ export const zUpdateUserData = z.object({ */ export const zUpdateUserResponse = zUser; -export const zGetPostsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - authorId: z.string().optional(), - status: z.enum([ - 'draft', - 'published', - 'archived' - ]).optional() - }).optional() +export const zGetPostsQuery = z.object({ + authorId: z.string().optional(), + status: z.enum([ + 'draft', + 'published', + 'archived' + ]).optional() }); /** @@ -124,13 +103,10 @@ export const zGetPostsData = z.object({ */ export const zGetPostsResponse = z.array(zPost); -export const zCreatePostData = z.object({ - body: zCreatePostInput, - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - 'X-Author-Id': z.string() - }) +export const zCreatePostBody = zCreatePostInput; + +export const zCreatePostHeaders = z.object({ + 'X-Author-Id': z.string() }); /** @@ -138,14 +114,12 @@ export const zCreatePostData = z.object({ */ export const zCreatePostResponse = zPost; -export const zGetPostByIdData = z.object({ - body: z.never().optional(), - path: z.object({ - postId: z.string() - }), - query: z.object({ - includeComments: z.boolean().optional().default(false) - }).optional() +export const zGetPostByIdPath = z.object({ + postId: z.string() +}); + +export const zGetPostByIdQuery = z.object({ + includeComments: z.boolean().optional().default(false) }); /** diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-custom-naming/orpc.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-custom-naming/orpc.gen.ts index de6c8c4f6..feef55aa8 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-custom-naming/orpc.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-custom-naming/orpc.gen.ts @@ -1,8 +1,9 @@ // This file is auto-generated by @hey-api/openapi-ts import { oc } from '@orpc/contract'; +import * as z from 'zod'; -import { zCreatePostData, zCreatePostResponse, zCreateUserData, zCreateUserResponse, zDeleteUserData, zGetPostByIdData, zGetPostByIdResponse, zGetPostsData, zGetPostsResponse, zGetUserByIdData, zGetUserByIdResponse, zGetUsersData, zGetUsersResponse, zUpdateUserData, zUpdateUserResponse } from './zod.gen'; +import { zCreatePostBody, zCreatePostHeaders, zCreatePostResponse, zCreateUserBody, zCreateUserResponse, zDeleteUserHeaders, zDeleteUserPath, zGetPostByIdPath, zGetPostByIdQuery, zGetPostByIdResponse, zGetPostsQuery, zGetPostsResponse, zGetUserByIdPath, zGetUserByIdResponse, zGetUsersQuery, zGetUsersResponse, zUpdateUserBody, zUpdateUserPath, zUpdateUserResponse } from './zod.gen'; /** * Get all users @@ -14,7 +15,7 @@ export const GetUsers = oc.route({ path: '/users', summary: 'Get all users', tags: ['users'] -}).input(zGetUsersData).output(zGetUsersResponse); +}).input(z.object({ query: zGetUsersQuery.optional() })).output(zGetUsersResponse); /** * Create a new user @@ -27,7 +28,7 @@ export const CreateUser = oc.route({ successStatus: 201, summary: 'Create a new user', tags: ['users'] -}).input(zCreateUserData).output(zCreateUserResponse); +}).input(z.object({ body: zCreateUserBody })).output(zCreateUserResponse); /** * Delete a user @@ -39,7 +40,7 @@ export const DeleteUser = oc.route({ path: '/users/{userId}', summary: 'Delete a user', tags: ['users'] -}).input(zDeleteUserData); +}).input(z.object({ headers: zDeleteUserHeaders.optional(), params: zDeleteUserPath })); /** * Get a user by ID @@ -51,7 +52,7 @@ export const GetUserById = oc.route({ path: '/users/{userId}', summary: 'Get a user by ID', tags: ['users'] -}).input(zGetUserByIdData).output(zGetUserByIdResponse); +}).input(z.object({ params: zGetUserByIdPath })).output(zGetUserByIdResponse); /** * Update a user @@ -63,7 +64,7 @@ export const UpdateUser = oc.route({ path: '/users/{userId}', summary: 'Update a user', tags: ['users'] -}).input(zUpdateUserData).output(zUpdateUserResponse); +}).input(z.object({ body: zUpdateUserBody, params: zUpdateUserPath })).output(zUpdateUserResponse); export const usersContracts = { GetUsers, @@ -83,7 +84,7 @@ export const GetPosts = oc.route({ path: '/posts', summary: 'Get all posts', tags: ['posts'] -}).input(zGetPostsData).output(zGetPostsResponse); +}).input(z.object({ query: zGetPostsQuery.optional() })).output(zGetPostsResponse); /** * Create a new post @@ -96,7 +97,7 @@ export const CreatePost = oc.route({ successStatus: 201, summary: 'Create a new post', tags: ['posts'] -}).input(zCreatePostData).output(zCreatePostResponse); +}).input(z.object({ body: zCreatePostBody, headers: zCreatePostHeaders })).output(zCreatePostResponse); /** * Get a post by ID @@ -108,7 +109,7 @@ export const GetPostById = oc.route({ path: '/posts/{postId}', summary: 'Get a post by ID', tags: ['posts'] -}).input(zGetPostByIdData).output(zGetPostByIdResponse); +}).input(z.object({ params: zGetPostByIdPath, query: zGetPostByIdQuery.optional() })).output(zGetPostByIdResponse); export const postsContracts = { GetPosts, diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-custom-naming/zod.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-custom-naming/zod.gen.ts index f43f854eb..449df619c 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-custom-naming/zod.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-custom-naming/zod.gen.ts @@ -39,13 +39,9 @@ export const zCreatePostInput = z.object({ status: z.enum(['draft', 'published']).optional() }); -export const zGetUsersData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - limit: z.int().optional().default(10), - offset: z.int().optional().default(0) - }).optional() +export const zGetUsersQuery = z.object({ + limit: z.int().optional().default(10), + offset: z.int().optional().default(0) }); /** @@ -53,26 +49,19 @@ export const zGetUsersData = z.object({ */ export const zGetUsersResponse = z.array(zUser); -export const zCreateUserData = z.object({ - body: zCreateUserInput, - path: z.never().optional(), - query: z.never().optional() -}); +export const zCreateUserBody = zCreateUserInput; /** * User created */ export const zCreateUserResponse = zUser; -export const zDeleteUserData = z.object({ - body: z.never().optional(), - path: z.object({ - userId: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'X-Request-Id': z.string().optional() - }).optional() +export const zDeleteUserHeaders = z.object({ + 'X-Request-Id': z.string().optional() +}); + +export const zDeleteUserPath = z.object({ + userId: z.string() }); /** @@ -80,12 +69,8 @@ export const zDeleteUserData = z.object({ */ export const zDeleteUserResponse = z.void(); -export const zGetUserByIdData = z.object({ - body: z.never().optional(), - path: z.object({ - userId: z.string() - }), - query: z.never().optional() +export const zGetUserByIdPath = z.object({ + userId: z.string() }); /** @@ -93,12 +78,10 @@ export const zGetUserByIdData = z.object({ */ export const zGetUserByIdResponse = zUser; -export const zUpdateUserData = z.object({ - body: zUpdateUserInput, - path: z.object({ - userId: z.string() - }), - query: z.never().optional() +export const zUpdateUserBody = zUpdateUserInput; + +export const zUpdateUserPath = z.object({ + userId: z.string() }); /** @@ -106,17 +89,13 @@ export const zUpdateUserData = z.object({ */ export const zUpdateUserResponse = zUser; -export const zGetPostsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - authorId: z.string().optional(), - status: z.enum([ - 'draft', - 'published', - 'archived' - ]).optional() - }).optional() +export const zGetPostsQuery = z.object({ + authorId: z.string().optional(), + status: z.enum([ + 'draft', + 'published', + 'archived' + ]).optional() }); /** @@ -124,13 +103,10 @@ export const zGetPostsData = z.object({ */ export const zGetPostsResponse = z.array(zPost); -export const zCreatePostData = z.object({ - body: zCreatePostInput, - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - 'X-Author-Id': z.string() - }) +export const zCreatePostBody = zCreatePostInput; + +export const zCreatePostHeaders = z.object({ + 'X-Author-Id': z.string() }); /** @@ -138,14 +114,12 @@ export const zCreatePostData = z.object({ */ export const zCreatePostResponse = zPost; -export const zGetPostByIdData = z.object({ - body: z.never().optional(), - path: z.object({ - postId: z.string() - }), - query: z.object({ - includeComments: z.boolean().optional().default(false) - }).optional() +export const zGetPostByIdPath = z.object({ + postId: z.string() +}); + +export const zGetPostByIdQuery = z.object({ + includeComments: z.boolean().optional().default(false) }); /** diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-nesting-id/orpc.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-nesting-id/orpc.gen.ts index d84b1c877..814d8b4ea 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-nesting-id/orpc.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-nesting-id/orpc.gen.ts @@ -1,8 +1,9 @@ // This file is auto-generated by @hey-api/openapi-ts import { oc } from '@orpc/contract'; +import * as z from 'zod'; -import { zCreatePostData, zCreatePostResponse, zCreateUserData, zCreateUserResponse, zDeleteUserData, zGetPostByIdData, zGetPostByIdResponse, zGetPostsData, zGetPostsResponse, zGetUserByIdData, zGetUserByIdResponse, zGetUsersData, zGetUsersResponse, zUpdateUserData, zUpdateUserResponse } from './zod.gen'; +import { zCreatePostBody, zCreatePostHeaders, zCreatePostResponse, zCreateUserBody, zCreateUserResponse, zDeleteUserHeaders, zDeleteUserPath, zGetPostByIdPath, zGetPostByIdQuery, zGetPostByIdResponse, zGetPostsQuery, zGetPostsResponse, zGetUserByIdPath, zGetUserByIdResponse, zGetUsersQuery, zGetUsersResponse, zUpdateUserBody, zUpdateUserPath, zUpdateUserResponse } from './zod.gen'; /** * Get all users @@ -14,7 +15,7 @@ export const getUsers = oc.route({ path: '/users', summary: 'Get all users', tags: ['users'] -}).input(zGetUsersData).output(zGetUsersResponse); +}).input(z.object({ query: zGetUsersQuery.optional() })).output(zGetUsersResponse); /** * Create a new user @@ -27,7 +28,7 @@ export const createUser = oc.route({ successStatus: 201, summary: 'Create a new user', tags: ['users'] -}).input(zCreateUserData).output(zCreateUserResponse); +}).input(z.object({ body: zCreateUserBody })).output(zCreateUserResponse); /** * Delete a user @@ -39,7 +40,7 @@ export const deleteUser = oc.route({ path: '/users/{userId}', summary: 'Delete a user', tags: ['users'] -}).input(zDeleteUserData); +}).input(z.object({ headers: zDeleteUserHeaders.optional(), params: zDeleteUserPath })); /** * Get a user by ID @@ -51,7 +52,7 @@ export const getUserById = oc.route({ path: '/users/{userId}', summary: 'Get a user by ID', tags: ['users'] -}).input(zGetUserByIdData).output(zGetUserByIdResponse); +}).input(z.object({ params: zGetUserByIdPath })).output(zGetUserByIdResponse); /** * Update a user @@ -63,7 +64,7 @@ export const updateUser = oc.route({ path: '/users/{userId}', summary: 'Update a user', tags: ['users'] -}).input(zUpdateUserData).output(zUpdateUserResponse); +}).input(z.object({ body: zUpdateUserBody, params: zUpdateUserPath })).output(zUpdateUserResponse); export const users = { getUsers, @@ -83,7 +84,7 @@ export const getPosts = oc.route({ path: '/posts', summary: 'Get all posts', tags: ['posts'] -}).input(zGetPostsData).output(zGetPostsResponse); +}).input(z.object({ query: zGetPostsQuery.optional() })).output(zGetPostsResponse); /** * Create a new post @@ -96,7 +97,7 @@ export const createPost = oc.route({ successStatus: 201, summary: 'Create a new post', tags: ['posts'] -}).input(zCreatePostData).output(zCreatePostResponse); +}).input(z.object({ body: zCreatePostBody, headers: zCreatePostHeaders })).output(zCreatePostResponse); /** * Get a post by ID @@ -108,7 +109,7 @@ export const getPostById = oc.route({ path: '/posts/{postId}', summary: 'Get a post by ID', tags: ['posts'] -}).input(zGetPostByIdData).output(zGetPostByIdResponse); +}).input(z.object({ params: zGetPostByIdPath, query: zGetPostByIdQuery.optional() })).output(zGetPostByIdResponse); export const posts = { getPosts, diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-nesting-id/zod.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-nesting-id/zod.gen.ts index f43f854eb..449df619c 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-nesting-id/zod.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-nesting-id/zod.gen.ts @@ -39,13 +39,9 @@ export const zCreatePostInput = z.object({ status: z.enum(['draft', 'published']).optional() }); -export const zGetUsersData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - limit: z.int().optional().default(10), - offset: z.int().optional().default(0) - }).optional() +export const zGetUsersQuery = z.object({ + limit: z.int().optional().default(10), + offset: z.int().optional().default(0) }); /** @@ -53,26 +49,19 @@ export const zGetUsersData = z.object({ */ export const zGetUsersResponse = z.array(zUser); -export const zCreateUserData = z.object({ - body: zCreateUserInput, - path: z.never().optional(), - query: z.never().optional() -}); +export const zCreateUserBody = zCreateUserInput; /** * User created */ export const zCreateUserResponse = zUser; -export const zDeleteUserData = z.object({ - body: z.never().optional(), - path: z.object({ - userId: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'X-Request-Id': z.string().optional() - }).optional() +export const zDeleteUserHeaders = z.object({ + 'X-Request-Id': z.string().optional() +}); + +export const zDeleteUserPath = z.object({ + userId: z.string() }); /** @@ -80,12 +69,8 @@ export const zDeleteUserData = z.object({ */ export const zDeleteUserResponse = z.void(); -export const zGetUserByIdData = z.object({ - body: z.never().optional(), - path: z.object({ - userId: z.string() - }), - query: z.never().optional() +export const zGetUserByIdPath = z.object({ + userId: z.string() }); /** @@ -93,12 +78,10 @@ export const zGetUserByIdData = z.object({ */ export const zGetUserByIdResponse = zUser; -export const zUpdateUserData = z.object({ - body: zUpdateUserInput, - path: z.object({ - userId: z.string() - }), - query: z.never().optional() +export const zUpdateUserBody = zUpdateUserInput; + +export const zUpdateUserPath = z.object({ + userId: z.string() }); /** @@ -106,17 +89,13 @@ export const zUpdateUserData = z.object({ */ export const zUpdateUserResponse = zUser; -export const zGetPostsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - authorId: z.string().optional(), - status: z.enum([ - 'draft', - 'published', - 'archived' - ]).optional() - }).optional() +export const zGetPostsQuery = z.object({ + authorId: z.string().optional(), + status: z.enum([ + 'draft', + 'published', + 'archived' + ]).optional() }); /** @@ -124,13 +103,10 @@ export const zGetPostsData = z.object({ */ export const zGetPostsResponse = z.array(zPost); -export const zCreatePostData = z.object({ - body: zCreatePostInput, - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - 'X-Author-Id': z.string() - }) +export const zCreatePostBody = zCreatePostInput; + +export const zCreatePostHeaders = z.object({ + 'X-Author-Id': z.string() }); /** @@ -138,14 +114,12 @@ export const zCreatePostData = z.object({ */ export const zCreatePostResponse = zPost; -export const zGetPostByIdData = z.object({ - body: z.never().optional(), - path: z.object({ - postId: z.string() - }), - query: z.object({ - includeComments: z.boolean().optional().default(false) - }).optional() +export const zGetPostByIdPath = z.object({ + postId: z.string() +}); + +export const zGetPostByIdQuery = z.object({ + includeComments: z.boolean().optional().default(false) }); /** diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-by-tags/orpc.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-by-tags/orpc.gen.ts index d84b1c877..814d8b4ea 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-by-tags/orpc.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-by-tags/orpc.gen.ts @@ -1,8 +1,9 @@ // This file is auto-generated by @hey-api/openapi-ts import { oc } from '@orpc/contract'; +import * as z from 'zod'; -import { zCreatePostData, zCreatePostResponse, zCreateUserData, zCreateUserResponse, zDeleteUserData, zGetPostByIdData, zGetPostByIdResponse, zGetPostsData, zGetPostsResponse, zGetUserByIdData, zGetUserByIdResponse, zGetUsersData, zGetUsersResponse, zUpdateUserData, zUpdateUserResponse } from './zod.gen'; +import { zCreatePostBody, zCreatePostHeaders, zCreatePostResponse, zCreateUserBody, zCreateUserResponse, zDeleteUserHeaders, zDeleteUserPath, zGetPostByIdPath, zGetPostByIdQuery, zGetPostByIdResponse, zGetPostsQuery, zGetPostsResponse, zGetUserByIdPath, zGetUserByIdResponse, zGetUsersQuery, zGetUsersResponse, zUpdateUserBody, zUpdateUserPath, zUpdateUserResponse } from './zod.gen'; /** * Get all users @@ -14,7 +15,7 @@ export const getUsers = oc.route({ path: '/users', summary: 'Get all users', tags: ['users'] -}).input(zGetUsersData).output(zGetUsersResponse); +}).input(z.object({ query: zGetUsersQuery.optional() })).output(zGetUsersResponse); /** * Create a new user @@ -27,7 +28,7 @@ export const createUser = oc.route({ successStatus: 201, summary: 'Create a new user', tags: ['users'] -}).input(zCreateUserData).output(zCreateUserResponse); +}).input(z.object({ body: zCreateUserBody })).output(zCreateUserResponse); /** * Delete a user @@ -39,7 +40,7 @@ export const deleteUser = oc.route({ path: '/users/{userId}', summary: 'Delete a user', tags: ['users'] -}).input(zDeleteUserData); +}).input(z.object({ headers: zDeleteUserHeaders.optional(), params: zDeleteUserPath })); /** * Get a user by ID @@ -51,7 +52,7 @@ export const getUserById = oc.route({ path: '/users/{userId}', summary: 'Get a user by ID', tags: ['users'] -}).input(zGetUserByIdData).output(zGetUserByIdResponse); +}).input(z.object({ params: zGetUserByIdPath })).output(zGetUserByIdResponse); /** * Update a user @@ -63,7 +64,7 @@ export const updateUser = oc.route({ path: '/users/{userId}', summary: 'Update a user', tags: ['users'] -}).input(zUpdateUserData).output(zUpdateUserResponse); +}).input(z.object({ body: zUpdateUserBody, params: zUpdateUserPath })).output(zUpdateUserResponse); export const users = { getUsers, @@ -83,7 +84,7 @@ export const getPosts = oc.route({ path: '/posts', summary: 'Get all posts', tags: ['posts'] -}).input(zGetPostsData).output(zGetPostsResponse); +}).input(z.object({ query: zGetPostsQuery.optional() })).output(zGetPostsResponse); /** * Create a new post @@ -96,7 +97,7 @@ export const createPost = oc.route({ successStatus: 201, summary: 'Create a new post', tags: ['posts'] -}).input(zCreatePostData).output(zCreatePostResponse); +}).input(z.object({ body: zCreatePostBody, headers: zCreatePostHeaders })).output(zCreatePostResponse); /** * Get a post by ID @@ -108,7 +109,7 @@ export const getPostById = oc.route({ path: '/posts/{postId}', summary: 'Get a post by ID', tags: ['posts'] -}).input(zGetPostByIdData).output(zGetPostByIdResponse); +}).input(z.object({ params: zGetPostByIdPath, query: zGetPostByIdQuery.optional() })).output(zGetPostByIdResponse); export const posts = { getPosts, diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-by-tags/zod.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-by-tags/zod.gen.ts index f43f854eb..449df619c 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-by-tags/zod.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-by-tags/zod.gen.ts @@ -39,13 +39,9 @@ export const zCreatePostInput = z.object({ status: z.enum(['draft', 'published']).optional() }); -export const zGetUsersData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - limit: z.int().optional().default(10), - offset: z.int().optional().default(0) - }).optional() +export const zGetUsersQuery = z.object({ + limit: z.int().optional().default(10), + offset: z.int().optional().default(0) }); /** @@ -53,26 +49,19 @@ export const zGetUsersData = z.object({ */ export const zGetUsersResponse = z.array(zUser); -export const zCreateUserData = z.object({ - body: zCreateUserInput, - path: z.never().optional(), - query: z.never().optional() -}); +export const zCreateUserBody = zCreateUserInput; /** * User created */ export const zCreateUserResponse = zUser; -export const zDeleteUserData = z.object({ - body: z.never().optional(), - path: z.object({ - userId: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'X-Request-Id': z.string().optional() - }).optional() +export const zDeleteUserHeaders = z.object({ + 'X-Request-Id': z.string().optional() +}); + +export const zDeleteUserPath = z.object({ + userId: z.string() }); /** @@ -80,12 +69,8 @@ export const zDeleteUserData = z.object({ */ export const zDeleteUserResponse = z.void(); -export const zGetUserByIdData = z.object({ - body: z.never().optional(), - path: z.object({ - userId: z.string() - }), - query: z.never().optional() +export const zGetUserByIdPath = z.object({ + userId: z.string() }); /** @@ -93,12 +78,10 @@ export const zGetUserByIdData = z.object({ */ export const zGetUserByIdResponse = zUser; -export const zUpdateUserData = z.object({ - body: zUpdateUserInput, - path: z.object({ - userId: z.string() - }), - query: z.never().optional() +export const zUpdateUserBody = zUpdateUserInput; + +export const zUpdateUserPath = z.object({ + userId: z.string() }); /** @@ -106,17 +89,13 @@ export const zUpdateUserData = z.object({ */ export const zUpdateUserResponse = zUser; -export const zGetPostsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - authorId: z.string().optional(), - status: z.enum([ - 'draft', - 'published', - 'archived' - ]).optional() - }).optional() +export const zGetPostsQuery = z.object({ + authorId: z.string().optional(), + status: z.enum([ + 'draft', + 'published', + 'archived' + ]).optional() }); /** @@ -124,13 +103,10 @@ export const zGetPostsData = z.object({ */ export const zGetPostsResponse = z.array(zPost); -export const zCreatePostData = z.object({ - body: zCreatePostInput, - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - 'X-Author-Id': z.string() - }) +export const zCreatePostBody = zCreatePostInput; + +export const zCreatePostHeaders = z.object({ + 'X-Author-Id': z.string() }); /** @@ -138,14 +114,12 @@ export const zCreatePostData = z.object({ */ export const zCreatePostResponse = zPost; -export const zGetPostByIdData = z.object({ - body: z.never().optional(), - path: z.object({ - postId: z.string() - }), - query: z.object({ - includeComments: z.boolean().optional().default(false) - }).optional() +export const zGetPostByIdPath = z.object({ + postId: z.string() +}); + +export const zGetPostByIdQuery = z.object({ + includeComments: z.boolean().optional().default(false) }); /** diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-single/orpc.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-single/orpc.gen.ts index b0c7704f4..35f92db12 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-single/orpc.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-single/orpc.gen.ts @@ -1,8 +1,9 @@ // This file is auto-generated by @hey-api/openapi-ts import { oc } from '@orpc/contract'; +import * as z from 'zod'; -import { zCreatePostData, zCreatePostResponse, zCreateUserData, zCreateUserResponse, zDeleteUserData, zGetPostByIdData, zGetPostByIdResponse, zGetPostsData, zGetPostsResponse, zGetUserByIdData, zGetUserByIdResponse, zGetUsersData, zGetUsersResponse, zUpdateUserData, zUpdateUserResponse } from './zod.gen'; +import { zCreatePostBody, zCreatePostHeaders, zCreatePostResponse, zCreateUserBody, zCreateUserResponse, zDeleteUserHeaders, zDeleteUserPath, zGetPostByIdPath, zGetPostByIdQuery, zGetPostByIdResponse, zGetPostsQuery, zGetPostsResponse, zGetUserByIdPath, zGetUserByIdResponse, zGetUsersQuery, zGetUsersResponse, zUpdateUserBody, zUpdateUserPath, zUpdateUserResponse } from './zod.gen'; /** * Get all users @@ -14,7 +15,7 @@ export const getUsers = oc.route({ path: '/users', summary: 'Get all users', tags: ['users'] -}).input(zGetUsersData).output(zGetUsersResponse); +}).input(z.object({ query: zGetUsersQuery.optional() })).output(zGetUsersResponse); /** * Create a new user @@ -27,7 +28,7 @@ export const createUser = oc.route({ successStatus: 201, summary: 'Create a new user', tags: ['users'] -}).input(zCreateUserData).output(zCreateUserResponse); +}).input(z.object({ body: zCreateUserBody })).output(zCreateUserResponse); /** * Delete a user @@ -39,7 +40,7 @@ export const deleteUser = oc.route({ path: '/users/{userId}', summary: 'Delete a user', tags: ['users'] -}).input(zDeleteUserData); +}).input(z.object({ headers: zDeleteUserHeaders.optional(), params: zDeleteUserPath })); /** * Get a user by ID @@ -51,7 +52,7 @@ export const getUserById = oc.route({ path: '/users/{userId}', summary: 'Get a user by ID', tags: ['users'] -}).input(zGetUserByIdData).output(zGetUserByIdResponse); +}).input(z.object({ params: zGetUserByIdPath })).output(zGetUserByIdResponse); /** * Update a user @@ -63,7 +64,7 @@ export const updateUser = oc.route({ path: '/users/{userId}', summary: 'Update a user', tags: ['users'] -}).input(zUpdateUserData).output(zUpdateUserResponse); +}).input(z.object({ body: zUpdateUserBody, params: zUpdateUserPath })).output(zUpdateUserResponse); /** * Get all posts @@ -75,7 +76,7 @@ export const getPosts = oc.route({ path: '/posts', summary: 'Get all posts', tags: ['posts'] -}).input(zGetPostsData).output(zGetPostsResponse); +}).input(z.object({ query: zGetPostsQuery.optional() })).output(zGetPostsResponse); /** * Create a new post @@ -88,7 +89,7 @@ export const createPost = oc.route({ successStatus: 201, summary: 'Create a new post', tags: ['posts'] -}).input(zCreatePostData).output(zCreatePostResponse); +}).input(z.object({ body: zCreatePostBody, headers: zCreatePostHeaders })).output(zCreatePostResponse); /** * Get a post by ID @@ -100,7 +101,7 @@ export const getPostById = oc.route({ path: '/posts/{postId}', summary: 'Get a post by ID', tags: ['posts'] -}).input(zGetPostByIdData).output(zGetPostByIdResponse); +}).input(z.object({ params: zGetPostByIdPath, query: zGetPostByIdQuery.optional() })).output(zGetPostByIdResponse); export const api = { getUsers, diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-single/zod.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-single/zod.gen.ts index f43f854eb..449df619c 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-single/zod.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/contracts-strategy-single/zod.gen.ts @@ -39,13 +39,9 @@ export const zCreatePostInput = z.object({ status: z.enum(['draft', 'published']).optional() }); -export const zGetUsersData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - limit: z.int().optional().default(10), - offset: z.int().optional().default(0) - }).optional() +export const zGetUsersQuery = z.object({ + limit: z.int().optional().default(10), + offset: z.int().optional().default(0) }); /** @@ -53,26 +49,19 @@ export const zGetUsersData = z.object({ */ export const zGetUsersResponse = z.array(zUser); -export const zCreateUserData = z.object({ - body: zCreateUserInput, - path: z.never().optional(), - query: z.never().optional() -}); +export const zCreateUserBody = zCreateUserInput; /** * User created */ export const zCreateUserResponse = zUser; -export const zDeleteUserData = z.object({ - body: z.never().optional(), - path: z.object({ - userId: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'X-Request-Id': z.string().optional() - }).optional() +export const zDeleteUserHeaders = z.object({ + 'X-Request-Id': z.string().optional() +}); + +export const zDeleteUserPath = z.object({ + userId: z.string() }); /** @@ -80,12 +69,8 @@ export const zDeleteUserData = z.object({ */ export const zDeleteUserResponse = z.void(); -export const zGetUserByIdData = z.object({ - body: z.never().optional(), - path: z.object({ - userId: z.string() - }), - query: z.never().optional() +export const zGetUserByIdPath = z.object({ + userId: z.string() }); /** @@ -93,12 +78,10 @@ export const zGetUserByIdData = z.object({ */ export const zGetUserByIdResponse = zUser; -export const zUpdateUserData = z.object({ - body: zUpdateUserInput, - path: z.object({ - userId: z.string() - }), - query: z.never().optional() +export const zUpdateUserBody = zUpdateUserInput; + +export const zUpdateUserPath = z.object({ + userId: z.string() }); /** @@ -106,17 +89,13 @@ export const zUpdateUserData = z.object({ */ export const zUpdateUserResponse = zUser; -export const zGetPostsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - authorId: z.string().optional(), - status: z.enum([ - 'draft', - 'published', - 'archived' - ]).optional() - }).optional() +export const zGetPostsQuery = z.object({ + authorId: z.string().optional(), + status: z.enum([ + 'draft', + 'published', + 'archived' + ]).optional() }); /** @@ -124,13 +103,10 @@ export const zGetPostsData = z.object({ */ export const zGetPostsResponse = z.array(zPost); -export const zCreatePostData = z.object({ - body: zCreatePostInput, - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - 'X-Author-Id': z.string() - }) +export const zCreatePostBody = zCreatePostInput; + +export const zCreatePostHeaders = z.object({ + 'X-Author-Id': z.string() }); /** @@ -138,14 +114,12 @@ export const zCreatePostData = z.object({ */ export const zCreatePostResponse = zPost; -export const zGetPostByIdData = z.object({ - body: z.never().optional(), - path: z.object({ - postId: z.string() - }), - query: z.object({ - includeComments: z.boolean().optional().default(false) - }).optional() +export const zGetPostByIdPath = z.object({ + postId: z.string() +}); + +export const zGetPostByIdQuery = z.object({ + includeComments: z.boolean().optional().default(false) }); /** diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/custom-names/orpc.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/custom-names/orpc.gen.ts index 92b5ebf1d..d36cc48df 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/custom-names/orpc.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/custom-names/orpc.gen.ts @@ -1,8 +1,9 @@ // This file is auto-generated by @hey-api/openapi-ts import { oc } from '@orpc/contract'; +import * as v from 'valibot'; -import { vCreatePostData, vCreatePostResponse, vCreateUserData, vCreateUserResponse, vDeleteUserData, vGetPostByIdData, vGetPostByIdResponse, vGetPostsData, vGetPostsResponse, vGetUserByIdData, vGetUserByIdResponse, vGetUsersData, vGetUsersResponse, vUpdateUserData, vUpdateUserResponse } from './valibot.gen'; +import { vCreatePostBody, vCreatePostHeaders, vCreatePostResponse, vCreateUserBody, vCreateUserResponse, vDeleteUserHeaders, vDeleteUserPath, vGetPostByIdPath, vGetPostByIdQuery, vGetPostByIdResponse, vGetPostsQuery, vGetPostsResponse, vGetUserByIdPath, vGetUserByIdResponse, vGetUsersQuery, vGetUsersResponse, vUpdateUserBody, vUpdateUserPath, vUpdateUserResponse } from './valibot.gen'; /** * Get all users @@ -14,7 +15,7 @@ export const getUsersRpc = oc.route({ path: '/users', summary: 'Get all users', tags: ['users'] -}).input(vGetUsersData).output(vGetUsersResponse); +}).input(v.object({ query: v.optional(vGetUsersQuery) })).output(vGetUsersResponse); /** * Create a new user @@ -27,7 +28,7 @@ export const createUserRpc = oc.route({ successStatus: 201, summary: 'Create a new user', tags: ['users'] -}).input(vCreateUserData).output(vCreateUserResponse); +}).input(v.object({ body: vCreateUserBody })).output(vCreateUserResponse); /** * Delete a user @@ -39,7 +40,7 @@ export const deleteUserRpc = oc.route({ path: '/users/{userId}', summary: 'Delete a user', tags: ['users'] -}).input(vDeleteUserData); +}).input(v.object({ headers: v.optional(vDeleteUserHeaders), params: vDeleteUserPath })); /** * Get a user by ID @@ -51,7 +52,7 @@ export const getUserByIdRpc = oc.route({ path: '/users/{userId}', summary: 'Get a user by ID', tags: ['users'] -}).input(vGetUserByIdData).output(vGetUserByIdResponse); +}).input(v.object({ params: vGetUserByIdPath })).output(vGetUserByIdResponse); /** * Update a user @@ -63,7 +64,7 @@ export const updateUserRpc = oc.route({ path: '/users/{userId}', summary: 'Update a user', tags: ['users'] -}).input(vUpdateUserData).output(vUpdateUserResponse); +}).input(v.object({ body: vUpdateUserBody, params: vUpdateUserPath })).output(vUpdateUserResponse); /** * Get all posts @@ -75,7 +76,7 @@ export const getPostsRpc = oc.route({ path: '/posts', summary: 'Get all posts', tags: ['posts'] -}).input(vGetPostsData).output(vGetPostsResponse); +}).input(v.object({ query: v.optional(vGetPostsQuery) })).output(vGetPostsResponse); /** * Create a new post @@ -88,7 +89,7 @@ export const createPostRpc = oc.route({ successStatus: 201, summary: 'Create a new post', tags: ['posts'] -}).input(vCreatePostData).output(vCreatePostResponse); +}).input(v.object({ body: vCreatePostBody, headers: vCreatePostHeaders })).output(vCreatePostResponse); /** * Get a post by ID @@ -100,7 +101,7 @@ export const getPostByIdRpc = oc.route({ path: '/posts/{postId}', summary: 'Get a post by ID', tags: ['posts'] -}).input(vGetPostByIdData).output(vGetPostByIdResponse); +}).input(v.object({ params: vGetPostByIdPath, query: v.optional(vGetPostByIdQuery) })).output(vGetPostByIdResponse); export const rpcContract = { getUsersRpc, diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/custom-names/valibot.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/custom-names/valibot.gen.ts index 9f5c64637..2a058ce74 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/custom-names/valibot.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/custom-names/valibot.gen.ts @@ -39,13 +39,9 @@ export const vCreatePostInput = v.object({ status: v.optional(v.picklist(['draft', 'published'])) }); -export const vGetUsersData = v.object({ - body: v.optional(v.never()), - path: v.optional(v.never()), - query: v.optional(v.object({ - limit: v.optional(v.pipe(v.number(), v.integer()), 10), - offset: v.optional(v.pipe(v.number(), v.integer()), 0) - })) +export const vGetUsersQuery = v.object({ + limit: v.optional(v.pipe(v.number(), v.integer()), 10), + offset: v.optional(v.pipe(v.number(), v.integer()), 0) }); /** @@ -53,26 +49,19 @@ export const vGetUsersData = v.object({ */ export const vGetUsersResponse = v.array(vUser); -export const vCreateUserData = v.object({ - body: vCreateUserInput, - path: v.optional(v.never()), - query: v.optional(v.never()) -}); +export const vCreateUserBody = vCreateUserInput; /** * User created */ export const vCreateUserResponse = vUser; -export const vDeleteUserData = v.object({ - body: v.optional(v.never()), - path: v.object({ - userId: v.string() - }), - query: v.optional(v.never()), - headers: v.optional(v.object({ - 'X-Request-Id': v.optional(v.string()) - })) +export const vDeleteUserHeaders = v.object({ + 'X-Request-Id': v.optional(v.string()) +}); + +export const vDeleteUserPath = v.object({ + userId: v.string() }); /** @@ -80,12 +69,8 @@ export const vDeleteUserData = v.object({ */ export const vDeleteUserResponse = v.void(); -export const vGetUserByIdData = v.object({ - body: v.optional(v.never()), - path: v.object({ - userId: v.string() - }), - query: v.optional(v.never()) +export const vGetUserByIdPath = v.object({ + userId: v.string() }); /** @@ -93,12 +78,10 @@ export const vGetUserByIdData = v.object({ */ export const vGetUserByIdResponse = vUser; -export const vUpdateUserData = v.object({ - body: vUpdateUserInput, - path: v.object({ - userId: v.string() - }), - query: v.optional(v.never()) +export const vUpdateUserBody = vUpdateUserInput; + +export const vUpdateUserPath = v.object({ + userId: v.string() }); /** @@ -106,17 +89,13 @@ export const vUpdateUserData = v.object({ */ export const vUpdateUserResponse = vUser; -export const vGetPostsData = v.object({ - body: v.optional(v.never()), - path: v.optional(v.never()), - query: v.optional(v.object({ - authorId: v.optional(v.string()), - status: v.optional(v.picklist([ - 'draft', - 'published', - 'archived' - ])) - })) +export const vGetPostsQuery = v.object({ + authorId: v.optional(v.string()), + status: v.optional(v.picklist([ + 'draft', + 'published', + 'archived' + ])) }); /** @@ -124,13 +103,10 @@ export const vGetPostsData = v.object({ */ export const vGetPostsResponse = v.array(vPost); -export const vCreatePostData = v.object({ - body: vCreatePostInput, - path: v.optional(v.never()), - query: v.optional(v.never()), - headers: v.object({ - 'X-Author-Id': v.string() - }) +export const vCreatePostBody = vCreatePostInput; + +export const vCreatePostHeaders = v.object({ + 'X-Author-Id': v.string() }); /** @@ -138,14 +114,12 @@ export const vCreatePostData = v.object({ */ export const vCreatePostResponse = vPost; -export const vGetPostByIdData = v.object({ - body: v.optional(v.never()), - path: v.object({ - postId: v.string() - }), - query: v.optional(v.object({ - includeComments: v.optional(v.boolean(), false) - })) +export const vGetPostByIdPath = v.object({ + postId: v.string() +}); + +export const vGetPostByIdQuery = v.object({ + includeComments: v.optional(v.boolean(), false) }); /** diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/default/orpc.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/default/orpc.gen.ts index 6e9637158..6df6e41ab 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/default/orpc.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/default/orpc.gen.ts @@ -1,8 +1,9 @@ // This file is auto-generated by @hey-api/openapi-ts import { oc } from '@orpc/contract'; +import * as z from 'zod'; -import { zCreatePostData, zCreatePostResponse, zCreateUserData, zCreateUserResponse, zDeleteUserData, zGetPostByIdData, zGetPostByIdResponse, zGetPostsData, zGetPostsResponse, zGetUserByIdData, zGetUserByIdResponse, zGetUsersData, zGetUsersResponse, zUpdateUserData, zUpdateUserResponse } from './zod.gen'; +import { zCreatePostBody, zCreatePostHeaders, zCreatePostResponse, zCreateUserBody, zCreateUserResponse, zDeleteUserHeaders, zDeleteUserPath, zGetPostByIdPath, zGetPostByIdQuery, zGetPostByIdResponse, zGetPostsQuery, zGetPostsResponse, zGetUserByIdPath, zGetUserByIdResponse, zGetUsersQuery, zGetUsersResponse, zUpdateUserBody, zUpdateUserPath, zUpdateUserResponse } from './zod.gen'; /** * Get all users @@ -14,7 +15,7 @@ export const getUsers = oc.route({ path: '/users', summary: 'Get all users', tags: ['users'] -}).input(zGetUsersData).output(zGetUsersResponse); +}).input(z.object({ query: zGetUsersQuery.optional() })).output(zGetUsersResponse); /** * Create a new user @@ -27,7 +28,7 @@ export const createUser = oc.route({ successStatus: 201, summary: 'Create a new user', tags: ['users'] -}).input(zCreateUserData).output(zCreateUserResponse); +}).input(z.object({ body: zCreateUserBody })).output(zCreateUserResponse); /** * Delete a user @@ -39,7 +40,7 @@ export const deleteUser = oc.route({ path: '/users/{userId}', summary: 'Delete a user', tags: ['users'] -}).input(zDeleteUserData); +}).input(z.object({ headers: zDeleteUserHeaders.optional(), params: zDeleteUserPath })); /** * Get a user by ID @@ -51,7 +52,7 @@ export const getUserById = oc.route({ path: '/users/{userId}', summary: 'Get a user by ID', tags: ['users'] -}).input(zGetUserByIdData).output(zGetUserByIdResponse); +}).input(z.object({ params: zGetUserByIdPath })).output(zGetUserByIdResponse); /** * Update a user @@ -63,7 +64,7 @@ export const updateUser = oc.route({ path: '/users/{userId}', summary: 'Update a user', tags: ['users'] -}).input(zUpdateUserData).output(zUpdateUserResponse); +}).input(z.object({ body: zUpdateUserBody, params: zUpdateUserPath })).output(zUpdateUserResponse); /** * Get all posts @@ -75,7 +76,7 @@ export const getPosts = oc.route({ path: '/posts', summary: 'Get all posts', tags: ['posts'] -}).input(zGetPostsData).output(zGetPostsResponse); +}).input(z.object({ query: zGetPostsQuery.optional() })).output(zGetPostsResponse); /** * Create a new post @@ -88,7 +89,7 @@ export const createPost = oc.route({ successStatus: 201, summary: 'Create a new post', tags: ['posts'] -}).input(zCreatePostData).output(zCreatePostResponse); +}).input(z.object({ body: zCreatePostBody, headers: zCreatePostHeaders })).output(zCreatePostResponse); /** * Get a post by ID @@ -100,7 +101,7 @@ export const getPostById = oc.route({ path: '/posts/{postId}', summary: 'Get a post by ID', tags: ['posts'] -}).input(zGetPostByIdData).output(zGetPostByIdResponse); +}).input(z.object({ params: zGetPostByIdPath, query: zGetPostByIdQuery.optional() })).output(zGetPostByIdResponse); export const contract = { getUsers, diff --git a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/default/zod.gen.ts b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/default/zod.gen.ts index f43f854eb..449df619c 100644 --- a/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/default/zod.gen.ts +++ b/packages/openapi-ts-tests/orpc/v1/__snapshots__/3.1.x/default/zod.gen.ts @@ -39,13 +39,9 @@ export const zCreatePostInput = z.object({ status: z.enum(['draft', 'published']).optional() }); -export const zGetUsersData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - limit: z.int().optional().default(10), - offset: z.int().optional().default(0) - }).optional() +export const zGetUsersQuery = z.object({ + limit: z.int().optional().default(10), + offset: z.int().optional().default(0) }); /** @@ -53,26 +49,19 @@ export const zGetUsersData = z.object({ */ export const zGetUsersResponse = z.array(zUser); -export const zCreateUserData = z.object({ - body: zCreateUserInput, - path: z.never().optional(), - query: z.never().optional() -}); +export const zCreateUserBody = zCreateUserInput; /** * User created */ export const zCreateUserResponse = zUser; -export const zDeleteUserData = z.object({ - body: z.never().optional(), - path: z.object({ - userId: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'X-Request-Id': z.string().optional() - }).optional() +export const zDeleteUserHeaders = z.object({ + 'X-Request-Id': z.string().optional() +}); + +export const zDeleteUserPath = z.object({ + userId: z.string() }); /** @@ -80,12 +69,8 @@ export const zDeleteUserData = z.object({ */ export const zDeleteUserResponse = z.void(); -export const zGetUserByIdData = z.object({ - body: z.never().optional(), - path: z.object({ - userId: z.string() - }), - query: z.never().optional() +export const zGetUserByIdPath = z.object({ + userId: z.string() }); /** @@ -93,12 +78,10 @@ export const zGetUserByIdData = z.object({ */ export const zGetUserByIdResponse = zUser; -export const zUpdateUserData = z.object({ - body: zUpdateUserInput, - path: z.object({ - userId: z.string() - }), - query: z.never().optional() +export const zUpdateUserBody = zUpdateUserInput; + +export const zUpdateUserPath = z.object({ + userId: z.string() }); /** @@ -106,17 +89,13 @@ export const zUpdateUserData = z.object({ */ export const zUpdateUserResponse = zUser; -export const zGetPostsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - authorId: z.string().optional(), - status: z.enum([ - 'draft', - 'published', - 'archived' - ]).optional() - }).optional() +export const zGetPostsQuery = z.object({ + authorId: z.string().optional(), + status: z.enum([ + 'draft', + 'published', + 'archived' + ]).optional() }); /** @@ -124,13 +103,10 @@ export const zGetPostsData = z.object({ */ export const zGetPostsResponse = z.array(zPost); -export const zCreatePostData = z.object({ - body: zCreatePostInput, - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - 'X-Author-Id': z.string() - }) +export const zCreatePostBody = zCreatePostInput; + +export const zCreatePostHeaders = z.object({ + 'X-Author-Id': z.string() }); /** @@ -138,14 +114,12 @@ export const zCreatePostData = z.object({ */ export const zCreatePostResponse = zPost; -export const zGetPostByIdData = z.object({ - body: z.never().optional(), - path: z.object({ - postId: z.string() - }), - query: z.object({ - includeComments: z.boolean().optional().default(false) - }).optional() +export const zGetPostByIdPath = z.object({ + postId: z.string() +}); + +export const zGetPostByIdQuery = z.object({ + includeComments: z.boolean().optional().default(false) }); /** diff --git a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/time-format/valibot.gen.ts b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/time-format/valibot.gen.ts index 06301e735..7bc06bb07 100644 --- a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/time-format/valibot.gen.ts +++ b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/time-format/valibot.gen.ts @@ -2,13 +2,9 @@ import * as v from 'valibot'; -export const vGetSearchData = v.object({ - body: v.optional(v.never()), - path: v.optional(v.never()), - query: v.object({ - start_time: v.optional(v.pipe(v.string(), v.isoTimeSecond())), - end_time: v.pipe(v.string(), v.isoTimeSecond()) - }) +export const vGetSearchQuery = v.object({ + start_time: v.optional(v.pipe(v.string(), v.isoTimeSecond())), + end_time: v.pipe(v.string(), v.isoTimeSecond()) }); /** diff --git a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/type-format/sdk.gen.ts b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/type-format/sdk.gen.ts index 6cf6f6694..af4e18178 100644 --- a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/type-format/sdk.gen.ts +++ b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/type-format/sdk.gen.ts @@ -6,7 +6,7 @@ import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; import { postFooResponseTransformer } from './transformers.gen'; import type { PostFooData, PostFooResponses } from './types.gen'; -import { vPostFooData, vPostFooResponse } from './valibot.gen'; +import { vPostFooResponse } from './valibot.gen'; export type Options = Options2 & { /** @@ -23,7 +23,11 @@ export type Options(options?: Options) => (options?.client ?? client).post({ - requestValidator: async (data) => await v.parseAsync(vPostFooData, data), + requestValidator: async (data) => await v.parseAsync(v.object({ + body: v.optional(v.never()), + path: v.optional(v.never()), + query: v.optional(v.never()) + }), data), responseTransformer: postFooResponseTransformer, responseValidator: async (data) => await v.parseAsync(vPostFooResponse, data), url: '/foo', diff --git a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/type-format/valibot.gen.ts b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/type-format/valibot.gen.ts index c369f0aa5..c86c8a90d 100644 --- a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/type-format/valibot.gen.ts +++ b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/type-format/valibot.gen.ts @@ -16,12 +16,6 @@ export const vBar = v.objectWithRest({ foo: v.pipe(v.number(), v.integer()) }, v.pipe(v.number(), v.integer())); -export const vPostFooData = v.object({ - body: v.optional(v.never()), - path: v.optional(v.never()), - query: v.optional(v.never()) -}); - /** * OK */ diff --git a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators-metadata-fn/valibot.gen.ts b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators-metadata-fn/valibot.gen.ts index ee2489a8d..29951954d 100644 --- a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators-metadata-fn/valibot.gen.ts +++ b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators-metadata-fn/valibot.gen.ts @@ -34,24 +34,18 @@ export const vFoo3 = v.pipe(v.object({ foo: v.optional(vBar) }), v.metadata({ custom: 'value', title: 'object' })); -export const vPatchFooData = v.pipe(v.object({ - body: v.pipe(v.object({ - foo: v.optional(v.pipe(v.string(), v.metadata({ custom: 'value', title: 'string' }))) - }), v.metadata({ custom: 'value', title: 'object' })), - path: v.optional(v.pipe(v.never(), v.metadata({ custom: 'value', title: 'never' }))), - query: v.optional(v.pipe(v.object({ - foo: v.optional(v.pipe(v.string(), v.metadata({ custom: 'value', title: 'This is Foo parameter.' }))), - bar: v.optional(vBar), - baz: v.optional(v.pipe(v.object({ - baz: v.optional(v.pipe(v.string(), v.metadata({ custom: 'value', title: 'string' }))) - }), v.metadata({ custom: 'value', title: 'object' }))), - qux: v.optional(v.pipe(v.pipe(v.string(), v.isoDate()), v.metadata({ custom: 'value', title: 'string' }))), - quux: v.optional(v.pipe(v.pipe(v.string(), v.isoTimestamp()), v.metadata({ custom: 'value', title: 'string' }))) - }), v.metadata({ custom: 'value', title: 'object' }))) +export const vPatchFooBody = v.pipe(v.object({ + foo: v.optional(v.pipe(v.string(), v.metadata({ custom: 'value', title: 'string' }))) }), v.metadata({ custom: 'value', title: 'object' })); -export const vPostFooData = v.pipe(v.object({ - body: vFoo3, - path: v.optional(v.pipe(v.never(), v.metadata({ custom: 'value', title: 'never' }))), - query: v.optional(v.pipe(v.never(), v.metadata({ custom: 'value', title: 'never' }))) +export const vPatchFooQuery = v.pipe(v.object({ + foo: v.optional(v.pipe(v.string(), v.metadata({ custom: 'value', title: 'This is Foo parameter.' }))), + bar: v.optional(vBar), + baz: v.optional(v.pipe(v.object({ + baz: v.optional(v.pipe(v.string(), v.metadata({ custom: 'value', title: 'string' }))) + }), v.metadata({ custom: 'value', title: 'object' }))), + qux: v.optional(v.pipe(v.pipe(v.string(), v.isoDate()), v.metadata({ custom: 'value', title: 'string' }))), + quux: v.optional(v.pipe(v.pipe(v.string(), v.isoTimestamp()), v.metadata({ custom: 'value', title: 'string' }))) }), v.metadata({ custom: 'value', title: 'object' })); + +export const vPostFooBody = vFoo3; diff --git a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators-metadata/valibot.gen.ts b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators-metadata/valibot.gen.ts index 8072a14be..1fb5ae267 100644 --- a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators-metadata/valibot.gen.ts +++ b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators-metadata/valibot.gen.ts @@ -34,24 +34,18 @@ export const vFoo3 = v.object({ foo: v.optional(vBar) }); -export const vPatchFooData = v.object({ - body: v.object({ - foo: v.optional(v.string()) - }), - path: v.optional(v.never()), - query: v.optional(v.object({ - foo: v.optional(v.pipe(v.string(), v.metadata({ description: 'This is Foo parameter.' }))), - bar: v.optional(vBar), - baz: v.optional(v.object({ - baz: v.optional(v.string()) - })), - qux: v.optional(v.pipe(v.string(), v.isoDate())), - quux: v.optional(v.pipe(v.string(), v.isoTimestamp())) - })) +export const vPatchFooBody = v.object({ + foo: v.optional(v.string()) }); -export const vPostFooData = v.object({ - body: vFoo3, - path: v.optional(v.never()), - query: v.optional(v.never()) +export const vPatchFooQuery = v.object({ + foo: v.optional(v.pipe(v.string(), v.metadata({ description: 'This is Foo parameter.' }))), + bar: v.optional(vBar), + baz: v.optional(v.object({ + baz: v.optional(v.string()) + })), + qux: v.optional(v.pipe(v.string(), v.isoDate())), + quux: v.optional(v.pipe(v.string(), v.isoTimestamp())) }); + +export const vPostFooBody = vFoo3; diff --git a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators-types/valibot.gen.ts b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators-types/valibot.gen.ts index 621d1f914..93b11d746 100644 --- a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators-types/valibot.gen.ts +++ b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators-types/valibot.gen.ts @@ -34,24 +34,18 @@ export const vFoo3 = v.object({ foo: v.optional(vBar) }); -export const vPatchFooData = v.object({ - body: v.object({ - foo: v.optional(v.string()) - }), - path: v.optional(v.never()), - query: v.optional(v.object({ - foo: v.optional(v.string()), - bar: v.optional(vBar), - baz: v.optional(v.object({ - baz: v.optional(v.string()) - })), - qux: v.optional(v.pipe(v.string(), v.isoDate())), - quux: v.optional(v.pipe(v.string(), v.isoTimestamp())) - })) +export const vPatchFooBody = v.object({ + foo: v.optional(v.string()) }); -export const vPostFooData = v.object({ - body: vFoo3, - path: v.optional(v.never()), - query: v.optional(v.never()) +export const vPatchFooQuery = v.object({ + foo: v.optional(v.string()), + bar: v.optional(vBar), + baz: v.optional(v.object({ + baz: v.optional(v.string()) + })), + qux: v.optional(v.pipe(v.string(), v.isoDate())), + quux: v.optional(v.pipe(v.string(), v.isoTimestamp())) }); + +export const vPostFooBody = vFoo3; diff --git a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators/valibot.gen.ts b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators/valibot.gen.ts index 621d1f914..93b11d746 100644 --- a/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators/valibot.gen.ts +++ b/packages/openapi-ts-tests/valibot/v1/__snapshots__/3.1.x/validators/valibot.gen.ts @@ -34,24 +34,18 @@ export const vFoo3 = v.object({ foo: v.optional(vBar) }); -export const vPatchFooData = v.object({ - body: v.object({ - foo: v.optional(v.string()) - }), - path: v.optional(v.never()), - query: v.optional(v.object({ - foo: v.optional(v.string()), - bar: v.optional(vBar), - baz: v.optional(v.object({ - baz: v.optional(v.string()) - })), - qux: v.optional(v.pipe(v.string(), v.isoDate())), - quux: v.optional(v.pipe(v.string(), v.isoTimestamp())) - })) +export const vPatchFooBody = v.object({ + foo: v.optional(v.string()) }); -export const vPostFooData = v.object({ - body: vFoo3, - path: v.optional(v.never()), - query: v.optional(v.never()) +export const vPatchFooQuery = v.object({ + foo: v.optional(v.string()), + bar: v.optional(vBar), + baz: v.optional(v.object({ + baz: v.optional(v.string()) + })), + qux: v.optional(v.pipe(v.string(), v.isoDate())), + quux: v.optional(v.pipe(v.string(), v.isoTimestamp())) }); + +export const vPostFooBody = vFoo3; 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 c158420b6..8e916050b 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 @@ -452,192 +452,83 @@ export const zModelWithPatternWritable = z.object({ patternWithUnicode: z.optional(z.string().check(z.regex(/^\p{L}+$/u))) }); -export const zServiceWithEmptyTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDescriptionsQuery = 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()) }); -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string() }); -export const zFooWowData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersPath = z.object({ + parameterPath: z.string(), + 'api-version': z.string() }); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersQuery = z.object({ + parameterQuery: z.string() }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -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()) - })) -}); - -export const zCallWithParametersData = z.object({ - body: z.optional(z.never()), - path: z.object({ - parameterPath: z.string(), - 'api-version': z.string() - }), - query: z.object({ - parameterQuery: z.string() - }), - headers: z.object({ - parameterHeader: z.string() - }) -}); - -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()), - 'api-version': z.string() - }), - query: z.object({ - default: z.optional(z.string()), - 'parameter-query': z.string() - }), - headers: z.object({ - 'parameter.header': z.string() - }) -}); - -export const zCallWithDefaultParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - parameterString: z._default(z.string(), 'Hello World!'), - parameterNumber: z._default(z.number(), 123), - parameterBoolean: z._default(z.boolean(), true), - parameterEnum: z.enum([ - 'Success', - 'Warning', - 'Error' - ]), - parameterModel: z._default(z.object({ - prop: z.optional(z.string()) - }), { 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._default(z.optional(z.string()), 'Hello World!'), - parameterNumber: z._default(z.optional(z.number()), 123), - parameterBoolean: z._default(z.optional(z.boolean()), true), - parameterEnum: z.optional(z.enum([ - 'Success', - 'Warning', - 'Error' - ])) - })) -}); - -export const zCallToTestOrderOfParamsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - parameterOptionalStringWithDefault: z._default(z.optional(z.string()), 'Hello World!'), - parameterOptionalStringWithEmptyDefault: z._default(z.optional(z.string()), ''), - parameterOptionalStringWithNoDefault: z.optional(z.string()), - parameterStringWithDefault: z._default(z.string(), 'Hello World!'), - parameterStringWithEmptyDefault: z._default(z.string(), ''), - parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.nullish(z.string()), - parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) - }) -}); +/** + * This is the parameter that is sent as request body + */ +export const zCallWithWeirdParameterNamesBody = z.string(); -export const zDuplicateNameData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string() }); -export const zDuplicateName2Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithWeirdParameterNamesPath = 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.string() }); -export const zDuplicateName3Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.optional(z.string()), + 'parameter-query': z.string() }); -export const zDuplicateName4Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDefaultParametersQuery = z.object({ + parameterString: z._default(z.string(), 'Hello World!'), + parameterNumber: z._default(z.number(), 123), + parameterBoolean: z._default(z.boolean(), true), + parameterEnum: z.enum([ + 'Success', + 'Warning', + 'Error' + ]), + parameterModel: z._default(z.object({ + prop: z.optional(z.string()) + }), { prop: 'Hello World!' }) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDefaultOptionalParametersQuery = z.object({ + parameterString: z._default(z.optional(z.string()), 'Hello World!'), + parameterNumber: z._default(z.optional(z.number()), 123), + parameterBoolean: z._default(z.optional(z.boolean()), true), + parameterEnum: z.optional(z.enum([ + 'Success', + 'Warning', + 'Error' + ])) }); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallToTestOrderOfParamsQuery = z.object({ + parameterOptionalStringWithDefault: z._default(z.optional(z.string()), 'Hello World!'), + parameterOptionalStringWithEmptyDefault: z._default(z.optional(z.string()), ''), + parameterOptionalStringWithNoDefault: z.optional(z.string()), + parameterStringWithDefault: z._default(z.string(), 'Hello World!'), + parameterStringWithEmptyDefault: z._default(z.string(), ''), + parameterStringWithNoDefault: z.string(), + parameterStringNullableWithNoDefault: z.nullish(z.string()), + parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) }); export const zCallWithResponseAndNoContentResponseResponse = z.union([ @@ -645,46 +536,16 @@ export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.unknown() ]); -export const zDummyAData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zDummyBData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zCallWithResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * Message for default response */ export const zCallWithResponseResponse = zModelWithString; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * Message for 201 response */ export const zCallWithDuplicateResponsesResponse = zModelWithString; -export const zCallWithResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.optional(z.readonly(z.string())), @@ -695,35 +556,29 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - parameterArrayCSV: z.array(z.string()), - parameterArraySSV: z.array(z.string()), - parameterArrayTSV: z.array(z.string()), - parameterArrayPipes: z.array(z.string()), - parameterArrayMulti: z.array(z.string()) - }) +export const zCollectionFormatQuery = z.object({ + parameterArrayCSV: z.array(z.string()), + parameterArraySSV: z.array(z.string()), + parameterArrayTSV: z.array(z.string()), + parameterArrayPipes: z.array(z.string()), + parameterArrayMulti: z.array(z.string()) }); -export const zTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.object({ - id: z.optional(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' }))) - })), - query: z.object({ - parameterNumber: z._default(z.number(), 123), - parameterString: z._default(z.string(), 'default'), - parameterBoolean: z._default(z.boolean(), true), - parameterArray: z.array(z.string()), - parameterDictionary: z.record(z.string(), z.unknown()), - parameterEnum: z.enum([ - 'Success', - 'Warning', - 'Error' - ]) - }) +export const zTypesPath = z.object({ + id: z.optional(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' }))) +}); + +export const zTypesQuery = z.object({ + parameterNumber: z._default(z.number(), 123), + parameterString: z._default(z.string(), 'default'), + parameterBoolean: z._default(z.boolean(), true), + parameterArray: z.array(z.string()), + parameterDictionary: z.record(z.string(), z.unknown()), + parameterEnum: z.enum([ + 'Success', + 'Warning', + 'Error' + ]) }); export const zTypesResponse = z.union([ @@ -733,20 +588,16 @@ export const zTypesResponse = z.union([ z.record(z.string(), z.unknown()) ]); -export const zComplexTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - parameterObject: z.object({ - first: z.optional(z.object({ - second: z.optional(z.object({ - third: z.optional(z.string()) - })) +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.optional(z.object({ + second: z.optional(z.object({ + third: z.optional(z.string()) })) - }), - parameterReference: z.object({ - prop: z.optional(z.string()) - }) + })) + }), + parameterReference: z.object({ + prop: z.optional(z.string()) }) }); @@ -755,26 +606,12 @@ 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()) -}); - -export const zTestErrorCodeData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - status: z.string() - }) +export const zTestErrorCodeQuery = z.object({ + status: z.string() }); -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.int() }); /** @@ -782,11 +619,10 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = zNonAsciiStringæøåÆøÅöôêÊ字符串; -export const zPostApiVbyApiVersionBodyData = z.object({ - body: zParameterActivityParams, - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +/** + * Body should not be unknown + */ +export const zPostApiVbyApiVersionBodyBody = zParameterActivityParams; /** * OK diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/type-format/zod.gen.ts index e21bae535..ae37637b5 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/mini/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.int() }); -export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * OK */ 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 085bf6077..a0b48d7fd 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 @@ -452,192 +452,83 @@ export const zModelWithPatternWritable = z.object({ patternWithUnicode: z.string().regex(/^\p{L}+$/u).optional() }); -export const zServiceWithEmptyTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDescriptionsQuery = 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() }); -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string() }); -export const zFooWowData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersPath = z.object({ + parameterPath: z.string(), + 'api-version': z.string() }); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersQuery = z.object({ + parameterQuery: z.string() }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zCallWithDescriptionsData = z.object({ - 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.never().optional(), - path: z.object({ - parameterPath: z.string(), - 'api-version': z.string() - }), - query: z.object({ - parameterQuery: z.string() - }), - headers: z.object({ - parameterHeader: z.string() - }) -}); - -export const zCallWithWeirdParameterNamesData = z.object({ - body: z.string(), - path: z.object({ - '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.string().optional(), - 'parameter-query': z.string() - }), - headers: z.object({ - 'parameter.header': z.string() - }) -}); - -export const zCallWithDefaultParametersData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterString: z.string().default('Hello World!'), - parameterNumber: z.number().default(123), - parameterBoolean: z.boolean().default(true), - parameterEnum: z.enum([ - 'Success', - 'Warning', - 'Error' - ]), - parameterModel: z.object({ - prop: z.string().optional() - }).default({ prop: 'Hello World!' }) - }) -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - 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.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.string().nullish(), - parameterStringNullableWithDefault: z.string().nullish().default(null) - }) -}); +/** + * This is the parameter that is sent as request body + */ +export const zCallWithWeirdParameterNamesBody = z.string(); -export const zDuplicateNameData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string() }); -export const zDuplicateName2Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithWeirdParameterNamesPath = z.object({ + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string() }); -export const zDuplicateName3Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.string().optional(), + 'parameter-query': z.string() }); -export const zDuplicateName4Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultParametersQuery = z.object({ + parameterString: z.string().default('Hello World!'), + parameterNumber: z.number().default(123), + parameterBoolean: z.boolean().default(true), + parameterEnum: z.enum([ + 'Success', + 'Warning', + 'Error' + ]), + parameterModel: z.object({ + prop: z.string().optional() + }).default({ prop: 'Hello World!' }) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultOptionalParametersQuery = 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() }); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallToTestOrderOfParamsQuery = z.object({ + 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.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }); export const zCallWithResponseAndNoContentResponseResponse = z.union([ @@ -645,46 +536,16 @@ export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.unknown() ]); -export const zDummyAData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zDummyBData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zCallWithResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Message for default response */ export const zCallWithResponseResponse = zModelWithString; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Message for 201 response */ export const zCallWithDuplicateResponsesResponse = zModelWithString; -export const zCallWithResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.string().readonly().optional(), @@ -695,35 +556,29 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterArrayCSV: z.array(z.string()), - parameterArraySSV: z.array(z.string()), - parameterArrayTSV: z.array(z.string()), - parameterArrayPipes: z.array(z.string()), - parameterArrayMulti: z.array(z.string()) - }) +export const zCollectionFormatQuery = z.object({ + parameterArrayCSV: z.array(z.string()), + parameterArraySSV: z.array(z.string()), + parameterArrayTSV: z.array(z.string()), + parameterArrayPipes: z.array(z.string()), + parameterArrayMulti: z.array(z.string()) }); -export const zTypesData = z.object({ - body: z.never().optional(), - path: 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' }).optional() - }).optional(), - query: z.object({ - parameterNumber: z.number().default(123), - parameterString: z.string().default('default'), - parameterBoolean: z.boolean().default(true), - parameterArray: z.array(z.string()), - parameterDictionary: z.record(z.unknown()), - parameterEnum: z.enum([ - 'Success', - 'Warning', - 'Error' - ]) - }) +export const zTypesPath = 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' }).optional() +}); + +export const zTypesQuery = z.object({ + parameterNumber: z.number().default(123), + parameterString: z.string().default('default'), + parameterBoolean: z.boolean().default(true), + parameterArray: z.array(z.string()), + parameterDictionary: z.record(z.unknown()), + parameterEnum: z.enum([ + 'Success', + 'Warning', + 'Error' + ]) }); export const zTypesResponse = z.union([ @@ -733,20 +588,16 @@ export const zTypesResponse = z.union([ z.record(z.unknown()) ]); -export const zComplexTypesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterObject: z.object({ - first: z.object({ - second: z.object({ - third: z.string().optional() - }).optional() +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.object({ + second: z.object({ + third: z.string().optional() }).optional() - }), - parameterReference: z.object({ - prop: z.string().optional() - }) + }).optional() + }), + parameterReference: z.object({ + prop: z.string().optional() }) }); @@ -755,26 +606,12 @@ export const zComplexTypesData = z.object({ */ export const zComplexTypesResponse = z.array(zModelWithString); -export const zCallWithResultFromHeaderData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zTestErrorCodeQuery = z.object({ + status: z.string() }); -export const zTestErrorCodeData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - status: z.string() - }) -}); - -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.number().int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.number().int() }); /** @@ -782,11 +619,10 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = zNonAsciiStringæøåÆøÅöôêÊ字符串; -export const zPostApiVbyApiVersionBodyData = z.object({ - body: zParameterActivityParams, - path: z.never().optional(), - query: z.never().optional() -}); +/** + * Body should not be unknown + */ +export const zPostApiVbyApiVersionBodyBody = zParameterActivityParams; /** * OK diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/type-format/zod.gen.ts index f7a98f3d5..9e6617bdb 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.number().int() }); -export const zPostFooData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ 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 3fc713430..bf295d5ac 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 @@ -452,192 +452,83 @@ export const zModelWithPatternWritable = z.object({ patternWithUnicode: z.string().regex(/^\p{L}+$/u).optional() }); -export const zServiceWithEmptyTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDescriptionsQuery = 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() }); -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string() }); -export const zFooWowData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersPath = z.object({ + parameterPath: z.string(), + 'api-version': z.string() }); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersQuery = z.object({ + parameterQuery: z.string() }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zCallWithDescriptionsData = z.object({ - 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.never().optional(), - path: z.object({ - parameterPath: z.string(), - 'api-version': z.string() - }), - query: z.object({ - parameterQuery: z.string() - }), - headers: z.object({ - parameterHeader: z.string() - }) -}); - -export const zCallWithWeirdParameterNamesData = z.object({ - body: z.string(), - path: z.object({ - '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.string().optional(), - 'parameter-query': z.string() - }), - headers: z.object({ - 'parameter.header': z.string() - }) -}); - -export const zCallWithDefaultParametersData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterString: z.string().default('Hello World!'), - parameterNumber: z.number().default(123), - parameterBoolean: z.boolean().default(true), - parameterEnum: z.enum([ - 'Success', - 'Warning', - 'Error' - ]), - parameterModel: z.object({ - prop: z.string().optional() - }).default({ prop: 'Hello World!' }) - }) -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - 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.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.string().nullish(), - parameterStringNullableWithDefault: z.string().nullish().default(null) - }) -}); +/** + * This is the parameter that is sent as request body + */ +export const zCallWithWeirdParameterNamesBody = z.string(); -export const zDuplicateNameData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string() }); -export const zDuplicateName2Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithWeirdParameterNamesPath = z.object({ + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string() }); -export const zDuplicateName3Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.string().optional(), + 'parameter-query': z.string() }); -export const zDuplicateName4Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultParametersQuery = z.object({ + parameterString: z.string().default('Hello World!'), + parameterNumber: z.number().default(123), + parameterBoolean: z.boolean().default(true), + parameterEnum: z.enum([ + 'Success', + 'Warning', + 'Error' + ]), + parameterModel: z.object({ + prop: z.string().optional() + }).default({ prop: 'Hello World!' }) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultOptionalParametersQuery = 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() }); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallToTestOrderOfParamsQuery = z.object({ + 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.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }); export const zCallWithResponseAndNoContentResponseResponse = z.union([ @@ -645,46 +536,16 @@ export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.unknown() ]); -export const zDummyAData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zDummyBData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zCallWithResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Message for default response */ export const zCallWithResponseResponse = zModelWithString; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Message for 201 response */ export const zCallWithDuplicateResponsesResponse = zModelWithString; -export const zCallWithResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.string().readonly().optional(), @@ -695,35 +556,29 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterArrayCSV: z.array(z.string()), - parameterArraySSV: z.array(z.string()), - parameterArrayTSV: z.array(z.string()), - parameterArrayPipes: z.array(z.string()), - parameterArrayMulti: z.array(z.string()) - }) +export const zCollectionFormatQuery = z.object({ + parameterArrayCSV: z.array(z.string()), + parameterArraySSV: z.array(z.string()), + parameterArrayTSV: z.array(z.string()), + parameterArrayPipes: z.array(z.string()), + parameterArrayMulti: z.array(z.string()) }); -export const zTypesData = z.object({ - 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'), - parameterBoolean: z.boolean().default(true), - parameterArray: z.array(z.string()), - parameterDictionary: z.record(z.string(), z.unknown()), - parameterEnum: z.enum([ - 'Success', - 'Warning', - 'Error' - ]) - }) +export const zTypesPath = 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() +}); + +export const zTypesQuery = z.object({ + parameterNumber: z.number().default(123), + parameterString: z.string().default('default'), + parameterBoolean: z.boolean().default(true), + parameterArray: z.array(z.string()), + parameterDictionary: z.record(z.string(), z.unknown()), + parameterEnum: z.enum([ + 'Success', + 'Warning', + 'Error' + ]) }); export const zTypesResponse = z.union([ @@ -733,20 +588,16 @@ export const zTypesResponse = z.union([ z.record(z.string(), z.unknown()) ]); -export const zComplexTypesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterObject: z.object({ - first: z.object({ - second: z.object({ - third: z.string().optional() - }).optional() +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.object({ + second: z.object({ + third: z.string().optional() }).optional() - }), - parameterReference: z.object({ - prop: z.string().optional() - }) + }).optional() + }), + parameterReference: z.object({ + prop: z.string().optional() }) }); @@ -755,26 +606,12 @@ export const zComplexTypesData = z.object({ */ export const zComplexTypesResponse = z.array(zModelWithString); -export const zCallWithResultFromHeaderData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zTestErrorCodeQuery = z.object({ + status: z.string() }); -export const zTestErrorCodeData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - status: z.string() - }) -}); - -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.int() }); /** @@ -782,11 +619,10 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = zNonAsciiStringæøåÆøÅöôêÊ字符串; -export const zPostApiVbyApiVersionBodyData = z.object({ - body: zParameterActivityParams, - path: z.never().optional(), - query: z.never().optional() -}); +/** + * Body should not be unknown + */ +export const zPostApiVbyApiVersionBodyBody = zParameterActivityParams; /** * OK diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/type-format/zod.gen.ts index 9b6647e58..85477ff58 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v4/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.int() }); -export const zPostFooData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ 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 91f87b838..67c360526 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 @@ -1081,55 +1081,23 @@ 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()) -}); - -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zImportData = z.object({ - body: z.union([ - zModelWithReadOnlyAndWriteOnlyWritable, - zModelWithArrayReadOnlyAndWriteOnlyWritable - ]), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +export const zImportBody = z.union([ + zModelWithReadOnlyAndWriteOnlyWritable, + zModelWithArrayReadOnlyAndWriteOnlyWritable +]); export const zImportResponse = z.union([ zModelFromZendesk, zModelWithReadOnlyAndWriteOnly ]); -export const zFooWowData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zApiVVersionODataControllerCountData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * Success */ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; -export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.optional(z.never()), - path: z.object({ - foo_param: z.string() - }), - query: z.optional(z.never()) +export const zGetApiVbyApiVersionSimpleOperationPath = z.object({ + foo_param: z.string() }); /** @@ -1137,131 +1105,87 @@ 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()) +export const zDeleteFooHeaders = z.object({ + 'x-Foo-Bar': zModelWithString }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zDeleteFooPath = z.object({ + foo_param: z.string(), + BarParam: z.string() }); -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDescriptionsQuery = 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()) }); -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zDeprecatedCallHeaders = z.object({ + parameter: z.nullable(zDeprecatedModel) }); -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +/** + * This is the parameter that goes into the body + */ +export const zCallWithParametersBody = z.nullable(z.record(z.string(), z.unknown())); -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.nullable(z.string()) }); -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersPath = z.object({ + parameterPath: z.nullable(z.string()), + 'api-version': z.nullable(z.string()) }); -export const zDeleteFooData3 = z.object({ - body: z.optional(z.never()), - path: z.object({ - foo_param: z.string(), - BarParam: z.string() - }), - query: z.optional(z.never()), - headers: z.object({ - 'x-Foo-Bar': zModelWithString - }) +export const zCallWithParametersQuery = z.object({ + foo_ref_enum: z.optional(zModelWithNestedArrayEnumsDataFoo), + foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, + cursor: z.nullable(z.string()) }); -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()) - })) +/** + * This is the parameter that goes into the body + */ +export const zCallWithWeirdParameterNamesBody = z.nullable(zModelWithString); + +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.nullable(z.string()) }); -export const zDeprecatedCallData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()), - headers: z.object({ - parameter: z.nullable(zDeprecatedModel) - }) +export const zCallWithWeirdParameterNamesPath = 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.nullable(z.string()) }); -export const zCallWithParametersData = z.object({ - body: z.nullable(z.record(z.string(), z.unknown())), - path: z.object({ - 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.nullable(z.string()) - }), - headers: z.object({ - parameterHeader: z.nullable(z.string()) - }) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.optional(z.string()), + 'parameter-query': z.nullable(z.string()) }); -export const zCallWithWeirdParameterNamesData = z.object({ - 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.nullable(z.string()) - }), - query: z.object({ - default: z.optional(z.string()), - 'parameter-query': z.nullable(z.string()) - }), - headers: z.object({ - 'parameter.header': z.nullable(z.string()) - }) +/** + * This is a required parameter + */ +export const zGetCallWithOptionalParamBody = zModelWithOneOfEnum; + +export const zGetCallWithOptionalParamQuery = z.object({ + page: z.optional(z.number()) }); -export const zGetCallWithOptionalParamData = z.object({ - body: zModelWithOneOfEnum, - path: z.optional(z.never()), - query: z.optional(z.object({ - page: z.optional(z.number()) - })) +/** + * This is an optional parameter + */ +export const zPostCallWithOptionalParamBody = z.object({ + offset: z.nullish(z.number()) }); -export const zPostCallWithOptionalParamData = z.object({ - body: z.optional(z.object({ - offset: z.nullish(z.number()) - })), - path: z.optional(z.never()), - query: z.object({ - parameter: zPageable - }) +export const zPostCallWithOptionalParamQuery = z.object({ + parameter: zPageable }); export const zPostCallWithOptionalParamResponse = z.union([ @@ -1269,97 +1193,57 @@ export const zPostCallWithOptionalParamResponse = z.union([ z.void() ]); -export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: z.optional(zSimpleRequestBody), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) -}); - -export const zPostApiVbyApiVersionFormDataData = z.object({ - body: z.optional(zSimpleFormData), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) -}); - -export const zCallWithDefaultParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - 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.nullish(zModelWithString) - })) -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z._default(z.optional(z.string()), 'Hello World!'), - parameterNumber: z._default(z.optional(z.number()), 123), - parameterBoolean: z._default(z.optional(z.boolean()), true), - parameterEnum: z.optional(z.enum([ - 'Success', - 'Warning', - 'Error' - ])), - parameterModel: z.optional(zModelWithString) - })) -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionRequestBodyBody = zSimpleRequestBody; -export const zCallToTestOrderOfParamsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - parameterOptionalStringWithDefault: z._default(z.optional(z.string()), 'Hello World!'), - parameterOptionalStringWithEmptyDefault: z._default(z.optional(z.string()), ''), - parameterOptionalStringWithNoDefault: z.optional(z.string()), - parameterStringWithDefault: z._default(z.string(), 'Hello World!'), - parameterStringWithEmptyDefault: z._default(z.string(), ''), - parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.nullish(z.string()), - parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) - }) +export const zPostApiVbyApiVersionRequestBodyQuery = z.object({ + parameter: z.optional(z.string()) }); -export const zDuplicateNameData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionFormDataBody = zSimpleFormData; -export const zDuplicateName2Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zPostApiVbyApiVersionFormDataQuery = z.object({ + parameter: z.optional(z.string()) }); -export const zDuplicateName3Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDefaultParametersQuery = z.object({ + 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.nullish(zModelWithString) }); -export const zDuplicateName4Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDefaultOptionalParametersQuery = z.object({ + parameterString: z._default(z.optional(z.string()), 'Hello World!'), + parameterNumber: z._default(z.optional(z.number()), 123), + parameterBoolean: z._default(z.optional(z.boolean()), true), + parameterEnum: z.optional(z.enum([ + 'Success', + 'Warning', + 'Error' + ])), + parameterModel: z.optional(zModelWithString) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallToTestOrderOfParamsQuery = z.object({ + parameterOptionalStringWithDefault: z._default(z.optional(z.string()), 'Hello World!'), + parameterOptionalStringWithEmptyDefault: z._default(z.optional(z.string()), ''), + parameterOptionalStringWithNoDefault: z.optional(z.string()), + parameterStringWithDefault: z._default(z.string(), 'Hello World!'), + parameterStringWithEmptyDefault: z._default(z.string(), ''), + parameterStringWithNoDefault: z.string(), + parameterStringNullableWithNoDefault: z.nullish(z.string()), + parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) }); /** @@ -1367,61 +1251,25 @@ 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()) -}); - export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.number(), z.void() ]); -export const zDummyAData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zDummyAResponse = z400; -export const zDummyBData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * Success */ 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()) -}); - export const zCallWithResponseResponse = zImport; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zCallWithDuplicateResponsesResponse = z.union([ z.intersection(zModelWithBoolean, zModelWithInteger), zModelWithString ]); -export const zCallWithResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.optional(z.readonly(z.string())), @@ -1432,36 +1280,30 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - 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())) - }) +export const zCollectionFormatQuery = z.object({ + 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())) }); -export const zTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.object({ - id: z.optional(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' }))) - })), - query: z.object({ - parameterNumber: z._default(z.number(), 123), - 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', - 'Error' - ]) - }) +export const zTypesPath = z.object({ + id: z.optional(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' }))) +}); + +export const zTypesQuery = z.object({ + parameterNumber: z._default(z.number(), 123), + 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', + 'Error' + ]) }); export const zTypesResponse = z.union([ @@ -1471,23 +1313,17 @@ export const zTypesResponse = z.union([ z.record(z.string(), z.unknown()) ]); -export const zUploadFileData = z.object({ - body: z.string(), - path: z.object({ - 'api-version': z.nullable(z.string()) - }), - query: z.optional(z.never()) +export const zUploadFileBody = z.string(); + +export const zUploadFilePath = z.object({ + 'api-version': z.nullable(z.string()) }); export const zUploadFileResponse = z.boolean(); -export const zFileResponseData = z.object({ - body: z.optional(z.never()), - path: z.object({ - id: z.string(), - 'api-version': z.string() - }), - query: z.optional(z.never()) +export const zFileResponsePath = z.object({ + id: z.string(), + 'api-version': z.string() }); /** @@ -1495,19 +1331,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()), - query: z.object({ - parameterObject: z.object({ - first: z.optional(z.object({ - second: z.optional(z.object({ - third: z.optional(z.string()) - })) +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.optional(z.object({ + second: z.optional(z.object({ + third: z.optional(z.string()) })) - }), - parameterReference: zModelWithString - }) + })) + }), + parameterReference: zModelWithString }); /** @@ -1515,12 +1347,6 @@ 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()) -}); - /** * OK */ @@ -1532,43 +1358,37 @@ export const zMultipartResponseResponse = z.object({ })) }); -export const zMultipartRequestData = z.object({ - body: z.optional(z.object({ - content: z.optional(z.string()), - data: z.nullish(zModelWithString) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zComplexParamsData = z.object({ - body: z.optional(z.object({ - 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.nullish(z.array(zModelWithString)), - listOfStrings: z.nullish(z.array(z.string())), - parameters: z.union([ - zModelWithString, - zModelWithEnum, - zModelWithArray, - zModelWithDictionary - ]), - 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.nullish(z.readonly(z.string())) - }))) - })), - path: z.object({ - id: 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' })), - 'api-version': z.string() - }), - query: z.optional(z.never()) +export const zMultipartRequestBody = z.object({ + content: z.optional(z.string()), + data: z.nullish(zModelWithString) +}); + +export const zComplexParamsBody = z.object({ + 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.nullish(z.array(zModelWithString)), + listOfStrings: z.nullish(z.array(z.string())), + parameters: z.union([ + zModelWithString, + zModelWithEnum, + zModelWithArray, + zModelWithDictionary + ]), + 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.nullish(z.readonly(z.string())) + }))) +}); + +export const zComplexParamsPath = z.object({ + id: 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' })), + 'api-version': z.string() }); /** @@ -1576,26 +1396,12 @@ 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()) +export const zTestErrorCodeQuery = z.object({ + status: z.int() }); -export const zTestErrorCodeData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - status: z.int() - }) -}); - -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.int() }); /** @@ -1603,8 +1409,4 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); -export const zPutWithFormUrlEncodedData = z.object({ - body: zArrayWithStrings, - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +export const zPutWithFormUrlEncodedBody = zArrayWithStrings; diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/type-format/zod.gen.ts index e21bae535..ae37637b5 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/mini/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.int() }); -export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * OK */ 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 ae765fb53..91920a121 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 @@ -1081,55 +1081,23 @@ export const zSimpleRequestBody = zModelWithString; export const zSimpleFormData = zModelWithString; -export const zExportData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zImportData = z.object({ - body: z.union([ - zModelWithReadOnlyAndWriteOnlyWritable, - zModelWithArrayReadOnlyAndWriteOnlyWritable - ]), - path: z.never().optional(), - query: z.never().optional() -}); +export const zImportBody = z.union([ + zModelWithReadOnlyAndWriteOnlyWritable, + zModelWithArrayReadOnlyAndWriteOnlyWritable +]); export const zImportResponse = z.union([ zModelFromZendesk, zModelWithReadOnlyAndWriteOnly ]); -export const zFooWowData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zApiVVersionODataControllerCountData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; -export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.string() - }), - query: z.never().optional() +export const zGetApiVbyApiVersionSimpleOperationPath = z.object({ + foo_param: z.string() }); /** @@ -1137,131 +1105,87 @@ export const zGetApiVbyApiVersionSimpleOperationData = z.object({ */ export const zGetApiVbyApiVersionSimpleOperationResponse = z.number(); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooHeaders = z.object({ + 'x-Foo-Bar': zModelWithString }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooPath = z.object({ + foo_param: z.string(), + BarParam: z.string() }); -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDescriptionsQuery = 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() }); -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeprecatedCallHeaders = z.object({ + parameter: zDeprecatedModel.nullable() }); -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * This is the parameter that goes into the body + */ +export const zCallWithParametersBody = z.record(z.unknown()).nullable(); -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string().nullable() }); -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersPath = z.object({ + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }); -export const zDeleteFooData3 = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.string(), - BarParam: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'x-Foo-Bar': zModelWithString - }) +export const zCallWithParametersQuery = z.object({ + foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), + foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, + cursor: z.string().nullable() }); -export const zCallWithDescriptionsData = z.object({ - 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() +/** + * This is the parameter that goes into the body + */ +export const zCallWithWeirdParameterNamesBody = zModelWithString.nullable(); + +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string().nullable() }); -export const zDeprecatedCallData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - parameter: zDeprecatedModel.nullable() - }) +export const zCallWithWeirdParameterNamesPath = z.object({ + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string().nullable() }); -export const zCallWithParametersData = z.object({ - body: z.record(z.unknown()).nullable(), - path: z.object({ - parameterPath: z.string().nullable(), - 'api-version': z.string().nullable() - }), - query: z.object({ - foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), - foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.string().nullable() - }), - headers: z.object({ - parameterHeader: z.string().nullable() - }) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.string().optional(), + 'parameter-query': z.string().nullable() }); -export const zCallWithWeirdParameterNamesData = z.object({ - 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.string().nullable() - }), - query: z.object({ - default: z.string().optional(), - 'parameter-query': z.string().nullable() - }), - headers: z.object({ - 'parameter.header': z.string().nullable() - }) +/** + * This is a required parameter + */ +export const zGetCallWithOptionalParamBody = zModelWithOneOfEnum; + +export const zGetCallWithOptionalParamQuery = z.object({ + page: z.number().optional() }); -export const zGetCallWithOptionalParamData = z.object({ - body: zModelWithOneOfEnum, - path: z.never().optional(), - query: z.object({ - page: z.number().optional() - }).optional() +/** + * This is an optional parameter + */ +export const zPostCallWithOptionalParamBody = z.object({ + offset: z.number().nullish() }); -export const zPostCallWithOptionalParamData = z.object({ - body: z.object({ - offset: z.number().nullish() - }).optional(), - path: z.never().optional(), - query: z.object({ - parameter: zPageable - }) +export const zPostCallWithOptionalParamQuery = z.object({ + parameter: zPageable }); export const zPostCallWithOptionalParamResponse = z.union([ @@ -1269,97 +1193,57 @@ export const zPostCallWithOptionalParamResponse = z.union([ z.void() ]); -export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: zSimpleRequestBody.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zPostApiVbyApiVersionFormDataData = z.object({ - body: zSimpleFormData.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zCallWithDefaultParametersData = z.object({ - 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' - ]).optional(), - parameterModel: zModelWithString.nullish() - }).optional() -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - 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(), - parameterModel: zModelWithString.optional() - }).optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionRequestBodyBody = zSimpleRequestBody; -export const zCallToTestOrderOfParamsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.string().nullish(), - parameterStringNullableWithDefault: z.string().nullish().default(null) - }) +export const zPostApiVbyApiVersionRequestBodyQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateNameData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionFormDataBody = zSimpleFormData; -export const zDuplicateName2Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zPostApiVbyApiVersionFormDataQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateName3Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultParametersQuery = 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' + ]).optional(), + parameterModel: zModelWithString.nullish() }); -export const zDuplicateName4Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultOptionalParametersQuery = 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(), + parameterModel: zModelWithString.optional() }); -export const zCallWithNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallToTestOrderOfParamsQuery = z.object({ + 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.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }); /** @@ -1367,61 +1251,25 @@ export const zCallWithNoContentResponseData = z.object({ */ export const zCallWithNoContentResponseResponse = z.void(); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.number(), z.void() ]); -export const zDummyAData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zDummyAResponse = z400; -export const zDummyBData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zDummyBResponse = z.void(); -export const zCallWithResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseResponse = zImport; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithDuplicateResponsesResponse = z.union([ zModelWithBoolean.and(zModelWithInteger), zModelWithString ]); -export const zCallWithResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.string().readonly().optional(), @@ -1432,36 +1280,30 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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 zCollectionFormatQuery = z.object({ + 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.never().optional(), - path: 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' }).optional() - }).optional(), - query: z.object({ - parameterNumber: z.number().default(123), - 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', - 'Error' - ]) - }) +export const zTypesPath = 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' }).optional() +}); + +export const zTypesQuery = z.object({ + parameterNumber: z.number().default(123), + 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', + 'Error' + ]) }); export const zTypesResponse = z.union([ @@ -1471,23 +1313,17 @@ export const zTypesResponse = z.union([ z.record(z.unknown()) ]); -export const zUploadFileData = z.object({ - body: z.string(), - path: z.object({ - 'api-version': z.string().nullable() - }), - query: z.never().optional() +export const zUploadFileBody = z.string(); + +export const zUploadFilePath = z.object({ + 'api-version': z.string().nullable() }); export const zUploadFileResponse = z.boolean(); -export const zFileResponseData = z.object({ - body: z.never().optional(), - path: z.object({ - id: z.string(), - 'api-version': z.string() - }), - query: z.never().optional() +export const zFileResponsePath = z.object({ + id: z.string(), + 'api-version': z.string() }); /** @@ -1495,19 +1331,15 @@ export const zFileResponseData = z.object({ */ export const zFileResponseResponse = z.string(); -export const zComplexTypesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterObject: z.object({ - first: z.object({ - second: z.object({ - third: z.string().optional() - }).optional() +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.object({ + second: z.object({ + third: z.string().optional() }).optional() - }), - parameterReference: zModelWithString - }) + }).optional() + }), + parameterReference: zModelWithString }); /** @@ -1515,12 +1347,6 @@ export const zComplexTypesData = z.object({ */ export const zComplexTypesResponse = z.array(zModelWithString); -export const zMultipartResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ @@ -1532,43 +1358,37 @@ export const zMultipartResponseResponse = z.object({ }).optional() }); -export const zMultipartRequestData = z.object({ - 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.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.array(zModelWithString).nullish(), - listOfStrings: z.array(z.string()).nullish(), - parameters: z.union([ - zModelWithString, - zModelWithEnum, - zModelWithArray, - zModelWithDictionary - ]), - 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.string().readonly().nullish() - }).readonly().optional() - }).optional(), - path: 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' }), - 'api-version': z.string() - }), - query: z.never().optional() +export const zMultipartRequestBody = z.object({ + content: z.string().optional(), + data: zModelWithString.nullish() +}); + +export const zComplexParamsBody = 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.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), + parameters: z.union([ + zModelWithString, + zModelWithEnum, + zModelWithArray, + zModelWithDictionary + ]), + 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.string().readonly().nullish() + }).readonly().optional() +}); + +export const zComplexParamsPath = 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' }), + 'api-version': z.string() }); /** @@ -1576,26 +1396,12 @@ export const zComplexParamsData = z.object({ */ export const zComplexParamsResponse = zModelWithString; -export const zCallWithResultFromHeaderData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zTestErrorCodeData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - status: z.number().int() - }) +export const zTestErrorCodeQuery = z.object({ + status: z.number().int() }); -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.number().int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.number().int() }); /** @@ -1603,8 +1409,4 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); -export const zPutWithFormUrlEncodedData = z.object({ - body: zArrayWithStrings, - path: z.never().optional(), - query: z.never().optional() -}); +export const zPutWithFormUrlEncodedBody = zArrayWithStrings; diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/type-format/zod.gen.ts index f7a98f3d5..9e6617bdb 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.number().int() }); -export const zPostFooData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ 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 9d6fb8aa9..c0fc81c05 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 @@ -1081,55 +1081,23 @@ export const zSimpleRequestBody = zModelWithString; export const zSimpleFormData = zModelWithString; -export const zExportData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zImportData = z.object({ - body: z.union([ - zModelWithReadOnlyAndWriteOnlyWritable, - zModelWithArrayReadOnlyAndWriteOnlyWritable - ]), - path: z.never().optional(), - query: z.never().optional() -}); +export const zImportBody = z.union([ + zModelWithReadOnlyAndWriteOnlyWritable, + zModelWithArrayReadOnlyAndWriteOnlyWritable +]); export const zImportResponse = z.union([ zModelFromZendesk, zModelWithReadOnlyAndWriteOnly ]); -export const zFooWowData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zApiVVersionODataControllerCountData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; -export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.string() - }), - query: z.never().optional() +export const zGetApiVbyApiVersionSimpleOperationPath = z.object({ + foo_param: z.string() }); /** @@ -1137,131 +1105,87 @@ export const zGetApiVbyApiVersionSimpleOperationData = z.object({ */ export const zGetApiVbyApiVersionSimpleOperationResponse = z.number(); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooHeaders = z.object({ + 'x-Foo-Bar': zModelWithString }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooPath = z.object({ + foo_param: z.string(), + BarParam: z.string() }); -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDescriptionsQuery = 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() }); -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeprecatedCallHeaders = z.object({ + parameter: zDeprecatedModel.nullable() }); -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * This is the parameter that goes into the body + */ +export const zCallWithParametersBody = z.record(z.string(), z.unknown()).nullable(); -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string().nullable() }); -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersPath = z.object({ + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }); -export const zDeleteFooData3 = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.string(), - BarParam: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'x-Foo-Bar': zModelWithString - }) +export const zCallWithParametersQuery = z.object({ + foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), + foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, + cursor: z.string().nullable() }); -export const zCallWithDescriptionsData = z.object({ - 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() +/** + * This is the parameter that goes into the body + */ +export const zCallWithWeirdParameterNamesBody = zModelWithString.nullable(); + +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string().nullable() }); -export const zDeprecatedCallData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - parameter: zDeprecatedModel.nullable() - }) +export const zCallWithWeirdParameterNamesPath = z.object({ + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string().nullable() }); -export const zCallWithParametersData = z.object({ - body: z.record(z.string(), z.unknown()).nullable(), - path: z.object({ - parameterPath: z.string().nullable(), - 'api-version': z.string().nullable() - }), - query: z.object({ - foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), - foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.string().nullable() - }), - headers: z.object({ - parameterHeader: z.string().nullable() - }) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.string().optional(), + 'parameter-query': z.string().nullable() }); -export const zCallWithWeirdParameterNamesData = z.object({ - 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.string().nullable() - }), - query: z.object({ - default: z.string().optional(), - 'parameter-query': z.string().nullable() - }), - headers: z.object({ - 'parameter.header': z.string().nullable() - }) +/** + * This is a required parameter + */ +export const zGetCallWithOptionalParamBody = zModelWithOneOfEnum; + +export const zGetCallWithOptionalParamQuery = z.object({ + page: z.number().optional() }); -export const zGetCallWithOptionalParamData = z.object({ - body: zModelWithOneOfEnum, - path: z.never().optional(), - query: z.object({ - page: z.number().optional() - }).optional() +/** + * This is an optional parameter + */ +export const zPostCallWithOptionalParamBody = z.object({ + offset: z.number().nullish() }); -export const zPostCallWithOptionalParamData = z.object({ - body: z.object({ - offset: z.number().nullish() - }).optional(), - path: z.never().optional(), - query: z.object({ - parameter: zPageable - }) +export const zPostCallWithOptionalParamQuery = z.object({ + parameter: zPageable }); export const zPostCallWithOptionalParamResponse = z.union([ @@ -1269,97 +1193,57 @@ export const zPostCallWithOptionalParamResponse = z.union([ z.void() ]); -export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: zSimpleRequestBody.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zPostApiVbyApiVersionFormDataData = z.object({ - body: zSimpleFormData.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zCallWithDefaultParametersData = z.object({ - 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' - ]).optional(), - parameterModel: zModelWithString.nullish() - }).optional() -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - 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(), - parameterModel: zModelWithString.optional() - }).optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionRequestBodyBody = zSimpleRequestBody; -export const zCallToTestOrderOfParamsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.string().nullish(), - parameterStringNullableWithDefault: z.string().nullish().default(null) - }) +export const zPostApiVbyApiVersionRequestBodyQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateNameData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionFormDataBody = zSimpleFormData; -export const zDuplicateName2Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zPostApiVbyApiVersionFormDataQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateName3Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultParametersQuery = 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' + ]).optional(), + parameterModel: zModelWithString.nullish() }); -export const zDuplicateName4Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultOptionalParametersQuery = 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(), + parameterModel: zModelWithString.optional() }); -export const zCallWithNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallToTestOrderOfParamsQuery = z.object({ + 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.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }); /** @@ -1367,61 +1251,25 @@ export const zCallWithNoContentResponseData = z.object({ */ export const zCallWithNoContentResponseResponse = z.void(); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.number(), z.void() ]); -export const zDummyAData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zDummyAResponse = z400; -export const zDummyBData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zDummyBResponse = z.void(); -export const zCallWithResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseResponse = zImport; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithDuplicateResponsesResponse = z.union([ zModelWithBoolean.and(zModelWithInteger), zModelWithString ]); -export const zCallWithResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.string().readonly().optional(), @@ -1432,36 +1280,30 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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 zCollectionFormatQuery = z.object({ + 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.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().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', - 'Error' - ]) - }) +export const zTypesPath = 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() +}); + +export const zTypesQuery = z.object({ + parameterNumber: z.number().default(123), + 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', + 'Error' + ]) }); export const zTypesResponse = z.union([ @@ -1471,23 +1313,17 @@ export const zTypesResponse = z.union([ z.record(z.string(), z.unknown()) ]); -export const zUploadFileData = z.object({ - body: z.string(), - path: z.object({ - 'api-version': z.string().nullable() - }), - query: z.never().optional() +export const zUploadFileBody = z.string(); + +export const zUploadFilePath = z.object({ + 'api-version': z.string().nullable() }); export const zUploadFileResponse = z.boolean(); -export const zFileResponseData = z.object({ - body: z.never().optional(), - path: z.object({ - id: z.string(), - 'api-version': z.string() - }), - query: z.never().optional() +export const zFileResponsePath = z.object({ + id: z.string(), + 'api-version': z.string() }); /** @@ -1495,19 +1331,15 @@ export const zFileResponseData = z.object({ */ export const zFileResponseResponse = z.string(); -export const zComplexTypesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterObject: z.object({ - first: z.object({ - second: z.object({ - third: z.string().optional() - }).optional() +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.object({ + second: z.object({ + third: z.string().optional() }).optional() - }), - parameterReference: zModelWithString - }) + }).optional() + }), + parameterReference: zModelWithString }); /** @@ -1515,12 +1347,6 @@ export const zComplexTypesData = z.object({ */ export const zComplexTypesResponse = z.array(zModelWithString); -export const zMultipartResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ @@ -1532,43 +1358,37 @@ export const zMultipartResponseResponse = z.object({ }).optional() }); -export const zMultipartRequestData = z.object({ - 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.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.array(zModelWithString).nullish(), - listOfStrings: z.array(z.string()).nullish(), - parameters: z.union([ - zModelWithString, - zModelWithEnum, - zModelWithArray, - zModelWithDictionary - ]), - 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.never().optional() +export const zMultipartRequestBody = z.object({ + content: z.string().optional(), + data: zModelWithString.nullish() +}); + +export const zComplexParamsBody = 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.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), + parameters: z.union([ + zModelWithString, + zModelWithEnum, + zModelWithArray, + zModelWithDictionary + ]), + 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() +}); + +export const zComplexParamsPath = 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() }); /** @@ -1576,26 +1396,12 @@ export const zComplexParamsData = z.object({ */ export const zComplexParamsResponse = zModelWithString; -export const zCallWithResultFromHeaderData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zTestErrorCodeData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - status: z.int() - }) +export const zTestErrorCodeQuery = z.object({ + status: z.int() }); -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.int() }); /** @@ -1603,8 +1409,4 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); -export const zPutWithFormUrlEncodedData = z.object({ - body: zArrayWithStrings, - path: z.never().optional(), - query: z.never().optional() -}); +export const zPutWithFormUrlEncodedBody = zArrayWithStrings; diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/type-format/zod.gen.ts index 9b6647e58..85477ff58 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v4/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.int() }); -export const zPostFooData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ 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 92fc8ee9f..671a115ff 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 @@ -1096,58 +1096,26 @@ 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()) -}); - -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zImportData = z.object({ - body: z.union([ - zModelWithReadOnlyAndWriteOnlyWritable, - zModelWithArrayReadOnlyAndWriteOnlyWritable - ]), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +export const zImportBody = z.union([ + zModelWithReadOnlyAndWriteOnlyWritable, + zModelWithArrayReadOnlyAndWriteOnlyWritable +]); export const zImportResponse = z.union([ zModelFromZendesk, zModelWithReadOnlyAndWriteOnly ]); -export const zFooWowData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zApiVVersionODataControllerCountData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * Success */ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; -export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.optional(z.never()), - path: z.object({ - foo_param: z.union([ - z.string(), - z.uuid() - ]) - }), - query: z.optional(z.never()) +export const zGetApiVbyApiVersionSimpleOperationPath = z.object({ + foo_param: z.union([ + z.string(), + z.uuid() + ]) }); /** @@ -1155,131 +1123,87 @@ 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()) +export const zDeleteFooHeaders = z.object({ + 'x-Foo-Bar': zModelWithString }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zDeleteFooPath = z.object({ + foo_param: z.string(), + BarParam: z.string() }); -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDescriptionsQuery = 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()) }); -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zDeprecatedCallHeaders = z.object({ + parameter: z.nullable(zDeprecatedModel) }); -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +/** + * This is the parameter that goes into the body + */ +export const zCallWithParametersBody = z.nullable(z.record(z.string(), z.unknown())); -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.nullable(z.string()) }); -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersPath = z.object({ + parameterPath: z.nullable(z.string()), + 'api-version': z.nullable(z.string()) }); -export const zDeleteFooData3 = z.object({ - body: z.optional(z.never()), - path: z.object({ - foo_param: z.string(), - BarParam: z.string() - }), - query: z.optional(z.never()), - headers: z.object({ - 'x-Foo-Bar': zModelWithString - }) +export const zCallWithParametersQuery = z.object({ + foo_ref_enum: z.optional(zModelWithNestedArrayEnumsDataFoo), + foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, + cursor: z.nullable(z.string()) }); -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()) - })) +/** + * This is the parameter that goes into the body + */ +export const zCallWithWeirdParameterNamesBody = z.nullable(zModelWithString); + +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.nullable(z.string()) }); -export const zDeprecatedCallData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()), - headers: z.object({ - parameter: z.nullable(zDeprecatedModel) - }) +export const zCallWithWeirdParameterNamesPath = 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.nullable(z.string()) }); -export const zCallWithParametersData = z.object({ - body: z.nullable(z.record(z.string(), z.unknown())), - path: z.object({ - 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.nullable(z.string()) - }), - headers: z.object({ - parameterHeader: z.nullable(z.string()) - }) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.optional(z.string()), + 'parameter-query': z.nullable(z.string()) }); -export const zCallWithWeirdParameterNamesData = z.object({ - 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.nullable(z.string()) - }), - query: z.object({ - default: z.optional(z.string()), - 'parameter-query': z.nullable(z.string()) - }), - headers: z.object({ - 'parameter.header': z.nullable(z.string()) - }) +/** + * This is a required parameter + */ +export const zGetCallWithOptionalParamBody = zModelWithOneOfEnum; + +export const zGetCallWithOptionalParamQuery = z.object({ + page: z.optional(z.number()) }); -export const zGetCallWithOptionalParamData = z.object({ - body: zModelWithOneOfEnum, - path: z.optional(z.never()), - query: z.optional(z.object({ - page: z.optional(z.number()) - })) +/** + * This is an optional parameter + */ +export const zPostCallWithOptionalParamBody = z.object({ + offset: z.nullish(z.number()) }); -export const zPostCallWithOptionalParamData = z.object({ - body: z.optional(z.object({ - offset: z.nullish(z.number()) - })), - path: z.optional(z.never()), - query: z.object({ - parameter: zPageable - }) +export const zPostCallWithOptionalParamQuery = z.object({ + parameter: zPageable }); export const zPostCallWithOptionalParamResponse = z.union([ @@ -1287,97 +1211,57 @@ export const zPostCallWithOptionalParamResponse = z.union([ z.void() ]); -export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: z.optional(zSimpleRequestBody), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) -}); - -export const zPostApiVbyApiVersionFormDataData = z.object({ - body: z.optional(zSimpleFormData), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) -}); - -export const zCallWithDefaultParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - 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.nullish(zModelWithString) - })) -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z._default(z.optional(z.string()), 'Hello World!'), - parameterNumber: z._default(z.optional(z.number()), 123), - parameterBoolean: z._default(z.optional(z.boolean()), true), - parameterEnum: z.optional(z.enum([ - 'Success', - 'Warning', - 'Error' - ])), - parameterModel: z._default(z.optional(zModelWithString), { prop: 'Hello World!' }) - })) -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionRequestBodyBody = zSimpleRequestBody; -export const zCallToTestOrderOfParamsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - parameterOptionalStringWithDefault: z._default(z.optional(z.string()), 'Hello World!'), - parameterOptionalStringWithEmptyDefault: z._default(z.optional(z.string()), ''), - parameterOptionalStringWithNoDefault: z.optional(z.string()), - parameterStringWithDefault: z._default(z.string(), 'Hello World!'), - parameterStringWithEmptyDefault: z._default(z.string(), ''), - parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.nullish(z.string()), - parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) - }) +export const zPostApiVbyApiVersionRequestBodyQuery = z.object({ + parameter: z.optional(z.string()) }); -export const zDuplicateNameData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionFormDataBody = zSimpleFormData; -export const zDuplicateName2Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zPostApiVbyApiVersionFormDataQuery = z.object({ + parameter: z.optional(z.string()) }); -export const zDuplicateName3Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDefaultParametersQuery = z.object({ + 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.nullish(zModelWithString) }); -export const zDuplicateName4Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDefaultOptionalParametersQuery = z.object({ + parameterString: z._default(z.optional(z.string()), 'Hello World!'), + parameterNumber: z._default(z.optional(z.number()), 123), + parameterBoolean: z._default(z.optional(z.boolean()), true), + parameterEnum: z.optional(z.enum([ + 'Success', + 'Warning', + 'Error' + ])), + parameterModel: z._default(z.optional(zModelWithString), { prop: 'Hello World!' }) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallToTestOrderOfParamsQuery = z.object({ + parameterOptionalStringWithDefault: z._default(z.optional(z.string()), 'Hello World!'), + parameterOptionalStringWithEmptyDefault: z._default(z.optional(z.string()), ''), + parameterOptionalStringWithNoDefault: z.optional(z.string()), + parameterStringWithDefault: z._default(z.string(), 'Hello World!'), + parameterStringWithEmptyDefault: z._default(z.string(), ''), + parameterStringWithNoDefault: z.string(), + parameterStringNullableWithNoDefault: z.nullish(z.string()), + parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) }); /** @@ -1385,61 +1269,25 @@ 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()) -}); - export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.number(), z.void() ]); -export const zDummyAData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zDummyAResponse = z400; -export const zDummyBData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * Success */ 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()) -}); - export const zCallWithResponseResponse = zImport; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zCallWithDuplicateResponsesResponse = z.union([ z.intersection(zModelWithBoolean, zModelWithInteger), zModelWithString ]); -export const zCallWithResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.optional(z.readonly(z.string())), @@ -1450,36 +1298,30 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - 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())) - }) -}); - -export const zTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.object({ - id: z.optional(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' }))) - })), - query: z.object({ - parameterNumber: z._default(z.number(), 123), - 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') - ])) - }) +export const zCollectionFormatQuery = z.object({ + 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())) +}); + +export const zTypesPath = z.object({ + id: z.optional(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' }))) +}); + +export const zTypesQuery = z.object({ + parameterNumber: z._default(z.number(), 123), + 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') + ])) }); export const zTypesResponse = z.union([ @@ -1489,23 +1331,17 @@ export const zTypesResponse = z.union([ z.record(z.string(), z.unknown()) ]); -export const zUploadFileData = z.object({ - body: z.string(), - path: z.object({ - 'api-version': z.nullable(z.string()) - }), - query: z.optional(z.never()) +export const zUploadFileBody = z.string(); + +export const zUploadFilePath = z.object({ + 'api-version': z.nullable(z.string()) }); export const zUploadFileResponse = z.boolean(); -export const zFileResponseData = z.object({ - body: z.optional(z.never()), - path: z.object({ - id: z.string(), - 'api-version': z.string() - }), - query: z.optional(z.never()) +export const zFileResponsePath = z.object({ + id: z.string(), + 'api-version': z.string() }); /** @@ -1513,19 +1349,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()), - query: z.object({ - parameterObject: z.object({ - first: z.optional(z.object({ - second: z.optional(z.object({ - third: z.optional(z.string()) - })) +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.optional(z.object({ + second: z.optional(z.object({ + third: z.optional(z.string()) })) - }), - parameterReference: zModelWithString - }) + })) + }), + parameterReference: zModelWithString }); /** @@ -1533,12 +1365,6 @@ 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()) -}); - /** * OK */ @@ -1550,43 +1376,37 @@ export const zMultipartResponseResponse = z.object({ })) }); -export const zMultipartRequestData = z.object({ - body: z.optional(z.object({ - content: z.optional(z.string()), - data: z.nullish(zModelWithString) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zComplexParamsData = z.object({ - body: z.optional(z.object({ - 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.nullish(z.array(zModelWithString)), - listOfStrings: z.nullish(z.array(z.string())), - parameters: z.union([ - zModelWithString, - zModelWithEnum, - zModelWithArray, - zModelWithDictionary - ]), - 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.nullish(z.readonly(z.string())) - }))) - })), - path: z.object({ - id: 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' })), - 'api-version': z.string() - }), - query: z.optional(z.never()) +export const zMultipartRequestBody = z.object({ + content: z.optional(z.string()), + data: z.nullish(zModelWithString) +}); + +export const zComplexParamsBody = z.object({ + 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.nullish(z.array(zModelWithString)), + listOfStrings: z.nullish(z.array(z.string())), + parameters: z.union([ + zModelWithString, + zModelWithEnum, + zModelWithArray, + zModelWithDictionary + ]), + 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.nullish(z.readonly(z.string())) + }))) +}); + +export const zComplexParamsPath = z.object({ + id: 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' })), + 'api-version': z.string() }); /** @@ -1594,26 +1414,12 @@ 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()) +export const zTestErrorCodeQuery = z.object({ + status: z.int() }); -export const zTestErrorCodeData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - status: z.int() - }) -}); - -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.int() }); /** @@ -1621,8 +1427,4 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); -export const zPutWithFormUrlEncodedData = z.object({ - body: zArrayWithStrings, - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +export const zPutWithFormUrlEncodedBody = zArrayWithStrings; diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/type-format/zod.gen.ts index e21bae535..ae37637b5 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/mini/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.int() }); -export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * OK */ 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 9b93e42fc..f98d3a4d1 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: z.optional(zBar) }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.optional(z.string()) - }), - 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 })) - })) +export const zPatchFooBody = z.object({ + foo: z.optional(z.string()) }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zPatchFooQuery = 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 })) }); + +export const zPostFooBody = zFoo3; 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 87ec55918..33c918fb8 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 @@ -44,26 +44,20 @@ export const zFoo3 = z.object({ foo: z.optional(zBar) }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.optional(z.string()) - }), - path: z.optional(z.never()), - query: z.optional(z.object({ - foo: z.optional(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()) - })) +export const zPatchFooBody = z.object({ + foo: z.optional(z.string()) }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zPatchFooQuery = z.object({ + foo: z.optional(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()) }); + +export const zPostFooBody = zFoo3; 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 272e5ee8b..a0e7680f8 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 @@ -46,28 +46,24 @@ export const zFoo3 = z.object({ export type FooZodType3 = z.infer; -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.optional(z.string()) - }), - 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()) - })) +export const zPatchFooBody = z.object({ + foo: z.optional(z.string()) }); -export type PatchFooDataZodType = z.infer; +export type PatchFooBodyZodType = z.infer; -export const zPostFooData = z.object({ - body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zPatchFooQuery = 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()) }); -export type PostFooDataZodType = z.infer; +export type PatchFooQueryZodType = z.infer; + +export const zPostFooBody = zFoo3; + +export type PostFooBodyZodType = 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 e21539a88..0cc767f51 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: z.optional(zBar) }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.optional(z.string()) - }), - 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()) - })) +export const zPatchFooBody = z.object({ + foo: z.optional(z.string()) }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zPatchFooQuery = 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()) }); + +export const zPostFooBody = zFoo3; 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 497cd4c1b..b444c5f8b 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 @@ -1096,58 +1096,26 @@ export const zSimpleRequestBody = zModelWithString; */ export const zSimpleFormData = zModelWithString; -export const zExportData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zImportData = z.object({ - body: z.union([ - zModelWithReadOnlyAndWriteOnlyWritable, - zModelWithArrayReadOnlyAndWriteOnlyWritable - ]), - path: z.never().optional(), - query: z.never().optional() -}); +export const zImportBody = z.union([ + zModelWithReadOnlyAndWriteOnlyWritable, + zModelWithArrayReadOnlyAndWriteOnlyWritable +]); export const zImportResponse = z.union([ zModelFromZendesk, zModelWithReadOnlyAndWriteOnly ]); -export const zFooWowData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zApiVVersionODataControllerCountData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; -export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.union([ - z.string(), - z.string().uuid() - ]) - }), - query: z.never().optional() +export const zGetApiVbyApiVersionSimpleOperationPath = z.object({ + foo_param: z.union([ + z.string(), + z.string().uuid() + ]) }); /** @@ -1155,131 +1123,87 @@ export const zGetApiVbyApiVersionSimpleOperationData = z.object({ */ export const zGetApiVbyApiVersionSimpleOperationResponse = z.number(); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooHeaders = z.object({ + 'x-Foo-Bar': zModelWithString }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooPath = z.object({ + foo_param: z.string(), + BarParam: z.string() }); -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDescriptionsQuery = 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() }); -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeprecatedCallHeaders = z.object({ + parameter: zDeprecatedModel.nullable() }); -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * This is the parameter that goes into the body + */ +export const zCallWithParametersBody = z.record(z.unknown()).nullable(); -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string().nullable() }); -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersPath = z.object({ + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }); -export const zDeleteFooData3 = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.string(), - BarParam: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'x-Foo-Bar': zModelWithString - }) +export const zCallWithParametersQuery = z.object({ + foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), + foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, + cursor: z.string().nullable() }); -export const zCallWithDescriptionsData = z.object({ - 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() +/** + * This is the parameter that goes into the body + */ +export const zCallWithWeirdParameterNamesBody = zModelWithString.nullable(); + +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string().nullable() }); -export const zDeprecatedCallData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - parameter: zDeprecatedModel.nullable() - }) +export const zCallWithWeirdParameterNamesPath = z.object({ + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string().nullable() }); -export const zCallWithParametersData = z.object({ - body: z.record(z.unknown()).nullable(), - path: z.object({ - parameterPath: z.string().nullable(), - 'api-version': z.string().nullable() - }), - query: z.object({ - foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), - foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.string().nullable() - }), - headers: z.object({ - parameterHeader: z.string().nullable() - }) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.string().optional(), + 'parameter-query': z.string().nullable() }); -export const zCallWithWeirdParameterNamesData = z.object({ - 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.string().nullable() - }), - query: z.object({ - default: z.string().optional(), - 'parameter-query': z.string().nullable() - }), - headers: z.object({ - 'parameter.header': z.string().nullable() - }) +/** + * This is a required parameter + */ +export const zGetCallWithOptionalParamBody = zModelWithOneOfEnum; + +export const zGetCallWithOptionalParamQuery = z.object({ + page: z.number().optional() }); -export const zGetCallWithOptionalParamData = z.object({ - body: zModelWithOneOfEnum, - path: z.never().optional(), - query: z.object({ - page: z.number().optional() - }).optional() +/** + * This is an optional parameter + */ +export const zPostCallWithOptionalParamBody = z.object({ + offset: z.number().nullish() }); -export const zPostCallWithOptionalParamData = z.object({ - body: z.object({ - offset: z.number().nullish() - }).optional(), - path: z.never().optional(), - query: z.object({ - parameter: zPageable - }) +export const zPostCallWithOptionalParamQuery = z.object({ + parameter: zPageable }); export const zPostCallWithOptionalParamResponse = z.union([ @@ -1287,97 +1211,57 @@ export const zPostCallWithOptionalParamResponse = z.union([ z.void() ]); -export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: zSimpleRequestBody.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zPostApiVbyApiVersionFormDataData = z.object({ - body: zSimpleFormData.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zCallWithDefaultParametersData = z.object({ - 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' - ]).optional(), - parameterModel: zModelWithString.nullish() - }).optional() -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - 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(), - parameterModel: zModelWithString.optional().default({ prop: 'Hello World!' }) - }).optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionRequestBodyBody = zSimpleRequestBody; -export const zCallToTestOrderOfParamsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.string().nullish(), - parameterStringNullableWithDefault: z.string().nullish().default(null) - }) +export const zPostApiVbyApiVersionRequestBodyQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateNameData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionFormDataBody = zSimpleFormData; -export const zDuplicateName2Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zPostApiVbyApiVersionFormDataQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateName3Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultParametersQuery = 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' + ]).optional(), + parameterModel: zModelWithString.nullish() }); -export const zDuplicateName4Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultOptionalParametersQuery = 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(), + parameterModel: zModelWithString.optional().default({ prop: 'Hello World!' }) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallToTestOrderOfParamsQuery = z.object({ + 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.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }); /** @@ -1385,61 +1269,25 @@ export const zCallWithNoContentResponseData = z.object({ */ export const zCallWithNoContentResponseResponse = z.void(); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.number(), z.void() ]); -export const zDummyAData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zDummyAResponse = z400; -export const zDummyBData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zDummyBResponse = z.void(); -export const zCallWithResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseResponse = zImport; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithDuplicateResponsesResponse = z.union([ zModelWithBoolean.and(zModelWithInteger), zModelWithString ]); -export const zCallWithResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.string().readonly().optional(), @@ -1450,36 +1298,30 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.never().optional(), - path: 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' }).optional() - }).optional(), - query: z.object({ - parameterNumber: z.number().default(123), - 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') - ]).nullable() - }) +export const zCollectionFormatQuery = z.object({ + 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 zTypesPath = 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' }).optional() +}); + +export const zTypesQuery = z.object({ + parameterNumber: z.number().default(123), + 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') + ]).nullable() }); export const zTypesResponse = z.union([ @@ -1489,23 +1331,17 @@ export const zTypesResponse = z.union([ z.record(z.unknown()) ]); -export const zUploadFileData = z.object({ - body: z.string(), - path: z.object({ - 'api-version': z.string().nullable() - }), - query: z.never().optional() +export const zUploadFileBody = z.string(); + +export const zUploadFilePath = z.object({ + 'api-version': z.string().nullable() }); export const zUploadFileResponse = z.boolean(); -export const zFileResponseData = z.object({ - body: z.never().optional(), - path: z.object({ - id: z.string(), - 'api-version': z.string() - }), - query: z.never().optional() +export const zFileResponsePath = z.object({ + id: z.string(), + 'api-version': z.string() }); /** @@ -1513,19 +1349,15 @@ export const zFileResponseData = z.object({ */ export const zFileResponseResponse = z.string(); -export const zComplexTypesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterObject: z.object({ - first: z.object({ - second: z.object({ - third: z.string().optional() - }).optional() +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.object({ + second: z.object({ + third: z.string().optional() }).optional() - }), - parameterReference: zModelWithString - }) + }).optional() + }), + parameterReference: zModelWithString }); /** @@ -1533,12 +1365,6 @@ export const zComplexTypesData = z.object({ */ export const zComplexTypesResponse = z.array(zModelWithString); -export const zMultipartResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ @@ -1550,43 +1376,37 @@ export const zMultipartResponseResponse = z.object({ }).optional() }); -export const zMultipartRequestData = z.object({ - 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.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.array(zModelWithString).nullish(), - listOfStrings: z.array(z.string()).nullish(), - parameters: z.union([ - zModelWithString, - zModelWithEnum, - zModelWithArray, - zModelWithDictionary - ]), - 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.string().readonly().nullish() - }).readonly().optional() - }).optional(), - path: 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' }), - 'api-version': z.string() - }), - query: z.never().optional() +export const zMultipartRequestBody = z.object({ + content: z.string().optional(), + data: zModelWithString.nullish() +}); + +export const zComplexParamsBody = 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.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), + parameters: z.union([ + zModelWithString, + zModelWithEnum, + zModelWithArray, + zModelWithDictionary + ]), + 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.string().readonly().nullish() + }).readonly().optional() +}); + +export const zComplexParamsPath = 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' }), + 'api-version': z.string() }); /** @@ -1594,26 +1414,12 @@ export const zComplexParamsData = z.object({ */ export const zComplexParamsResponse = zModelWithString; -export const zCallWithResultFromHeaderData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zTestErrorCodeData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - status: z.number().int() - }) +export const zTestErrorCodeQuery = z.object({ + status: z.number().int() }); -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.number().int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.number().int() }); /** @@ -1621,8 +1427,4 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); -export const zPutWithFormUrlEncodedData = z.object({ - body: zArrayWithStrings, - path: z.never().optional(), - query: z.never().optional() -}); +export const zPutWithFormUrlEncodedBody = zArrayWithStrings; diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/type-format/zod.gen.ts index f7a98f3d5..9e6617bdb 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.number().int() }); -export const zPostFooData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ 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 56a06552a..518849bee 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: zBar.optional() }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - path: z.never().optional(), - query: z.object({ - foo: z.string().optional(), - bar: zBar.optional(), - baz: z.object({ - baz: z.string().optional() - }).optional(), - qux: z.string().date().optional(), - quux: z.string().datetime({ offset: true }).optional() - }).optional() +export const zPatchFooBody = z.object({ + foo: z.string().optional() }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = z.object({ + foo: z.string().optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.string().date().optional(), + quux: z.string().datetime({ offset: true }).optional() }); + +export const zPostFooBody = zFoo3; 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 685be7b15..a984a7a42 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: zBar.optional() }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - path: z.never().optional(), - query: z.object({ - foo: z.string().describe('This is Foo parameter.').optional(), - bar: zBar.optional(), - baz: z.object({ - baz: z.string().optional() - }).optional(), - qux: z.string().date().optional(), - quux: z.string().datetime().optional() - }).optional() +export const zPatchFooBody = z.object({ + foo: z.string().optional() }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = z.object({ + foo: z.string().describe('This is Foo parameter.').optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.string().date().optional(), + quux: z.string().datetime().optional() }); + +export const zPostFooBody = zFoo3; 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 89abc2a22..deafcaf48 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 @@ -46,28 +46,24 @@ export const zFoo3 = z.object({ export type FooZodType3 = z.infer; -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - path: z.never().optional(), - query: z.object({ - foo: z.string().optional(), - bar: zBar.optional(), - baz: z.object({ - baz: z.string().optional() - }).optional(), - qux: z.string().date().optional(), - quux: z.string().datetime().optional() - }).optional() +export const zPatchFooBody = z.object({ + foo: z.string().optional() }); -export type PatchFooDataZodType = z.infer; +export type PatchFooBodyZodType = z.infer; -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = z.object({ + foo: z.string().optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.string().date().optional(), + quux: z.string().datetime().optional() }); -export type PostFooDataZodType = z.infer; +export type PatchFooQueryZodType = z.infer; + +export const zPostFooBody = zFoo3; + +export type PostFooBodyZodType = 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 9ccffb61d..43072cb35 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: zBar.optional() }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - path: z.never().optional(), - query: z.object({ - foo: z.string().optional(), - bar: zBar.optional(), - baz: z.object({ - baz: z.string().optional() - }).optional(), - qux: z.string().date().optional(), - quux: z.string().datetime().optional() - }).optional() +export const zPatchFooBody = z.object({ + foo: z.string().optional() }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = z.object({ + foo: z.string().optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.string().date().optional(), + quux: z.string().datetime().optional() }); + +export const zPostFooBody = zFoo3; 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 1aec887d3..23bfd10ea 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 @@ -1096,58 +1096,26 @@ export const zSimpleRequestBody = zModelWithString; */ export const zSimpleFormData = zModelWithString; -export const zExportData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zImportData = z.object({ - body: z.union([ - zModelWithReadOnlyAndWriteOnlyWritable, - zModelWithArrayReadOnlyAndWriteOnlyWritable - ]), - path: z.never().optional(), - query: z.never().optional() -}); +export const zImportBody = z.union([ + zModelWithReadOnlyAndWriteOnlyWritable, + zModelWithArrayReadOnlyAndWriteOnlyWritable +]); export const zImportResponse = z.union([ zModelFromZendesk, zModelWithReadOnlyAndWriteOnly ]); -export const zFooWowData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zApiVVersionODataControllerCountData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; -export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.union([ - z.string(), - z.uuid() - ]) - }), - query: z.never().optional() +export const zGetApiVbyApiVersionSimpleOperationPath = z.object({ + foo_param: z.union([ + z.string(), + z.uuid() + ]) }); /** @@ -1155,131 +1123,87 @@ export const zGetApiVbyApiVersionSimpleOperationData = z.object({ */ export const zGetApiVbyApiVersionSimpleOperationResponse = z.number(); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooHeaders = z.object({ + 'x-Foo-Bar': zModelWithString }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooPath = z.object({ + foo_param: z.string(), + BarParam: z.string() }); -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDescriptionsQuery = 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() }); -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeprecatedCallHeaders = z.object({ + parameter: zDeprecatedModel.nullable() }); -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * This is the parameter that goes into the body + */ +export const zCallWithParametersBody = z.record(z.string(), z.unknown()).nullable(); -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string().nullable() }); -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersPath = z.object({ + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }); -export const zDeleteFooData3 = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.string(), - BarParam: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'x-Foo-Bar': zModelWithString - }) +export const zCallWithParametersQuery = z.object({ + foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), + foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, + cursor: z.string().nullable() }); -export const zCallWithDescriptionsData = z.object({ - 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() +/** + * This is the parameter that goes into the body + */ +export const zCallWithWeirdParameterNamesBody = zModelWithString.nullable(); + +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string().nullable() }); -export const zDeprecatedCallData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - parameter: zDeprecatedModel.nullable() - }) +export const zCallWithWeirdParameterNamesPath = z.object({ + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string().nullable() }); -export const zCallWithParametersData = z.object({ - body: z.record(z.string(), z.unknown()).nullable(), - path: z.object({ - parameterPath: z.string().nullable(), - 'api-version': z.string().nullable() - }), - query: z.object({ - foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), - foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.string().nullable() - }), - headers: z.object({ - parameterHeader: z.string().nullable() - }) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.string().optional(), + 'parameter-query': z.string().nullable() }); -export const zCallWithWeirdParameterNamesData = z.object({ - 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.string().nullable() - }), - query: z.object({ - default: z.string().optional(), - 'parameter-query': z.string().nullable() - }), - headers: z.object({ - 'parameter.header': z.string().nullable() - }) +/** + * This is a required parameter + */ +export const zGetCallWithOptionalParamBody = zModelWithOneOfEnum; + +export const zGetCallWithOptionalParamQuery = z.object({ + page: z.number().optional() }); -export const zGetCallWithOptionalParamData = z.object({ - body: zModelWithOneOfEnum, - path: z.never().optional(), - query: z.object({ - page: z.number().optional() - }).optional() +/** + * This is an optional parameter + */ +export const zPostCallWithOptionalParamBody = z.object({ + offset: z.number().nullish() }); -export const zPostCallWithOptionalParamData = z.object({ - body: z.object({ - offset: z.number().nullish() - }).optional(), - path: z.never().optional(), - query: z.object({ - parameter: zPageable - }) +export const zPostCallWithOptionalParamQuery = z.object({ + parameter: zPageable }); export const zPostCallWithOptionalParamResponse = z.union([ @@ -1287,97 +1211,57 @@ export const zPostCallWithOptionalParamResponse = z.union([ z.void() ]); -export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: zSimpleRequestBody.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zPostApiVbyApiVersionFormDataData = z.object({ - body: zSimpleFormData.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zCallWithDefaultParametersData = z.object({ - 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' - ]).optional(), - parameterModel: zModelWithString.nullish() - }).optional() -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - 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(), - parameterModel: zModelWithString.optional().default({ prop: 'Hello World!' }) - }).optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionRequestBodyBody = zSimpleRequestBody; -export const zCallToTestOrderOfParamsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.string().nullish(), - parameterStringNullableWithDefault: z.string().nullish().default(null) - }) +export const zPostApiVbyApiVersionRequestBodyQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateNameData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionFormDataBody = zSimpleFormData; -export const zDuplicateName2Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zPostApiVbyApiVersionFormDataQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateName3Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultParametersQuery = 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' + ]).optional(), + parameterModel: zModelWithString.nullish() }); -export const zDuplicateName4Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultOptionalParametersQuery = 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(), + parameterModel: zModelWithString.optional().default({ prop: 'Hello World!' }) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallToTestOrderOfParamsQuery = z.object({ + 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.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }); /** @@ -1385,61 +1269,25 @@ export const zCallWithNoContentResponseData = z.object({ */ export const zCallWithNoContentResponseResponse = z.void(); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.number(), z.void() ]); -export const zDummyAData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zDummyAResponse = z400; -export const zDummyBData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zDummyBResponse = z.void(); -export const zCallWithResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseResponse = zImport; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithDuplicateResponsesResponse = z.union([ zModelWithBoolean.and(zModelWithInteger), zModelWithString ]); -export const zCallWithResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.string().readonly().optional(), @@ -1450,36 +1298,30 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.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().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') - ]).nullable() - }) +export const zCollectionFormatQuery = z.object({ + 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 zTypesPath = 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() +}); + +export const zTypesQuery = z.object({ + parameterNumber: z.number().default(123), + 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') + ]).nullable() }); export const zTypesResponse = z.union([ @@ -1489,23 +1331,17 @@ export const zTypesResponse = z.union([ z.record(z.string(), z.unknown()) ]); -export const zUploadFileData = z.object({ - body: z.string(), - path: z.object({ - 'api-version': z.string().nullable() - }), - query: z.never().optional() +export const zUploadFileBody = z.string(); + +export const zUploadFilePath = z.object({ + 'api-version': z.string().nullable() }); export const zUploadFileResponse = z.boolean(); -export const zFileResponseData = z.object({ - body: z.never().optional(), - path: z.object({ - id: z.string(), - 'api-version': z.string() - }), - query: z.never().optional() +export const zFileResponsePath = z.object({ + id: z.string(), + 'api-version': z.string() }); /** @@ -1513,19 +1349,15 @@ export const zFileResponseData = z.object({ */ export const zFileResponseResponse = z.string(); -export const zComplexTypesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterObject: z.object({ - first: z.object({ - second: z.object({ - third: z.string().optional() - }).optional() +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.object({ + second: z.object({ + third: z.string().optional() }).optional() - }), - parameterReference: zModelWithString - }) + }).optional() + }), + parameterReference: zModelWithString }); /** @@ -1533,12 +1365,6 @@ export const zComplexTypesData = z.object({ */ export const zComplexTypesResponse = z.array(zModelWithString); -export const zMultipartResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ @@ -1550,43 +1376,37 @@ export const zMultipartResponseResponse = z.object({ }).optional() }); -export const zMultipartRequestData = z.object({ - 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.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.array(zModelWithString).nullish(), - listOfStrings: z.array(z.string()).nullish(), - parameters: z.union([ - zModelWithString, - zModelWithEnum, - zModelWithArray, - zModelWithDictionary - ]), - 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.never().optional() +export const zMultipartRequestBody = z.object({ + content: z.string().optional(), + data: zModelWithString.nullish() +}); + +export const zComplexParamsBody = 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.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), + parameters: z.union([ + zModelWithString, + zModelWithEnum, + zModelWithArray, + zModelWithDictionary + ]), + 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() +}); + +export const zComplexParamsPath = 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() }); /** @@ -1594,26 +1414,12 @@ export const zComplexParamsData = z.object({ */ export const zComplexParamsResponse = zModelWithString; -export const zCallWithResultFromHeaderData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zTestErrorCodeData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - status: z.int() - }) +export const zTestErrorCodeQuery = z.object({ + status: z.int() }); -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.int() }); /** @@ -1621,8 +1427,4 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); -export const zPutWithFormUrlEncodedData = z.object({ - body: zArrayWithStrings, - path: z.never().optional(), - query: z.never().optional() -}); +export const zPutWithFormUrlEncodedBody = zArrayWithStrings; diff --git a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/type-format/zod.gen.ts index 9b6647e58..85477ff58 100644 --- a/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v4/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.int() }); -export const zPostFooData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ 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 400ed387a..3fe68dd1e 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: zBar.optional() }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - 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 zPatchFooBody = z.object({ + foo: z.string().optional() }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = 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() }); + +export const zPostFooBody = zFoo3; 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 8adbe94ba..4b8affd9a 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 @@ -44,26 +44,20 @@ export const zFoo3 = z.object({ foo: zBar.optional() }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - path: z.never().optional(), - query: z.object({ - foo: z.string().register(z.globalRegistry, { - description: 'This is Foo parameter.' - }).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 zPatchFooBody = z.object({ + foo: z.string().optional() }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = z.object({ + foo: z.string().register(z.globalRegistry, { + description: 'This is Foo parameter.' + }).optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.iso.date().optional(), + quux: z.iso.datetime().optional() }); + +export const zPostFooBody = zFoo3; 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 2fcda22b9..fdf095f5d 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 @@ -46,28 +46,24 @@ export const zFoo3 = z.object({ export type FooZodType3 = z.infer; -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - 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 zPatchFooBody = z.object({ + foo: z.string().optional() }); -export type PatchFooDataZodType = z.infer; +export type PatchFooBodyZodType = z.infer; -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = 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() }); -export type PostFooDataZodType = z.infer; +export type PatchFooQueryZodType = z.infer; + +export const zPostFooBody = zFoo3; + +export type PostFooBodyZodType = z.infer; 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 d6b4bb64a..ff18cb34c 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: zBar.optional() }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - 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 zPatchFooBody = z.object({ + foo: z.string().optional() }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = 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() }); + +export const zPostFooBody = zFoo3; 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 1c8209528..64e7cd31f 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 @@ -452,192 +452,83 @@ export const zModelWithPatternWritable = z.object({ patternWithUnicode: z.optional(z.string().check(z.regex(/^\p{L}+$/u))) }); -export const zServiceWithEmptyTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDescriptionsQuery = 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()) }); -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string() }); -export const zFooWowData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersPath = z.object({ + parameterPath: z.string(), + 'api-version': z.string() }); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersQuery = z.object({ + parameterQuery: z.string() }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -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()) - })) -}); - -export const zCallWithParametersData = z.object({ - body: z.optional(z.never()), - path: z.object({ - parameterPath: z.string(), - 'api-version': z.string() - }), - query: z.object({ - parameterQuery: z.string() - }), - headers: z.object({ - parameterHeader: z.string() - }) -}); - -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()), - 'api-version': z.string() - }), - query: z.object({ - default: z.optional(z.string()), - 'parameter-query': z.string() - }), - headers: z.object({ - 'parameter.header': z.string() - }) -}); - -export const zCallWithDefaultParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - parameterString: z._default(z.string(), 'Hello World!'), - parameterNumber: z._default(z.number(), 123), - parameterBoolean: z._default(z.boolean(), true), - parameterEnum: z.enum([ - 'Success', - 'Warning', - 'Error' - ]), - parameterModel: z._default(z.object({ - prop: z.optional(z.string()) - }), { 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._default(z.optional(z.string()), 'Hello World!'), - parameterNumber: z._default(z.optional(z.number()), 123), - parameterBoolean: z._default(z.optional(z.boolean()), true), - parameterEnum: z.optional(z.enum([ - 'Success', - 'Warning', - 'Error' - ])) - })) -}); - -export const zCallToTestOrderOfParamsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - parameterOptionalStringWithDefault: z._default(z.optional(z.string()), 'Hello World!'), - parameterOptionalStringWithEmptyDefault: z._default(z.optional(z.string()), ''), - parameterOptionalStringWithNoDefault: z.optional(z.string()), - parameterStringWithDefault: z._default(z.string(), 'Hello World!'), - parameterStringWithEmptyDefault: z._default(z.string(), ''), - parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.nullish(z.string()), - parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) - }) -}); +/** + * This is the parameter that is sent as request body + */ +export const zCallWithWeirdParameterNamesBody = z.string(); -export const zDuplicateNameData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string() }); -export const zDuplicateName2Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithWeirdParameterNamesPath = 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.string() }); -export const zDuplicateName3Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.optional(z.string()), + 'parameter-query': z.string() }); -export const zDuplicateName4Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDefaultParametersQuery = z.object({ + parameterString: z._default(z.string(), 'Hello World!'), + parameterNumber: z._default(z.number(), 123), + parameterBoolean: z._default(z.boolean(), true), + parameterEnum: z.enum([ + 'Success', + 'Warning', + 'Error' + ]), + parameterModel: z._default(z.object({ + prop: z.optional(z.string()) + }), { prop: 'Hello World!' }) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDefaultOptionalParametersQuery = z.object({ + parameterString: z._default(z.optional(z.string()), 'Hello World!'), + parameterNumber: z._default(z.optional(z.number()), 123), + parameterBoolean: z._default(z.optional(z.boolean()), true), + parameterEnum: z.optional(z.enum([ + 'Success', + 'Warning', + 'Error' + ])) }); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallToTestOrderOfParamsQuery = z.object({ + parameterOptionalStringWithDefault: z._default(z.optional(z.string()), 'Hello World!'), + parameterOptionalStringWithEmptyDefault: z._default(z.optional(z.string()), ''), + parameterOptionalStringWithNoDefault: z.optional(z.string()), + parameterStringWithDefault: z._default(z.string(), 'Hello World!'), + parameterStringWithEmptyDefault: z._default(z.string(), ''), + parameterStringWithNoDefault: z.string(), + parameterStringNullableWithNoDefault: z.nullish(z.string()), + parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) }); export const zCallWithResponseAndNoContentResponseResponse = z.union([ @@ -645,46 +536,16 @@ export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.unknown() ]); -export const zDummyAData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zDummyBData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zCallWithResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * Message for default response */ export const zCallWithResponseResponse = zModelWithString; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * Message for 201 response */ export const zCallWithDuplicateResponsesResponse = zModelWithString; -export const zCallWithResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.optional(z.readonly(z.string())), @@ -695,35 +556,29 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - parameterArrayCSV: z.array(z.string()), - parameterArraySSV: z.array(z.string()), - parameterArrayTSV: z.array(z.string()), - parameterArrayPipes: z.array(z.string()), - parameterArrayMulti: z.array(z.string()) - }) +export const zCollectionFormatQuery = z.object({ + parameterArrayCSV: z.array(z.string()), + parameterArraySSV: z.array(z.string()), + parameterArrayTSV: z.array(z.string()), + parameterArrayPipes: z.array(z.string()), + parameterArrayMulti: z.array(z.string()) }); -export const zTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.object({ - id: z.optional(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' }))) - })), - query: z.object({ - parameterNumber: z._default(z.number(), 123), - parameterString: z._default(z.string(), 'default'), - parameterBoolean: z._default(z.boolean(), true), - parameterArray: z.array(z.string()), - parameterDictionary: z.record(z.string(), z.unknown()), - parameterEnum: z.enum([ - 'Success', - 'Warning', - 'Error' - ]) - }) +export const zTypesPath = z.object({ + id: z.optional(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' }))) +}); + +export const zTypesQuery = z.object({ + parameterNumber: z._default(z.number(), 123), + parameterString: z._default(z.string(), 'default'), + parameterBoolean: z._default(z.boolean(), true), + parameterArray: z.array(z.string()), + parameterDictionary: z.record(z.string(), z.unknown()), + parameterEnum: z.enum([ + 'Success', + 'Warning', + 'Error' + ]) }); export const zTypesResponse = z.union([ @@ -733,20 +588,16 @@ export const zTypesResponse = z.union([ z.record(z.string(), z.unknown()) ]); -export const zComplexTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - parameterObject: z.object({ - first: z.optional(z.object({ - second: z.optional(z.object({ - third: z.optional(z.string()) - })) +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.optional(z.object({ + second: z.optional(z.object({ + third: z.optional(z.string()) })) - }), - parameterReference: z.object({ - prop: z.optional(z.string()) - }) + })) + }), + parameterReference: z.object({ + prop: z.optional(z.string()) }) }); @@ -755,26 +606,12 @@ 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()) -}); - -export const zTestErrorCodeData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - status: z.string() - }) +export const zTestErrorCodeQuery = z.object({ + status: z.string() }); -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.int() }); /** @@ -782,11 +619,10 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = zNonAsciiStringæøåÆøÅöôêÊ字符串; -export const zPostApiVbyApiVersionBodyData = z.object({ - body: zParameterActivityParams, - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +/** + * Body should not be unknown + */ +export const zPostApiVbyApiVersionBodyBody = zParameterActivityParams; /** * OK diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/type-format/sdk.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/type-format/sdk.gen.ts index aadc85c9f..d1796559d 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/type-format/sdk.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/type-format/sdk.gen.ts @@ -1,10 +1,12 @@ // This file is auto-generated by @hey-api/openapi-ts +import * as z from 'zod/mini'; + import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; import { postFooResponseTransformer } from './transformers.gen'; import type { PostFooData, PostFooResponses } from './types.gen'; -import { zPostFooData, zPostFooResponse } from './zod.gen'; +import { zPostFooResponse } from './zod.gen'; export type Options = Options2 & { /** @@ -21,7 +23,11 @@ export type Options(options?: Options) => (options?.client ?? client).post({ - requestValidator: async (data) => await zPostFooData.parseAsync(data), + requestValidator: async (data) => await z.object({ + body: z.optional(z.never()), + path: z.optional(z.never()), + query: z.optional(z.never()) + }).parseAsync(data), responseTransformer: postFooResponseTransformer, responseValidator: async (data) => await zPostFooResponse.parseAsync(data), url: '/foo', diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/type-format/zod.gen.ts index 41a01d04a..482008970 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/mini/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.int() }); -export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * OK */ 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 9a52d13e9..fb799c1b8 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 @@ -452,192 +452,83 @@ export const zModelWithPatternWritable = z.object({ patternWithUnicode: z.string().regex(/^\p{L}+$/u).optional() }); -export const zServiceWithEmptyTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDescriptionsQuery = 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() }); -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string() }); -export const zFooWowData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersPath = z.object({ + parameterPath: z.string(), + 'api-version': z.string() }); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersQuery = z.object({ + parameterQuery: z.string() }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zCallWithDescriptionsData = z.object({ - 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.never().optional(), - path: z.object({ - parameterPath: z.string(), - 'api-version': z.string() - }), - query: z.object({ - parameterQuery: z.string() - }), - headers: z.object({ - parameterHeader: z.string() - }) -}); - -export const zCallWithWeirdParameterNamesData = z.object({ - body: z.string(), - path: z.object({ - '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.string().optional(), - 'parameter-query': z.string() - }), - headers: z.object({ - 'parameter.header': z.string() - }) -}); - -export const zCallWithDefaultParametersData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterString: z.string().default('Hello World!'), - parameterNumber: z.number().default(123), - parameterBoolean: z.boolean().default(true), - parameterEnum: z.enum([ - 'Success', - 'Warning', - 'Error' - ]), - parameterModel: z.object({ - prop: z.string().optional() - }).default({ prop: 'Hello World!' }) - }) -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - 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.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.string().nullish(), - parameterStringNullableWithDefault: z.string().nullish().default(null) - }) -}); +/** + * This is the parameter that is sent as request body + */ +export const zCallWithWeirdParameterNamesBody = z.string(); -export const zDuplicateNameData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string() }); -export const zDuplicateName2Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithWeirdParameterNamesPath = z.object({ + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string() }); -export const zDuplicateName3Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.string().optional(), + 'parameter-query': z.string() }); -export const zDuplicateName4Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultParametersQuery = z.object({ + parameterString: z.string().default('Hello World!'), + parameterNumber: z.number().default(123), + parameterBoolean: z.boolean().default(true), + parameterEnum: z.enum([ + 'Success', + 'Warning', + 'Error' + ]), + parameterModel: z.object({ + prop: z.string().optional() + }).default({ prop: 'Hello World!' }) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultOptionalParametersQuery = 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() }); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallToTestOrderOfParamsQuery = z.object({ + 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.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }); export const zCallWithResponseAndNoContentResponseResponse = z.union([ @@ -645,46 +536,16 @@ export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.unknown() ]); -export const zDummyAData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zDummyBData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zCallWithResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Message for default response */ export const zCallWithResponseResponse = zModelWithString; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Message for 201 response */ export const zCallWithDuplicateResponsesResponse = zModelWithString; -export const zCallWithResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.string().readonly().optional(), @@ -695,35 +556,29 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterArrayCSV: z.array(z.string()), - parameterArraySSV: z.array(z.string()), - parameterArrayTSV: z.array(z.string()), - parameterArrayPipes: z.array(z.string()), - parameterArrayMulti: z.array(z.string()) - }) +export const zCollectionFormatQuery = z.object({ + parameterArrayCSV: z.array(z.string()), + parameterArraySSV: z.array(z.string()), + parameterArrayTSV: z.array(z.string()), + parameterArrayPipes: z.array(z.string()), + parameterArrayMulti: z.array(z.string()) }); -export const zTypesData = z.object({ - body: z.never().optional(), - path: 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' }).optional() - }).optional(), - query: z.object({ - parameterNumber: z.number().default(123), - parameterString: z.string().default('default'), - parameterBoolean: z.boolean().default(true), - parameterArray: z.array(z.string()), - parameterDictionary: z.record(z.unknown()), - parameterEnum: z.enum([ - 'Success', - 'Warning', - 'Error' - ]) - }) +export const zTypesPath = 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' }).optional() +}); + +export const zTypesQuery = z.object({ + parameterNumber: z.number().default(123), + parameterString: z.string().default('default'), + parameterBoolean: z.boolean().default(true), + parameterArray: z.array(z.string()), + parameterDictionary: z.record(z.unknown()), + parameterEnum: z.enum([ + 'Success', + 'Warning', + 'Error' + ]) }); export const zTypesResponse = z.union([ @@ -733,20 +588,16 @@ export const zTypesResponse = z.union([ z.record(z.unknown()) ]); -export const zComplexTypesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterObject: z.object({ - first: z.object({ - second: z.object({ - third: z.string().optional() - }).optional() +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.object({ + second: z.object({ + third: z.string().optional() }).optional() - }), - parameterReference: z.object({ - prop: z.string().optional() - }) + }).optional() + }), + parameterReference: z.object({ + prop: z.string().optional() }) }); @@ -755,26 +606,12 @@ export const zComplexTypesData = z.object({ */ export const zComplexTypesResponse = z.array(zModelWithString); -export const zCallWithResultFromHeaderData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zTestErrorCodeQuery = z.object({ + status: z.string() }); -export const zTestErrorCodeData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - status: z.string() - }) -}); - -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.number().int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.number().int() }); /** @@ -782,11 +619,10 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = zNonAsciiStringæøåÆøÅöôêÊ字符串; -export const zPostApiVbyApiVersionBodyData = z.object({ - body: zParameterActivityParams, - path: z.never().optional(), - query: z.never().optional() -}); +/** + * Body should not be unknown + */ +export const zPostApiVbyApiVersionBodyBody = zParameterActivityParams; /** * OK diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/type-format/sdk.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/type-format/sdk.gen.ts index aadc85c9f..2e3b86b27 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/type-format/sdk.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/type-format/sdk.gen.ts @@ -1,10 +1,12 @@ // This file is auto-generated by @hey-api/openapi-ts +import { z } from 'zod/v3'; + import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; import { postFooResponseTransformer } from './transformers.gen'; import type { PostFooData, PostFooResponses } from './types.gen'; -import { zPostFooData, zPostFooResponse } from './zod.gen'; +import { zPostFooResponse } from './zod.gen'; export type Options = Options2 & { /** @@ -21,7 +23,11 @@ export type Options(options?: Options) => (options?.client ?? client).post({ - requestValidator: async (data) => await zPostFooData.parseAsync(data), + requestValidator: async (data) => await z.object({ + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() + }).parseAsync(data), responseTransformer: postFooResponseTransformer, responseValidator: async (data) => await zPostFooResponse.parseAsync(data), url: '/foo', diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/type-format/zod.gen.ts index 262cf8307..01c7ccbc5 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.number().int() }); -export const zPostFooData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ 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 c8b413ed9..dc4cc947d 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 @@ -452,192 +452,83 @@ export const zModelWithPatternWritable = z.object({ patternWithUnicode: z.string().regex(/^\p{L}+$/u).optional() }); -export const zServiceWithEmptyTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDescriptionsQuery = 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() }); -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string() }); -export const zFooWowData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersPath = z.object({ + parameterPath: z.string(), + 'api-version': z.string() }); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersQuery = z.object({ + parameterQuery: z.string() }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zCallWithDescriptionsData = z.object({ - 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.never().optional(), - path: z.object({ - parameterPath: z.string(), - 'api-version': z.string() - }), - query: z.object({ - parameterQuery: z.string() - }), - headers: z.object({ - parameterHeader: z.string() - }) -}); - -export const zCallWithWeirdParameterNamesData = z.object({ - body: z.string(), - path: z.object({ - '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.string().optional(), - 'parameter-query': z.string() - }), - headers: z.object({ - 'parameter.header': z.string() - }) -}); - -export const zCallWithDefaultParametersData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterString: z.string().default('Hello World!'), - parameterNumber: z.number().default(123), - parameterBoolean: z.boolean().default(true), - parameterEnum: z.enum([ - 'Success', - 'Warning', - 'Error' - ]), - parameterModel: z.object({ - prop: z.string().optional() - }).default({ prop: 'Hello World!' }) - }) -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - 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.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.string().nullish(), - parameterStringNullableWithDefault: z.string().nullish().default(null) - }) -}); +/** + * This is the parameter that is sent as request body + */ +export const zCallWithWeirdParameterNamesBody = z.string(); -export const zDuplicateNameData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string() }); -export const zDuplicateName2Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithWeirdParameterNamesPath = z.object({ + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string() }); -export const zDuplicateName3Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.string().optional(), + 'parameter-query': z.string() }); -export const zDuplicateName4Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultParametersQuery = z.object({ + parameterString: z.string().default('Hello World!'), + parameterNumber: z.number().default(123), + parameterBoolean: z.boolean().default(true), + parameterEnum: z.enum([ + 'Success', + 'Warning', + 'Error' + ]), + parameterModel: z.object({ + prop: z.string().optional() + }).default({ prop: 'Hello World!' }) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultOptionalParametersQuery = 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() }); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallToTestOrderOfParamsQuery = z.object({ + 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.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }); export const zCallWithResponseAndNoContentResponseResponse = z.union([ @@ -645,46 +536,16 @@ export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.unknown() ]); -export const zDummyAData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zDummyBData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zCallWithResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Message for default response */ export const zCallWithResponseResponse = zModelWithString; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Message for 201 response */ export const zCallWithDuplicateResponsesResponse = zModelWithString; -export const zCallWithResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.string().readonly().optional(), @@ -695,35 +556,29 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterArrayCSV: z.array(z.string()), - parameterArraySSV: z.array(z.string()), - parameterArrayTSV: z.array(z.string()), - parameterArrayPipes: z.array(z.string()), - parameterArrayMulti: z.array(z.string()) - }) +export const zCollectionFormatQuery = z.object({ + parameterArrayCSV: z.array(z.string()), + parameterArraySSV: z.array(z.string()), + parameterArrayTSV: z.array(z.string()), + parameterArrayPipes: z.array(z.string()), + parameterArrayMulti: z.array(z.string()) }); -export const zTypesData = z.object({ - 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'), - parameterBoolean: z.boolean().default(true), - parameterArray: z.array(z.string()), - parameterDictionary: z.record(z.string(), z.unknown()), - parameterEnum: z.enum([ - 'Success', - 'Warning', - 'Error' - ]) - }) +export const zTypesPath = 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() +}); + +export const zTypesQuery = z.object({ + parameterNumber: z.number().default(123), + parameterString: z.string().default('default'), + parameterBoolean: z.boolean().default(true), + parameterArray: z.array(z.string()), + parameterDictionary: z.record(z.string(), z.unknown()), + parameterEnum: z.enum([ + 'Success', + 'Warning', + 'Error' + ]) }); export const zTypesResponse = z.union([ @@ -733,20 +588,16 @@ export const zTypesResponse = z.union([ z.record(z.string(), z.unknown()) ]); -export const zComplexTypesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterObject: z.object({ - first: z.object({ - second: z.object({ - third: z.string().optional() - }).optional() +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.object({ + second: z.object({ + third: z.string().optional() }).optional() - }), - parameterReference: z.object({ - prop: z.string().optional() - }) + }).optional() + }), + parameterReference: z.object({ + prop: z.string().optional() }) }); @@ -755,26 +606,12 @@ export const zComplexTypesData = z.object({ */ export const zComplexTypesResponse = z.array(zModelWithString); -export const zCallWithResultFromHeaderData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zTestErrorCodeQuery = z.object({ + status: z.string() }); -export const zTestErrorCodeData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - status: z.string() - }) -}); - -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.int() }); /** @@ -782,11 +619,10 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = zNonAsciiStringæøåÆøÅöôêÊ字符串; -export const zPostApiVbyApiVersionBodyData = z.object({ - body: zParameterActivityParams, - path: z.never().optional(), - query: z.never().optional() -}); +/** + * Body should not be unknown + */ +export const zPostApiVbyApiVersionBodyBody = zParameterActivityParams; /** * OK diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/type-format/sdk.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/type-format/sdk.gen.ts index aadc85c9f..f1b1a1e06 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/type-format/sdk.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/type-format/sdk.gen.ts @@ -1,10 +1,12 @@ // This file is auto-generated by @hey-api/openapi-ts +import * as z from 'zod'; + import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; import { postFooResponseTransformer } from './transformers.gen'; import type { PostFooData, PostFooResponses } from './types.gen'; -import { zPostFooData, zPostFooResponse } from './zod.gen'; +import { zPostFooResponse } from './zod.gen'; export type Options = Options2 & { /** @@ -21,7 +23,11 @@ export type Options(options?: Options) => (options?.client ?? client).post({ - requestValidator: async (data) => await zPostFooData.parseAsync(data), + requestValidator: async (data) => await z.object({ + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() + }).parseAsync(data), responseTransformer: postFooResponseTransformer, responseValidator: async (data) => await zPostFooResponse.parseAsync(data), url: '/foo', diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/type-format/zod.gen.ts index bb1956f79..6173cb820 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v4/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.int() }); -export const zPostFooData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ 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 b035545f7..dd640bbde 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 @@ -1081,55 +1081,23 @@ 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()) -}); - -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zImportData = z.object({ - body: z.union([ - zModelWithReadOnlyAndWriteOnlyWritable, - zModelWithArrayReadOnlyAndWriteOnlyWritable - ]), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +export const zImportBody = z.union([ + zModelWithReadOnlyAndWriteOnlyWritable, + zModelWithArrayReadOnlyAndWriteOnlyWritable +]); export const zImportResponse = z.union([ zModelFromZendesk, zModelWithReadOnlyAndWriteOnly ]); -export const zFooWowData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zApiVVersionODataControllerCountData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * Success */ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; -export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.optional(z.never()), - path: z.object({ - foo_param: z.string() - }), - query: z.optional(z.never()) +export const zGetApiVbyApiVersionSimpleOperationPath = z.object({ + foo_param: z.string() }); /** @@ -1137,131 +1105,87 @@ 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()) +export const zDeleteFooHeaders = z.object({ + 'x-Foo-Bar': zModelWithString }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zDeleteFooPath = z.object({ + foo_param: z.string(), + BarParam: z.string() }); -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDescriptionsQuery = 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()) }); -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zDeprecatedCallHeaders = z.object({ + parameter: z.nullable(zDeprecatedModel) }); -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +/** + * This is the parameter that goes into the body + */ +export const zCallWithParametersBody = z.nullable(z.record(z.string(), z.unknown())); -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.nullable(z.string()) }); -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersPath = z.object({ + parameterPath: z.nullable(z.string()), + 'api-version': z.nullable(z.string()) }); -export const zDeleteFooData3 = z.object({ - body: z.optional(z.never()), - path: z.object({ - foo_param: z.string(), - BarParam: z.string() - }), - query: z.optional(z.never()), - headers: z.object({ - 'x-Foo-Bar': zModelWithString - }) +export const zCallWithParametersQuery = z.object({ + foo_ref_enum: z.optional(zModelWithNestedArrayEnumsDataFoo), + foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, + cursor: z.nullable(z.string()) }); -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()) - })) +/** + * This is the parameter that goes into the body + */ +export const zCallWithWeirdParameterNamesBody = z.nullable(zModelWithString); + +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.nullable(z.string()) }); -export const zDeprecatedCallData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()), - headers: z.object({ - parameter: z.nullable(zDeprecatedModel) - }) +export const zCallWithWeirdParameterNamesPath = 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.nullable(z.string()) }); -export const zCallWithParametersData = z.object({ - body: z.nullable(z.record(z.string(), z.unknown())), - path: z.object({ - 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.nullable(z.string()) - }), - headers: z.object({ - parameterHeader: z.nullable(z.string()) - }) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.optional(z.string()), + 'parameter-query': z.nullable(z.string()) }); -export const zCallWithWeirdParameterNamesData = z.object({ - 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.nullable(z.string()) - }), - query: z.object({ - default: z.optional(z.string()), - 'parameter-query': z.nullable(z.string()) - }), - headers: z.object({ - 'parameter.header': z.nullable(z.string()) - }) +/** + * This is a required parameter + */ +export const zGetCallWithOptionalParamBody = zModelWithOneOfEnum; + +export const zGetCallWithOptionalParamQuery = z.object({ + page: z.optional(z.number()) }); -export const zGetCallWithOptionalParamData = z.object({ - body: zModelWithOneOfEnum, - path: z.optional(z.never()), - query: z.optional(z.object({ - page: z.optional(z.number()) - })) +/** + * This is an optional parameter + */ +export const zPostCallWithOptionalParamBody = z.object({ + offset: z.nullish(z.number()) }); -export const zPostCallWithOptionalParamData = z.object({ - body: z.optional(z.object({ - offset: z.nullish(z.number()) - })), - path: z.optional(z.never()), - query: z.object({ - parameter: zPageable - }) +export const zPostCallWithOptionalParamQuery = z.object({ + parameter: zPageable }); export const zPostCallWithOptionalParamResponse = z.union([ @@ -1269,97 +1193,57 @@ export const zPostCallWithOptionalParamResponse = z.union([ z.void() ]); -export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: z.optional(zSimpleRequestBody), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) -}); - -export const zPostApiVbyApiVersionFormDataData = z.object({ - body: z.optional(zSimpleFormData), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) -}); - -export const zCallWithDefaultParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - 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.nullish(zModelWithString) - })) -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z._default(z.optional(z.string()), 'Hello World!'), - parameterNumber: z._default(z.optional(z.number()), 123), - parameterBoolean: z._default(z.optional(z.boolean()), true), - parameterEnum: z.optional(z.enum([ - 'Success', - 'Warning', - 'Error' - ])), - parameterModel: z.optional(zModelWithString) - })) -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionRequestBodyBody = zSimpleRequestBody; -export const zCallToTestOrderOfParamsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - parameterOptionalStringWithDefault: z._default(z.optional(z.string()), 'Hello World!'), - parameterOptionalStringWithEmptyDefault: z._default(z.optional(z.string()), ''), - parameterOptionalStringWithNoDefault: z.optional(z.string()), - parameterStringWithDefault: z._default(z.string(), 'Hello World!'), - parameterStringWithEmptyDefault: z._default(z.string(), ''), - parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.nullish(z.string()), - parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) - }) +export const zPostApiVbyApiVersionRequestBodyQuery = z.object({ + parameter: z.optional(z.string()) }); -export const zDuplicateNameData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionFormDataBody = zSimpleFormData; -export const zDuplicateName2Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zPostApiVbyApiVersionFormDataQuery = z.object({ + parameter: z.optional(z.string()) }); -export const zDuplicateName3Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDefaultParametersQuery = z.object({ + 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.nullish(zModelWithString) }); -export const zDuplicateName4Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDefaultOptionalParametersQuery = z.object({ + parameterString: z._default(z.optional(z.string()), 'Hello World!'), + parameterNumber: z._default(z.optional(z.number()), 123), + parameterBoolean: z._default(z.optional(z.boolean()), true), + parameterEnum: z.optional(z.enum([ + 'Success', + 'Warning', + 'Error' + ])), + parameterModel: z.optional(zModelWithString) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallToTestOrderOfParamsQuery = z.object({ + parameterOptionalStringWithDefault: z._default(z.optional(z.string()), 'Hello World!'), + parameterOptionalStringWithEmptyDefault: z._default(z.optional(z.string()), ''), + parameterOptionalStringWithNoDefault: z.optional(z.string()), + parameterStringWithDefault: z._default(z.string(), 'Hello World!'), + parameterStringWithEmptyDefault: z._default(z.string(), ''), + parameterStringWithNoDefault: z.string(), + parameterStringNullableWithNoDefault: z.nullish(z.string()), + parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) }); /** @@ -1367,61 +1251,25 @@ 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()) -}); - export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.number(), z.void() ]); -export const zDummyAData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zDummyAResponse = z400; -export const zDummyBData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * Success */ 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()) -}); - export const zCallWithResponseResponse = zImport; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zCallWithDuplicateResponsesResponse = z.union([ z.intersection(zModelWithBoolean, zModelWithInteger), zModelWithString ]); -export const zCallWithResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.optional(z.readonly(z.string())), @@ -1432,36 +1280,30 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - 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())) - }) +export const zCollectionFormatQuery = z.object({ + 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())) }); -export const zTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.object({ - id: z.optional(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' }))) - })), - query: z.object({ - parameterNumber: z._default(z.number(), 123), - 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', - 'Error' - ]) - }) +export const zTypesPath = z.object({ + id: z.optional(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' }))) +}); + +export const zTypesQuery = z.object({ + parameterNumber: z._default(z.number(), 123), + 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', + 'Error' + ]) }); export const zTypesResponse = z.union([ @@ -1471,23 +1313,17 @@ export const zTypesResponse = z.union([ z.record(z.string(), z.unknown()) ]); -export const zUploadFileData = z.object({ - body: z.string(), - path: z.object({ - 'api-version': z.nullable(z.string()) - }), - query: z.optional(z.never()) +export const zUploadFileBody = z.string(); + +export const zUploadFilePath = z.object({ + 'api-version': z.nullable(z.string()) }); export const zUploadFileResponse = z.boolean(); -export const zFileResponseData = z.object({ - body: z.optional(z.never()), - path: z.object({ - id: z.string(), - 'api-version': z.string() - }), - query: z.optional(z.never()) +export const zFileResponsePath = z.object({ + id: z.string(), + 'api-version': z.string() }); /** @@ -1495,19 +1331,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()), - query: z.object({ - parameterObject: z.object({ - first: z.optional(z.object({ - second: z.optional(z.object({ - third: z.optional(z.string()) - })) +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.optional(z.object({ + second: z.optional(z.object({ + third: z.optional(z.string()) })) - }), - parameterReference: zModelWithString - }) + })) + }), + parameterReference: zModelWithString }); /** @@ -1515,12 +1347,6 @@ 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()) -}); - /** * OK */ @@ -1532,43 +1358,37 @@ export const zMultipartResponseResponse = z.object({ })) }); -export const zMultipartRequestData = z.object({ - body: z.optional(z.object({ - content: z.optional(z.string()), - data: z.nullish(zModelWithString) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zComplexParamsData = z.object({ - body: z.optional(z.object({ - 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.nullish(z.array(zModelWithString)), - listOfStrings: z.nullish(z.array(z.string())), - parameters: z.union([ - zModelWithString, - zModelWithEnum, - zModelWithArray, - zModelWithDictionary - ]), - 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.nullish(z.readonly(z.string())) - }))) - })), - path: z.object({ - id: 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' })), - 'api-version': z.string() - }), - query: z.optional(z.never()) +export const zMultipartRequestBody = z.object({ + content: z.optional(z.string()), + data: z.nullish(zModelWithString) +}); + +export const zComplexParamsBody = z.object({ + 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.nullish(z.array(zModelWithString)), + listOfStrings: z.nullish(z.array(z.string())), + parameters: z.union([ + zModelWithString, + zModelWithEnum, + zModelWithArray, + zModelWithDictionary + ]), + 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.nullish(z.readonly(z.string())) + }))) +}); + +export const zComplexParamsPath = z.object({ + id: 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' })), + 'api-version': z.string() }); /** @@ -1576,26 +1396,12 @@ 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()) +export const zTestErrorCodeQuery = z.object({ + status: z.int() }); -export const zTestErrorCodeData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - status: z.int() - }) -}); - -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.int() }); /** @@ -1603,8 +1409,4 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); -export const zPutWithFormUrlEncodedData = z.object({ - body: zArrayWithStrings, - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +export const zPutWithFormUrlEncodedBody = zArrayWithStrings; diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/type-format/sdk.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/type-format/sdk.gen.ts index aadc85c9f..d1796559d 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/type-format/sdk.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/type-format/sdk.gen.ts @@ -1,10 +1,12 @@ // This file is auto-generated by @hey-api/openapi-ts +import * as z from 'zod/mini'; + import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; import { postFooResponseTransformer } from './transformers.gen'; import type { PostFooData, PostFooResponses } from './types.gen'; -import { zPostFooData, zPostFooResponse } from './zod.gen'; +import { zPostFooResponse } from './zod.gen'; export type Options = Options2 & { /** @@ -21,7 +23,11 @@ export type Options(options?: Options) => (options?.client ?? client).post({ - requestValidator: async (data) => await zPostFooData.parseAsync(data), + requestValidator: async (data) => await z.object({ + body: z.optional(z.never()), + path: z.optional(z.never()), + query: z.optional(z.never()) + }).parseAsync(data), responseTransformer: postFooResponseTransformer, responseValidator: async (data) => await zPostFooResponse.parseAsync(data), url: '/foo', diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/type-format/zod.gen.ts index 41a01d04a..482008970 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/mini/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.int() }); -export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * OK */ 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 d4b71b4c7..f323f23a1 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 @@ -1081,55 +1081,23 @@ export const zSimpleRequestBody = zModelWithString; export const zSimpleFormData = zModelWithString; -export const zExportData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zImportData = z.object({ - body: z.union([ - zModelWithReadOnlyAndWriteOnlyWritable, - zModelWithArrayReadOnlyAndWriteOnlyWritable - ]), - path: z.never().optional(), - query: z.never().optional() -}); +export const zImportBody = z.union([ + zModelWithReadOnlyAndWriteOnlyWritable, + zModelWithArrayReadOnlyAndWriteOnlyWritable +]); export const zImportResponse = z.union([ zModelFromZendesk, zModelWithReadOnlyAndWriteOnly ]); -export const zFooWowData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zApiVVersionODataControllerCountData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; -export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.string() - }), - query: z.never().optional() +export const zGetApiVbyApiVersionSimpleOperationPath = z.object({ + foo_param: z.string() }); /** @@ -1137,131 +1105,87 @@ export const zGetApiVbyApiVersionSimpleOperationData = z.object({ */ export const zGetApiVbyApiVersionSimpleOperationResponse = z.number(); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooHeaders = z.object({ + 'x-Foo-Bar': zModelWithString }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooPath = z.object({ + foo_param: z.string(), + BarParam: z.string() }); -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDescriptionsQuery = 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() }); -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeprecatedCallHeaders = z.object({ + parameter: zDeprecatedModel.nullable() }); -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * This is the parameter that goes into the body + */ +export const zCallWithParametersBody = z.record(z.unknown()).nullable(); -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string().nullable() }); -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersPath = z.object({ + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }); -export const zDeleteFooData3 = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.string(), - BarParam: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'x-Foo-Bar': zModelWithString - }) +export const zCallWithParametersQuery = z.object({ + foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), + foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, + cursor: z.string().nullable() }); -export const zCallWithDescriptionsData = z.object({ - 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() +/** + * This is the parameter that goes into the body + */ +export const zCallWithWeirdParameterNamesBody = zModelWithString.nullable(); + +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string().nullable() }); -export const zDeprecatedCallData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - parameter: zDeprecatedModel.nullable() - }) +export const zCallWithWeirdParameterNamesPath = z.object({ + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string().nullable() }); -export const zCallWithParametersData = z.object({ - body: z.record(z.unknown()).nullable(), - path: z.object({ - parameterPath: z.string().nullable(), - 'api-version': z.string().nullable() - }), - query: z.object({ - foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), - foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.string().nullable() - }), - headers: z.object({ - parameterHeader: z.string().nullable() - }) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.string().optional(), + 'parameter-query': z.string().nullable() }); -export const zCallWithWeirdParameterNamesData = z.object({ - 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.string().nullable() - }), - query: z.object({ - default: z.string().optional(), - 'parameter-query': z.string().nullable() - }), - headers: z.object({ - 'parameter.header': z.string().nullable() - }) +/** + * This is a required parameter + */ +export const zGetCallWithOptionalParamBody = zModelWithOneOfEnum; + +export const zGetCallWithOptionalParamQuery = z.object({ + page: z.number().optional() }); -export const zGetCallWithOptionalParamData = z.object({ - body: zModelWithOneOfEnum, - path: z.never().optional(), - query: z.object({ - page: z.number().optional() - }).optional() +/** + * This is an optional parameter + */ +export const zPostCallWithOptionalParamBody = z.object({ + offset: z.number().nullish() }); -export const zPostCallWithOptionalParamData = z.object({ - body: z.object({ - offset: z.number().nullish() - }).optional(), - path: z.never().optional(), - query: z.object({ - parameter: zPageable - }) +export const zPostCallWithOptionalParamQuery = z.object({ + parameter: zPageable }); export const zPostCallWithOptionalParamResponse = z.union([ @@ -1269,97 +1193,57 @@ export const zPostCallWithOptionalParamResponse = z.union([ z.void() ]); -export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: zSimpleRequestBody.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zPostApiVbyApiVersionFormDataData = z.object({ - body: zSimpleFormData.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zCallWithDefaultParametersData = z.object({ - 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' - ]).optional(), - parameterModel: zModelWithString.nullish() - }).optional() -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - 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(), - parameterModel: zModelWithString.optional() - }).optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionRequestBodyBody = zSimpleRequestBody; -export const zCallToTestOrderOfParamsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.string().nullish(), - parameterStringNullableWithDefault: z.string().nullish().default(null) - }) +export const zPostApiVbyApiVersionRequestBodyQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateNameData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionFormDataBody = zSimpleFormData; -export const zDuplicateName2Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zPostApiVbyApiVersionFormDataQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateName3Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultParametersQuery = 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' + ]).optional(), + parameterModel: zModelWithString.nullish() }); -export const zDuplicateName4Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultOptionalParametersQuery = 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(), + parameterModel: zModelWithString.optional() }); -export const zCallWithNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallToTestOrderOfParamsQuery = z.object({ + 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.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }); /** @@ -1367,61 +1251,25 @@ export const zCallWithNoContentResponseData = z.object({ */ export const zCallWithNoContentResponseResponse = z.void(); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.number(), z.void() ]); -export const zDummyAData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zDummyAResponse = z400; -export const zDummyBData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zDummyBResponse = z.void(); -export const zCallWithResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseResponse = zImport; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithDuplicateResponsesResponse = z.union([ zModelWithBoolean.and(zModelWithInteger), zModelWithString ]); -export const zCallWithResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.string().readonly().optional(), @@ -1432,36 +1280,30 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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 zCollectionFormatQuery = z.object({ + 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.never().optional(), - path: 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' }).optional() - }).optional(), - query: z.object({ - parameterNumber: z.number().default(123), - 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', - 'Error' - ]) - }) +export const zTypesPath = 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' }).optional() +}); + +export const zTypesQuery = z.object({ + parameterNumber: z.number().default(123), + 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', + 'Error' + ]) }); export const zTypesResponse = z.union([ @@ -1471,23 +1313,17 @@ export const zTypesResponse = z.union([ z.record(z.unknown()) ]); -export const zUploadFileData = z.object({ - body: z.string(), - path: z.object({ - 'api-version': z.string().nullable() - }), - query: z.never().optional() +export const zUploadFileBody = z.string(); + +export const zUploadFilePath = z.object({ + 'api-version': z.string().nullable() }); export const zUploadFileResponse = z.boolean(); -export const zFileResponseData = z.object({ - body: z.never().optional(), - path: z.object({ - id: z.string(), - 'api-version': z.string() - }), - query: z.never().optional() +export const zFileResponsePath = z.object({ + id: z.string(), + 'api-version': z.string() }); /** @@ -1495,19 +1331,15 @@ export const zFileResponseData = z.object({ */ export const zFileResponseResponse = z.string(); -export const zComplexTypesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterObject: z.object({ - first: z.object({ - second: z.object({ - third: z.string().optional() - }).optional() +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.object({ + second: z.object({ + third: z.string().optional() }).optional() - }), - parameterReference: zModelWithString - }) + }).optional() + }), + parameterReference: zModelWithString }); /** @@ -1515,12 +1347,6 @@ export const zComplexTypesData = z.object({ */ export const zComplexTypesResponse = z.array(zModelWithString); -export const zMultipartResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ @@ -1532,43 +1358,37 @@ export const zMultipartResponseResponse = z.object({ }).optional() }); -export const zMultipartRequestData = z.object({ - 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.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.array(zModelWithString).nullish(), - listOfStrings: z.array(z.string()).nullish(), - parameters: z.union([ - zModelWithString, - zModelWithEnum, - zModelWithArray, - zModelWithDictionary - ]), - 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.string().readonly().nullish() - }).readonly().optional() - }).optional(), - path: 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' }), - 'api-version': z.string() - }), - query: z.never().optional() +export const zMultipartRequestBody = z.object({ + content: z.string().optional(), + data: zModelWithString.nullish() +}); + +export const zComplexParamsBody = 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.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), + parameters: z.union([ + zModelWithString, + zModelWithEnum, + zModelWithArray, + zModelWithDictionary + ]), + 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.string().readonly().nullish() + }).readonly().optional() +}); + +export const zComplexParamsPath = 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' }), + 'api-version': z.string() }); /** @@ -1576,26 +1396,12 @@ export const zComplexParamsData = z.object({ */ export const zComplexParamsResponse = zModelWithString; -export const zCallWithResultFromHeaderData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zTestErrorCodeData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - status: z.number().int() - }) +export const zTestErrorCodeQuery = z.object({ + status: z.number().int() }); -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.number().int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.number().int() }); /** @@ -1603,8 +1409,4 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); -export const zPutWithFormUrlEncodedData = z.object({ - body: zArrayWithStrings, - path: z.never().optional(), - query: z.never().optional() -}); +export const zPutWithFormUrlEncodedBody = zArrayWithStrings; diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/type-format/sdk.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/type-format/sdk.gen.ts index aadc85c9f..2e3b86b27 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/type-format/sdk.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/type-format/sdk.gen.ts @@ -1,10 +1,12 @@ // This file is auto-generated by @hey-api/openapi-ts +import { z } from 'zod/v3'; + import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; import { postFooResponseTransformer } from './transformers.gen'; import type { PostFooData, PostFooResponses } from './types.gen'; -import { zPostFooData, zPostFooResponse } from './zod.gen'; +import { zPostFooResponse } from './zod.gen'; export type Options = Options2 & { /** @@ -21,7 +23,11 @@ export type Options(options?: Options) => (options?.client ?? client).post({ - requestValidator: async (data) => await zPostFooData.parseAsync(data), + requestValidator: async (data) => await z.object({ + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() + }).parseAsync(data), responseTransformer: postFooResponseTransformer, responseValidator: async (data) => await zPostFooResponse.parseAsync(data), url: '/foo', diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/type-format/zod.gen.ts index 262cf8307..01c7ccbc5 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.number().int() }); -export const zPostFooData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ 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 969175d39..2785152b8 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 @@ -1081,55 +1081,23 @@ export const zSimpleRequestBody = zModelWithString; export const zSimpleFormData = zModelWithString; -export const zExportData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zImportData = z.object({ - body: z.union([ - zModelWithReadOnlyAndWriteOnlyWritable, - zModelWithArrayReadOnlyAndWriteOnlyWritable - ]), - path: z.never().optional(), - query: z.never().optional() -}); +export const zImportBody = z.union([ + zModelWithReadOnlyAndWriteOnlyWritable, + zModelWithArrayReadOnlyAndWriteOnlyWritable +]); export const zImportResponse = z.union([ zModelFromZendesk, zModelWithReadOnlyAndWriteOnly ]); -export const zFooWowData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zApiVVersionODataControllerCountData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; -export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.string() - }), - query: z.never().optional() +export const zGetApiVbyApiVersionSimpleOperationPath = z.object({ + foo_param: z.string() }); /** @@ -1137,131 +1105,87 @@ export const zGetApiVbyApiVersionSimpleOperationData = z.object({ */ export const zGetApiVbyApiVersionSimpleOperationResponse = z.number(); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooHeaders = z.object({ + 'x-Foo-Bar': zModelWithString }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooPath = z.object({ + foo_param: z.string(), + BarParam: z.string() }); -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDescriptionsQuery = 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() }); -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeprecatedCallHeaders = z.object({ + parameter: zDeprecatedModel.nullable() }); -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * This is the parameter that goes into the body + */ +export const zCallWithParametersBody = z.record(z.string(), z.unknown()).nullable(); -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string().nullable() }); -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersPath = z.object({ + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }); -export const zDeleteFooData3 = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.string(), - BarParam: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'x-Foo-Bar': zModelWithString - }) +export const zCallWithParametersQuery = z.object({ + foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), + foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, + cursor: z.string().nullable() }); -export const zCallWithDescriptionsData = z.object({ - 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() +/** + * This is the parameter that goes into the body + */ +export const zCallWithWeirdParameterNamesBody = zModelWithString.nullable(); + +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string().nullable() }); -export const zDeprecatedCallData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - parameter: zDeprecatedModel.nullable() - }) +export const zCallWithWeirdParameterNamesPath = z.object({ + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string().nullable() }); -export const zCallWithParametersData = z.object({ - body: z.record(z.string(), z.unknown()).nullable(), - path: z.object({ - parameterPath: z.string().nullable(), - 'api-version': z.string().nullable() - }), - query: z.object({ - foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), - foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.string().nullable() - }), - headers: z.object({ - parameterHeader: z.string().nullable() - }) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.string().optional(), + 'parameter-query': z.string().nullable() }); -export const zCallWithWeirdParameterNamesData = z.object({ - 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.string().nullable() - }), - query: z.object({ - default: z.string().optional(), - 'parameter-query': z.string().nullable() - }), - headers: z.object({ - 'parameter.header': z.string().nullable() - }) +/** + * This is a required parameter + */ +export const zGetCallWithOptionalParamBody = zModelWithOneOfEnum; + +export const zGetCallWithOptionalParamQuery = z.object({ + page: z.number().optional() }); -export const zGetCallWithOptionalParamData = z.object({ - body: zModelWithOneOfEnum, - path: z.never().optional(), - query: z.object({ - page: z.number().optional() - }).optional() +/** + * This is an optional parameter + */ +export const zPostCallWithOptionalParamBody = z.object({ + offset: z.number().nullish() }); -export const zPostCallWithOptionalParamData = z.object({ - body: z.object({ - offset: z.number().nullish() - }).optional(), - path: z.never().optional(), - query: z.object({ - parameter: zPageable - }) +export const zPostCallWithOptionalParamQuery = z.object({ + parameter: zPageable }); export const zPostCallWithOptionalParamResponse = z.union([ @@ -1269,97 +1193,57 @@ export const zPostCallWithOptionalParamResponse = z.union([ z.void() ]); -export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: zSimpleRequestBody.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zPostApiVbyApiVersionFormDataData = z.object({ - body: zSimpleFormData.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zCallWithDefaultParametersData = z.object({ - 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' - ]).optional(), - parameterModel: zModelWithString.nullish() - }).optional() -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - 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(), - parameterModel: zModelWithString.optional() - }).optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionRequestBodyBody = zSimpleRequestBody; -export const zCallToTestOrderOfParamsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.string().nullish(), - parameterStringNullableWithDefault: z.string().nullish().default(null) - }) +export const zPostApiVbyApiVersionRequestBodyQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateNameData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionFormDataBody = zSimpleFormData; -export const zDuplicateName2Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zPostApiVbyApiVersionFormDataQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateName3Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultParametersQuery = 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' + ]).optional(), + parameterModel: zModelWithString.nullish() }); -export const zDuplicateName4Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultOptionalParametersQuery = 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(), + parameterModel: zModelWithString.optional() }); -export const zCallWithNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallToTestOrderOfParamsQuery = z.object({ + 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.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }); /** @@ -1367,61 +1251,25 @@ export const zCallWithNoContentResponseData = z.object({ */ export const zCallWithNoContentResponseResponse = z.void(); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.number(), z.void() ]); -export const zDummyAData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zDummyAResponse = z400; -export const zDummyBData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zDummyBResponse = z.void(); -export const zCallWithResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseResponse = zImport; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithDuplicateResponsesResponse = z.union([ zModelWithBoolean.and(zModelWithInteger), zModelWithString ]); -export const zCallWithResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.string().readonly().optional(), @@ -1432,36 +1280,30 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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 zCollectionFormatQuery = z.object({ + 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.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().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', - 'Error' - ]) - }) +export const zTypesPath = 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() +}); + +export const zTypesQuery = z.object({ + parameterNumber: z.number().default(123), + 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', + 'Error' + ]) }); export const zTypesResponse = z.union([ @@ -1471,23 +1313,17 @@ export const zTypesResponse = z.union([ z.record(z.string(), z.unknown()) ]); -export const zUploadFileData = z.object({ - body: z.string(), - path: z.object({ - 'api-version': z.string().nullable() - }), - query: z.never().optional() +export const zUploadFileBody = z.string(); + +export const zUploadFilePath = z.object({ + 'api-version': z.string().nullable() }); export const zUploadFileResponse = z.boolean(); -export const zFileResponseData = z.object({ - body: z.never().optional(), - path: z.object({ - id: z.string(), - 'api-version': z.string() - }), - query: z.never().optional() +export const zFileResponsePath = z.object({ + id: z.string(), + 'api-version': z.string() }); /** @@ -1495,19 +1331,15 @@ export const zFileResponseData = z.object({ */ export const zFileResponseResponse = z.string(); -export const zComplexTypesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterObject: z.object({ - first: z.object({ - second: z.object({ - third: z.string().optional() - }).optional() +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.object({ + second: z.object({ + third: z.string().optional() }).optional() - }), - parameterReference: zModelWithString - }) + }).optional() + }), + parameterReference: zModelWithString }); /** @@ -1515,12 +1347,6 @@ export const zComplexTypesData = z.object({ */ export const zComplexTypesResponse = z.array(zModelWithString); -export const zMultipartResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ @@ -1532,43 +1358,37 @@ export const zMultipartResponseResponse = z.object({ }).optional() }); -export const zMultipartRequestData = z.object({ - 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.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.array(zModelWithString).nullish(), - listOfStrings: z.array(z.string()).nullish(), - parameters: z.union([ - zModelWithString, - zModelWithEnum, - zModelWithArray, - zModelWithDictionary - ]), - 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.never().optional() +export const zMultipartRequestBody = z.object({ + content: z.string().optional(), + data: zModelWithString.nullish() +}); + +export const zComplexParamsBody = 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.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), + parameters: z.union([ + zModelWithString, + zModelWithEnum, + zModelWithArray, + zModelWithDictionary + ]), + 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() +}); + +export const zComplexParamsPath = 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() }); /** @@ -1576,26 +1396,12 @@ export const zComplexParamsData = z.object({ */ export const zComplexParamsResponse = zModelWithString; -export const zCallWithResultFromHeaderData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zTestErrorCodeData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - status: z.int() - }) +export const zTestErrorCodeQuery = z.object({ + status: z.int() }); -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.int() }); /** @@ -1603,8 +1409,4 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); -export const zPutWithFormUrlEncodedData = z.object({ - body: zArrayWithStrings, - path: z.never().optional(), - query: z.never().optional() -}); +export const zPutWithFormUrlEncodedBody = zArrayWithStrings; diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/type-format/sdk.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/type-format/sdk.gen.ts index aadc85c9f..f1b1a1e06 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/type-format/sdk.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/type-format/sdk.gen.ts @@ -1,10 +1,12 @@ // This file is auto-generated by @hey-api/openapi-ts +import * as z from 'zod'; + import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; import { postFooResponseTransformer } from './transformers.gen'; import type { PostFooData, PostFooResponses } from './types.gen'; -import { zPostFooData, zPostFooResponse } from './zod.gen'; +import { zPostFooResponse } from './zod.gen'; export type Options = Options2 & { /** @@ -21,7 +23,11 @@ export type Options(options?: Options) => (options?.client ?? client).post({ - requestValidator: async (data) => await zPostFooData.parseAsync(data), + requestValidator: async (data) => await z.object({ + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() + }).parseAsync(data), responseTransformer: postFooResponseTransformer, responseValidator: async (data) => await zPostFooResponse.parseAsync(data), url: '/foo', diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/type-format/zod.gen.ts index bb1956f79..6173cb820 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v4/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.int() }); -export const zPostFooData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ 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 634333934..be6c7527b 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 @@ -1096,58 +1096,26 @@ 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()) -}); - -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zImportData = z.object({ - body: z.union([ - zModelWithReadOnlyAndWriteOnlyWritable, - zModelWithArrayReadOnlyAndWriteOnlyWritable - ]), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +export const zImportBody = z.union([ + zModelWithReadOnlyAndWriteOnlyWritable, + zModelWithArrayReadOnlyAndWriteOnlyWritable +]); export const zImportResponse = z.union([ zModelFromZendesk, zModelWithReadOnlyAndWriteOnly ]); -export const zFooWowData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zApiVVersionODataControllerCountData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * Success */ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; -export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.optional(z.never()), - path: z.object({ - foo_param: z.union([ - z.string(), - z.uuid() - ]) - }), - query: z.optional(z.never()) +export const zGetApiVbyApiVersionSimpleOperationPath = z.object({ + foo_param: z.union([ + z.string(), + z.uuid() + ]) }); /** @@ -1155,131 +1123,87 @@ 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()) +export const zDeleteFooHeaders = z.object({ + 'x-Foo-Bar': zModelWithString }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zDeleteFooPath = z.object({ + foo_param: z.string(), + BarParam: z.string() }); -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDescriptionsQuery = 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()) }); -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zDeprecatedCallHeaders = z.object({ + parameter: z.nullable(zDeprecatedModel) }); -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +/** + * This is the parameter that goes into the body + */ +export const zCallWithParametersBody = z.nullable(z.record(z.string(), z.unknown())); -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.nullable(z.string()) }); -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithParametersPath = z.object({ + parameterPath: z.nullable(z.string()), + 'api-version': z.nullable(z.string()) }); -export const zDeleteFooData3 = z.object({ - body: z.optional(z.never()), - path: z.object({ - foo_param: z.string(), - BarParam: z.string() - }), - query: z.optional(z.never()), - headers: z.object({ - 'x-Foo-Bar': zModelWithString - }) +export const zCallWithParametersQuery = z.object({ + foo_ref_enum: z.optional(zModelWithNestedArrayEnumsDataFoo), + foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, + cursor: z.nullable(z.string()) }); -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()) - })) +/** + * This is the parameter that goes into the body + */ +export const zCallWithWeirdParameterNamesBody = z.nullable(zModelWithString); + +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.nullable(z.string()) }); -export const zDeprecatedCallData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()), - headers: z.object({ - parameter: z.nullable(zDeprecatedModel) - }) +export const zCallWithWeirdParameterNamesPath = 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.nullable(z.string()) }); -export const zCallWithParametersData = z.object({ - body: z.nullable(z.record(z.string(), z.unknown())), - path: z.object({ - 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.nullable(z.string()) - }), - headers: z.object({ - parameterHeader: z.nullable(z.string()) - }) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.optional(z.string()), + 'parameter-query': z.nullable(z.string()) }); -export const zCallWithWeirdParameterNamesData = z.object({ - 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.nullable(z.string()) - }), - query: z.object({ - default: z.optional(z.string()), - 'parameter-query': z.nullable(z.string()) - }), - headers: z.object({ - 'parameter.header': z.nullable(z.string()) - }) +/** + * This is a required parameter + */ +export const zGetCallWithOptionalParamBody = zModelWithOneOfEnum; + +export const zGetCallWithOptionalParamQuery = z.object({ + page: z.optional(z.number()) }); -export const zGetCallWithOptionalParamData = z.object({ - body: zModelWithOneOfEnum, - path: z.optional(z.never()), - query: z.optional(z.object({ - page: z.optional(z.number()) - })) +/** + * This is an optional parameter + */ +export const zPostCallWithOptionalParamBody = z.object({ + offset: z.nullish(z.number()) }); -export const zPostCallWithOptionalParamData = z.object({ - body: z.optional(z.object({ - offset: z.nullish(z.number()) - })), - path: z.optional(z.never()), - query: z.object({ - parameter: zPageable - }) +export const zPostCallWithOptionalParamQuery = z.object({ + parameter: zPageable }); export const zPostCallWithOptionalParamResponse = z.union([ @@ -1287,97 +1211,57 @@ export const zPostCallWithOptionalParamResponse = z.union([ z.void() ]); -export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: z.optional(zSimpleRequestBody), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) -}); - -export const zPostApiVbyApiVersionFormDataData = z.object({ - body: z.optional(zSimpleFormData), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameter: z.optional(z.string()) - })) -}); - -export const zCallWithDefaultParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - 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.nullish(zModelWithString) - })) -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.object({ - parameterString: z._default(z.optional(z.string()), 'Hello World!'), - parameterNumber: z._default(z.optional(z.number()), 123), - parameterBoolean: z._default(z.optional(z.boolean()), true), - parameterEnum: z.optional(z.enum([ - 'Success', - 'Warning', - 'Error' - ])), - parameterModel: z._default(z.optional(zModelWithString), { prop: 'Hello World!' }) - })) -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionRequestBodyBody = zSimpleRequestBody; -export const zCallToTestOrderOfParamsData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - parameterOptionalStringWithDefault: z._default(z.optional(z.string()), 'Hello World!'), - parameterOptionalStringWithEmptyDefault: z._default(z.optional(z.string()), ''), - parameterOptionalStringWithNoDefault: z.optional(z.string()), - parameterStringWithDefault: z._default(z.string(), 'Hello World!'), - parameterStringWithEmptyDefault: z._default(z.string(), ''), - parameterStringWithNoDefault: z.string(), - parameterStringNullableWithNoDefault: z.nullish(z.string()), - parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) - }) +export const zPostApiVbyApiVersionRequestBodyQuery = z.object({ + parameter: z.optional(z.string()) }); -export const zDuplicateNameData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionFormDataBody = zSimpleFormData; -export const zDuplicateName2Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zPostApiVbyApiVersionFormDataQuery = z.object({ + parameter: z.optional(z.string()) }); -export const zDuplicateName3Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDefaultParametersQuery = z.object({ + 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.nullish(zModelWithString) }); -export const zDuplicateName4Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallWithDefaultOptionalParametersQuery = z.object({ + parameterString: z._default(z.optional(z.string()), 'Hello World!'), + parameterNumber: z._default(z.optional(z.number()), 123), + parameterBoolean: z._default(z.optional(z.boolean()), true), + parameterEnum: z.optional(z.enum([ + 'Success', + 'Warning', + 'Error' + ])), + parameterModel: z._default(z.optional(zModelWithString), { prop: 'Hello World!' }) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zCallToTestOrderOfParamsQuery = z.object({ + parameterOptionalStringWithDefault: z._default(z.optional(z.string()), 'Hello World!'), + parameterOptionalStringWithEmptyDefault: z._default(z.optional(z.string()), ''), + parameterOptionalStringWithNoDefault: z.optional(z.string()), + parameterStringWithDefault: z._default(z.string(), 'Hello World!'), + parameterStringWithEmptyDefault: z._default(z.string(), ''), + parameterStringWithNoDefault: z.string(), + parameterStringNullableWithNoDefault: z.nullish(z.string()), + parameterStringNullableWithDefault: z._default(z.nullish(z.string()), null) }); /** @@ -1385,61 +1269,25 @@ 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()) -}); - export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.number(), z.void() ]); -export const zDummyAData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zDummyAResponse = z400; -export const zDummyBData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * Success */ 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()) -}); - export const zCallWithResponseResponse = zImport; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zCallWithDuplicateResponsesResponse = z.union([ z.intersection(zModelWithBoolean, zModelWithInteger), zModelWithString ]); -export const zCallWithResponsesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.optional(z.readonly(z.string())), @@ -1450,36 +1298,30 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - 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())) - }) -}); - -export const zTypesData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.object({ - id: z.optional(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' }))) - })), - query: z.object({ - parameterNumber: z._default(z.number(), 123), - 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') - ])) - }) +export const zCollectionFormatQuery = z.object({ + 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())) +}); + +export const zTypesPath = z.object({ + id: z.optional(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' }))) +}); + +export const zTypesQuery = z.object({ + parameterNumber: z._default(z.number(), 123), + 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') + ])) }); export const zTypesResponse = z.union([ @@ -1489,23 +1331,17 @@ export const zTypesResponse = z.union([ z.record(z.string(), z.unknown()) ]); -export const zUploadFileData = z.object({ - body: z.string(), - path: z.object({ - 'api-version': z.nullable(z.string()) - }), - query: z.optional(z.never()) +export const zUploadFileBody = z.string(); + +export const zUploadFilePath = z.object({ + 'api-version': z.nullable(z.string()) }); export const zUploadFileResponse = z.boolean(); -export const zFileResponseData = z.object({ - body: z.optional(z.never()), - path: z.object({ - id: z.string(), - 'api-version': z.string() - }), - query: z.optional(z.never()) +export const zFileResponsePath = z.object({ + id: z.string(), + 'api-version': z.string() }); /** @@ -1513,19 +1349,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()), - query: z.object({ - parameterObject: z.object({ - first: z.optional(z.object({ - second: z.optional(z.object({ - third: z.optional(z.string()) - })) +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.optional(z.object({ + second: z.optional(z.object({ + third: z.optional(z.string()) })) - }), - parameterReference: zModelWithString - }) + })) + }), + parameterReference: zModelWithString }); /** @@ -1533,12 +1365,6 @@ 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()) -}); - /** * OK */ @@ -1550,43 +1376,37 @@ export const zMultipartResponseResponse = z.object({ })) }); -export const zMultipartRequestData = z.object({ - body: z.optional(z.object({ - content: z.optional(z.string()), - data: z.nullish(zModelWithString) - })), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - -export const zComplexParamsData = z.object({ - body: z.optional(z.object({ - 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.nullish(z.array(zModelWithString)), - listOfStrings: z.nullish(z.array(z.string())), - parameters: z.union([ - zModelWithString, - zModelWithEnum, - zModelWithArray, - zModelWithDictionary - ]), - 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.nullish(z.readonly(z.string())) - }))) - })), - path: z.object({ - id: 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' })), - 'api-version': z.string() - }), - query: z.optional(z.never()) +export const zMultipartRequestBody = z.object({ + content: z.optional(z.string()), + data: z.nullish(zModelWithString) +}); + +export const zComplexParamsBody = z.object({ + 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.nullish(z.array(zModelWithString)), + listOfStrings: z.nullish(z.array(z.string())), + parameters: z.union([ + zModelWithString, + zModelWithEnum, + zModelWithArray, + zModelWithDictionary + ]), + 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.nullish(z.readonly(z.string())) + }))) +}); + +export const zComplexParamsPath = z.object({ + id: 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' })), + 'api-version': z.string() }); /** @@ -1594,26 +1414,12 @@ 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()) +export const zTestErrorCodeQuery = z.object({ + status: z.int() }); -export const zTestErrorCodeData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - status: z.int() - }) -}); - -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.int() }); /** @@ -1621,8 +1427,4 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); -export const zPutWithFormUrlEncodedData = z.object({ - body: zArrayWithStrings, - path: z.optional(z.never()), - query: z.optional(z.never()) -}); +export const zPutWithFormUrlEncodedBody = zArrayWithStrings; diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/string-with-guid-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/string-with-guid-format/zod.gen.ts index ae8a5eb80..497557a67 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/string-with-guid-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/string-with-guid-format/zod.gen.ts @@ -2,10 +2,6 @@ import * as z from 'zod/mini'; -export const zGetFooData = z.object({ - body: z.optional(z.never()), - path: z.object({ - guidId: z.guid() - }), - query: z.optional(z.never()) +export const zGetFooPath = z.object({ + guidId: z.guid() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/type-format/sdk.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/type-format/sdk.gen.ts index aadc85c9f..d1796559d 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/type-format/sdk.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/type-format/sdk.gen.ts @@ -1,10 +1,12 @@ // This file is auto-generated by @hey-api/openapi-ts +import * as z from 'zod/mini'; + import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; import { postFooResponseTransformer } from './transformers.gen'; import type { PostFooData, PostFooResponses } from './types.gen'; -import { zPostFooData, zPostFooResponse } from './zod.gen'; +import { zPostFooResponse } from './zod.gen'; export type Options = Options2 & { /** @@ -21,7 +23,11 @@ export type Options(options?: Options) => (options?.client ?? client).post({ - requestValidator: async (data) => await zPostFooData.parseAsync(data), + requestValidator: async (data) => await z.object({ + body: z.optional(z.never()), + path: z.optional(z.never()), + query: z.optional(z.never()) + }).parseAsync(data), responseTransformer: postFooResponseTransformer, responseValidator: async (data) => await zPostFooResponse.parseAsync(data), url: '/foo', diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/type-format/zod.gen.ts index 41a01d04a..482008970 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.int() }); -export const zPostFooData = z.object({ - body: z.optional(z.never()), - path: z.optional(z.never()), - query: z.optional(z.never()) -}); - /** * OK */ 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 47eb9503a..f4c05f3e4 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: z.optional(zBar) }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.optional(z.string()) - }), - 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 })) - })) +export const zPatchFooBody = z.object({ + foo: z.optional(z.string()) }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zPatchFooQuery = 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 })) }); + +export const zPostFooBody = zFoo3; diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-metadata-fn/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-metadata-fn/zod.gen.ts index 9f85a8a0d..10c1cf9c8 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-metadata-fn/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/mini/validators-metadata-fn/zod.gen.ts @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: z.optional(zBar) }).register(z.globalRegistry, { custom: 'value', title: 'object' }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.optional(z.string().register(z.globalRegistry, { custom: 'value', title: 'string' })) - }).register(z.globalRegistry, { custom: 'value', title: 'object' }), - path: z.optional(z.never().register(z.globalRegistry, { custom: 'value', title: 'never' })), - query: z.optional(z.object({ - foo: z.optional(z.string().register(z.globalRegistry, { custom: 'value', title: 'This is Foo parameter.' })), - bar: z.optional(zBar), - baz: z.optional(z.object({ - baz: z.optional(z.string().register(z.globalRegistry, { custom: 'value', title: 'string' })) - }).register(z.globalRegistry, { custom: 'value', title: 'object' })), - qux: z.optional(z.iso.date().register(z.globalRegistry, { custom: 'value', title: 'string' })), - quux: z.optional(z.iso.datetime().register(z.globalRegistry, { custom: 'value', title: 'string' })) - }).register(z.globalRegistry, { custom: 'value', title: 'object' })) +export const zPatchFooBody = z.object({ + foo: z.optional(z.string().register(z.globalRegistry, { custom: 'value', title: 'string' })) }).register(z.globalRegistry, { custom: 'value', title: 'object' }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.optional(z.never().register(z.globalRegistry, { custom: 'value', title: 'never' })), - query: z.optional(z.never().register(z.globalRegistry, { custom: 'value', title: 'never' })) +export const zPatchFooQuery = z.object({ + foo: z.optional(z.string().register(z.globalRegistry, { custom: 'value', title: 'This is Foo parameter.' })), + bar: z.optional(zBar), + baz: z.optional(z.object({ + baz: z.optional(z.string().register(z.globalRegistry, { custom: 'value', title: 'string' })) + }).register(z.globalRegistry, { custom: 'value', title: 'object' })), + qux: z.optional(z.iso.date().register(z.globalRegistry, { custom: 'value', title: 'string' })), + quux: z.optional(z.iso.datetime().register(z.globalRegistry, { custom: 'value', title: 'string' })) }).register(z.globalRegistry, { custom: 'value', title: 'object' }); + +export const zPostFooBody = zFoo3; 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 004b5e06d..74056350b 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 @@ -44,26 +44,20 @@ export const zFoo3 = z.object({ foo: z.optional(zBar) }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.optional(z.string()) - }), - path: z.optional(z.never()), - query: z.optional(z.object({ - foo: z.optional(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()) - })) +export const zPatchFooBody = z.object({ + foo: z.optional(z.string()) }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zPatchFooQuery = z.object({ + foo: z.optional(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()) }); + +export const zPostFooBody = zFoo3; 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 e69e527ef..436869e13 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 @@ -46,28 +46,24 @@ export const zFoo3 = z.object({ export type FooZodType3 = z.infer; -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.optional(z.string()) - }), - 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()) - })) +export const zPatchFooBody = z.object({ + foo: z.optional(z.string()) }); -export type PatchFooDataZodType = z.infer; +export type PatchFooBodyZodType = z.infer; -export const zPostFooData = z.object({ - body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zPatchFooQuery = 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()) }); -export type PostFooDataZodType = z.infer; +export type PatchFooQueryZodType = z.infer; + +export const zPostFooBody = zFoo3; + +export type PostFooBodyZodType = 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 3b365dc73..74e1108e6 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: z.optional(zBar) }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.optional(z.string()) - }), - 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()) - })) +export const zPatchFooBody = z.object({ + foo: z.optional(z.string()) }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.optional(z.never()), - query: z.optional(z.never()) +export const zPatchFooQuery = 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()) }); + +export const zPostFooBody = zFoo3; 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 374d4eedc..c4e6824cf 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 @@ -1096,58 +1096,26 @@ export const zSimpleRequestBody = zModelWithString; */ export const zSimpleFormData = zModelWithString; -export const zExportData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zImportData = z.object({ - body: z.union([ - zModelWithReadOnlyAndWriteOnlyWritable, - zModelWithArrayReadOnlyAndWriteOnlyWritable - ]), - path: z.never().optional(), - query: z.never().optional() -}); +export const zImportBody = z.union([ + zModelWithReadOnlyAndWriteOnlyWritable, + zModelWithArrayReadOnlyAndWriteOnlyWritable +]); export const zImportResponse = z.union([ zModelFromZendesk, zModelWithReadOnlyAndWriteOnly ]); -export const zFooWowData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zApiVVersionODataControllerCountData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; -export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.union([ - z.string(), - z.string().uuid() - ]) - }), - query: z.never().optional() +export const zGetApiVbyApiVersionSimpleOperationPath = z.object({ + foo_param: z.union([ + z.string(), + z.string().uuid() + ]) }); /** @@ -1155,131 +1123,87 @@ export const zGetApiVbyApiVersionSimpleOperationData = z.object({ */ export const zGetApiVbyApiVersionSimpleOperationResponse = z.number(); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooHeaders = z.object({ + 'x-Foo-Bar': zModelWithString }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooPath = z.object({ + foo_param: z.string(), + BarParam: z.string() }); -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDescriptionsQuery = 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() }); -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeprecatedCallHeaders = z.object({ + parameter: zDeprecatedModel.nullable() }); -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * This is the parameter that goes into the body + */ +export const zCallWithParametersBody = z.record(z.unknown()).nullable(); -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string().nullable() }); -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersPath = z.object({ + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }); -export const zDeleteFooData3 = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.string(), - BarParam: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'x-Foo-Bar': zModelWithString - }) +export const zCallWithParametersQuery = z.object({ + foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), + foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, + cursor: z.string().nullable() }); -export const zCallWithDescriptionsData = z.object({ - 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() +/** + * This is the parameter that goes into the body + */ +export const zCallWithWeirdParameterNamesBody = zModelWithString.nullable(); + +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string().nullable() }); -export const zDeprecatedCallData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - parameter: zDeprecatedModel.nullable() - }) +export const zCallWithWeirdParameterNamesPath = z.object({ + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string().nullable() }); -export const zCallWithParametersData = z.object({ - body: z.record(z.unknown()).nullable(), - path: z.object({ - parameterPath: z.string().nullable(), - 'api-version': z.string().nullable() - }), - query: z.object({ - foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), - foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.string().nullable() - }), - headers: z.object({ - parameterHeader: z.string().nullable() - }) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.string().optional(), + 'parameter-query': z.string().nullable() }); -export const zCallWithWeirdParameterNamesData = z.object({ - 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.string().nullable() - }), - query: z.object({ - default: z.string().optional(), - 'parameter-query': z.string().nullable() - }), - headers: z.object({ - 'parameter.header': z.string().nullable() - }) +/** + * This is a required parameter + */ +export const zGetCallWithOptionalParamBody = zModelWithOneOfEnum; + +export const zGetCallWithOptionalParamQuery = z.object({ + page: z.number().optional() }); -export const zGetCallWithOptionalParamData = z.object({ - body: zModelWithOneOfEnum, - path: z.never().optional(), - query: z.object({ - page: z.number().optional() - }).optional() +/** + * This is an optional parameter + */ +export const zPostCallWithOptionalParamBody = z.object({ + offset: z.number().nullish() }); -export const zPostCallWithOptionalParamData = z.object({ - body: z.object({ - offset: z.number().nullish() - }).optional(), - path: z.never().optional(), - query: z.object({ - parameter: zPageable - }) +export const zPostCallWithOptionalParamQuery = z.object({ + parameter: zPageable }); export const zPostCallWithOptionalParamResponse = z.union([ @@ -1287,97 +1211,57 @@ export const zPostCallWithOptionalParamResponse = z.union([ z.void() ]); -export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: zSimpleRequestBody.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zPostApiVbyApiVersionFormDataData = z.object({ - body: zSimpleFormData.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zCallWithDefaultParametersData = z.object({ - 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' - ]).optional(), - parameterModel: zModelWithString.nullish() - }).optional() -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - 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(), - parameterModel: zModelWithString.optional().default({ prop: 'Hello World!' }) - }).optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionRequestBodyBody = zSimpleRequestBody; -export const zCallToTestOrderOfParamsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.string().nullish(), - parameterStringNullableWithDefault: z.string().nullish().default(null) - }) +export const zPostApiVbyApiVersionRequestBodyQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateNameData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionFormDataBody = zSimpleFormData; -export const zDuplicateName2Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zPostApiVbyApiVersionFormDataQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateName3Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultParametersQuery = 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' + ]).optional(), + parameterModel: zModelWithString.nullish() }); -export const zDuplicateName4Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultOptionalParametersQuery = 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(), + parameterModel: zModelWithString.optional().default({ prop: 'Hello World!' }) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallToTestOrderOfParamsQuery = z.object({ + 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.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }); /** @@ -1385,61 +1269,25 @@ export const zCallWithNoContentResponseData = z.object({ */ export const zCallWithNoContentResponseResponse = z.void(); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.number(), z.void() ]); -export const zDummyAData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zDummyAResponse = z400; -export const zDummyBData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zDummyBResponse = z.void(); -export const zCallWithResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseResponse = zImport; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithDuplicateResponsesResponse = z.union([ zModelWithBoolean.and(zModelWithInteger), zModelWithString ]); -export const zCallWithResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.string().readonly().optional(), @@ -1450,36 +1298,30 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.never().optional(), - path: 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' }).optional() - }).optional(), - query: z.object({ - parameterNumber: z.number().default(123), - 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') - ]).nullable() - }) +export const zCollectionFormatQuery = z.object({ + 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 zTypesPath = 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' }).optional() +}); + +export const zTypesQuery = z.object({ + parameterNumber: z.number().default(123), + 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') + ]).nullable() }); export const zTypesResponse = z.union([ @@ -1489,23 +1331,17 @@ export const zTypesResponse = z.union([ z.record(z.unknown()) ]); -export const zUploadFileData = z.object({ - body: z.string(), - path: z.object({ - 'api-version': z.string().nullable() - }), - query: z.never().optional() +export const zUploadFileBody = z.string(); + +export const zUploadFilePath = z.object({ + 'api-version': z.string().nullable() }); export const zUploadFileResponse = z.boolean(); -export const zFileResponseData = z.object({ - body: z.never().optional(), - path: z.object({ - id: z.string(), - 'api-version': z.string() - }), - query: z.never().optional() +export const zFileResponsePath = z.object({ + id: z.string(), + 'api-version': z.string() }); /** @@ -1513,19 +1349,15 @@ export const zFileResponseData = z.object({ */ export const zFileResponseResponse = z.string(); -export const zComplexTypesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterObject: z.object({ - first: z.object({ - second: z.object({ - third: z.string().optional() - }).optional() +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.object({ + second: z.object({ + third: z.string().optional() }).optional() - }), - parameterReference: zModelWithString - }) + }).optional() + }), + parameterReference: zModelWithString }); /** @@ -1533,12 +1365,6 @@ export const zComplexTypesData = z.object({ */ export const zComplexTypesResponse = z.array(zModelWithString); -export const zMultipartResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ @@ -1550,43 +1376,37 @@ export const zMultipartResponseResponse = z.object({ }).optional() }); -export const zMultipartRequestData = z.object({ - 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.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.array(zModelWithString).nullish(), - listOfStrings: z.array(z.string()).nullish(), - parameters: z.union([ - zModelWithString, - zModelWithEnum, - zModelWithArray, - zModelWithDictionary - ]), - 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.string().readonly().nullish() - }).readonly().optional() - }).optional(), - path: 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' }), - 'api-version': z.string() - }), - query: z.never().optional() +export const zMultipartRequestBody = z.object({ + content: z.string().optional(), + data: zModelWithString.nullish() +}); + +export const zComplexParamsBody = 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.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), + parameters: z.union([ + zModelWithString, + zModelWithEnum, + zModelWithArray, + zModelWithDictionary + ]), + 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.string().readonly().nullish() + }).readonly().optional() +}); + +export const zComplexParamsPath = 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' }), + 'api-version': z.string() }); /** @@ -1594,26 +1414,12 @@ export const zComplexParamsData = z.object({ */ export const zComplexParamsResponse = zModelWithString; -export const zCallWithResultFromHeaderData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zTestErrorCodeData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - status: z.number().int() - }) +export const zTestErrorCodeQuery = z.object({ + status: z.number().int() }); -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.number().int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.number().int() }); /** @@ -1621,8 +1427,4 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); -export const zPutWithFormUrlEncodedData = z.object({ - body: zArrayWithStrings, - path: z.never().optional(), - query: z.never().optional() -}); +export const zPutWithFormUrlEncodedBody = zArrayWithStrings; diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/string-with-guid-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/string-with-guid-format/zod.gen.ts index 14d6b526f..fa8f6cc67 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/string-with-guid-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/string-with-guid-format/zod.gen.ts @@ -2,10 +2,6 @@ import { z } from 'zod/v3'; -export const zGetFooData = z.object({ - body: z.never().optional(), - path: z.object({ - guidId: z.string() - }), - query: z.never().optional() +export const zGetFooPath = z.object({ + guidId: z.string() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/type-format/sdk.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/type-format/sdk.gen.ts index aadc85c9f..2e3b86b27 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/type-format/sdk.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/type-format/sdk.gen.ts @@ -1,10 +1,12 @@ // This file is auto-generated by @hey-api/openapi-ts +import { z } from 'zod/v3'; + import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; import { postFooResponseTransformer } from './transformers.gen'; import type { PostFooData, PostFooResponses } from './types.gen'; -import { zPostFooData, zPostFooResponse } from './zod.gen'; +import { zPostFooResponse } from './zod.gen'; export type Options = Options2 & { /** @@ -21,7 +23,11 @@ export type Options(options?: Options) => (options?.client ?? client).post({ - requestValidator: async (data) => await zPostFooData.parseAsync(data), + requestValidator: async (data) => await z.object({ + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() + }).parseAsync(data), responseTransformer: postFooResponseTransformer, responseValidator: async (data) => await zPostFooResponse.parseAsync(data), url: '/foo', diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/type-format/zod.gen.ts index 262cf8307..01c7ccbc5 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.number().int() }); -export const zPostFooData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ 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 752d86c56..cfe41b5d1 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: zBar.optional() }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - path: z.never().optional(), - query: z.object({ - foo: z.string().optional(), - bar: zBar.optional(), - baz: z.object({ - baz: z.string().optional() - }).optional(), - qux: z.string().date().optional(), - quux: z.string().datetime({ offset: true }).optional() - }).optional() +export const zPatchFooBody = z.object({ + foo: z.string().optional() }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = z.object({ + foo: z.string().optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.string().date().optional(), + quux: z.string().datetime({ offset: true }).optional() }); + +export const zPostFooBody = zFoo3; diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-metadata-fn/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-metadata-fn/zod.gen.ts index 4c243e93f..ec54e3466 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-metadata-fn/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/validators-metadata-fn/zod.gen.ts @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: zBar.optional() }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - path: z.never().optional(), - query: z.object({ - foo: z.string().describe('This is Foo parameter.').optional(), - bar: zBar.optional(), - baz: z.object({ - baz: z.string().optional() - }).optional(), - qux: z.string().date().optional(), - quux: z.string().datetime().optional() - }).optional() +export const zPatchFooBody = z.object({ + foo: z.string().optional() }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = z.object({ + foo: z.string().describe('This is Foo parameter.').optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.string().date().optional(), + quux: z.string().datetime().optional() }); + +export const zPostFooBody = zFoo3; 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 4c243e93f..ec54e3466 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: zBar.optional() }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - path: z.never().optional(), - query: z.object({ - foo: z.string().describe('This is Foo parameter.').optional(), - bar: zBar.optional(), - baz: z.object({ - baz: z.string().optional() - }).optional(), - qux: z.string().date().optional(), - quux: z.string().datetime().optional() - }).optional() +export const zPatchFooBody = z.object({ + foo: z.string().optional() }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = z.object({ + foo: z.string().describe('This is Foo parameter.').optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.string().date().optional(), + quux: z.string().datetime().optional() }); + +export const zPostFooBody = zFoo3; 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 e2734ee19..0699f4d2c 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 @@ -46,28 +46,24 @@ export const zFoo3 = z.object({ export type FooZodType3 = z.infer; -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - path: z.never().optional(), - query: z.object({ - foo: z.string().optional(), - bar: zBar.optional(), - baz: z.object({ - baz: z.string().optional() - }).optional(), - qux: z.string().date().optional(), - quux: z.string().datetime().optional() - }).optional() +export const zPatchFooBody = z.object({ + foo: z.string().optional() }); -export type PatchFooDataZodType = z.infer; +export type PatchFooBodyZodType = z.infer; -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = z.object({ + foo: z.string().optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.string().date().optional(), + quux: z.string().datetime().optional() }); -export type PostFooDataZodType = z.infer; +export type PatchFooQueryZodType = z.infer; + +export const zPostFooBody = zFoo3; + +export type PostFooBodyZodType = 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 89bcb622f..fb0bb585c 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: zBar.optional() }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - path: z.never().optional(), - query: z.object({ - foo: z.string().optional(), - bar: zBar.optional(), - baz: z.object({ - baz: z.string().optional() - }).optional(), - qux: z.string().date().optional(), - quux: z.string().datetime().optional() - }).optional() +export const zPatchFooBody = z.object({ + foo: z.string().optional() }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = z.object({ + foo: z.string().optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.string().date().optional(), + quux: z.string().datetime().optional() }); + +export const zPostFooBody = zFoo3; 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 217db289a..0ae161f4b 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 @@ -1096,58 +1096,26 @@ export const zSimpleRequestBody = zModelWithString; */ export const zSimpleFormData = zModelWithString; -export const zExportData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zPatchApiVbyApiVersionNoTagData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zImportData = z.object({ - body: z.union([ - zModelWithReadOnlyAndWriteOnlyWritable, - zModelWithArrayReadOnlyAndWriteOnlyWritable - ]), - path: z.never().optional(), - query: z.never().optional() -}); +export const zImportBody = z.union([ + zModelWithReadOnlyAndWriteOnlyWritable, + zModelWithArrayReadOnlyAndWriteOnlyWritable +]); export const zImportResponse = z.union([ zModelFromZendesk, zModelWithReadOnlyAndWriteOnly ]); -export const zFooWowData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zApiVVersionODataControllerCountData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zApiVVersionODataControllerCountResponse = zModelFromZendesk; -export const zGetApiVbyApiVersionSimpleOperationData = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.union([ - z.string(), - z.uuid() - ]) - }), - query: z.never().optional() +export const zGetApiVbyApiVersionSimpleOperationPath = z.object({ + foo_param: z.union([ + z.string(), + z.uuid() + ]) }); /** @@ -1155,131 +1123,87 @@ export const zGetApiVbyApiVersionSimpleOperationData = z.object({ */ export const zGetApiVbyApiVersionSimpleOperationResponse = z.number(); -export const zDeleteCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooHeaders = z.object({ + 'x-Foo-Bar': zModelWithString }); -export const zGetCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeleteFooPath = z.object({ + foo_param: z.string(), + BarParam: z.string() }); -export const zHeadCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDescriptionsQuery = 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() }); -export const zOptionsCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zDeprecatedCallHeaders = z.object({ + parameter: zDeprecatedModel.nullable() }); -export const zPatchCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * This is the parameter that goes into the body + */ +export const zCallWithParametersBody = z.record(z.string(), z.unknown()).nullable(); -export const zPostCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersHeaders = z.object({ + parameterHeader: z.string().nullable() }); -export const zPutCallWithoutParametersAndResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithParametersPath = z.object({ + parameterPath: z.string().nullable(), + 'api-version': z.string().nullable() }); -export const zDeleteFooData3 = z.object({ - body: z.never().optional(), - path: z.object({ - foo_param: z.string(), - BarParam: z.string() - }), - query: z.never().optional(), - headers: z.object({ - 'x-Foo-Bar': zModelWithString - }) +export const zCallWithParametersQuery = z.object({ + foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), + foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, + cursor: z.string().nullable() }); -export const zCallWithDescriptionsData = z.object({ - 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() +/** + * This is the parameter that goes into the body + */ +export const zCallWithWeirdParameterNamesBody = zModelWithString.nullable(); + +export const zCallWithWeirdParameterNamesHeaders = z.object({ + 'parameter.header': z.string().nullable() }); -export const zDeprecatedCallData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional(), - headers: z.object({ - parameter: zDeprecatedModel.nullable() - }) +export const zCallWithWeirdParameterNamesPath = z.object({ + 'parameter.path.1': z.string().optional(), + 'parameter-path-2': z.string().optional(), + 'PARAMETER-PATH-3': z.string().optional(), + 'api-version': z.string().nullable() }); -export const zCallWithParametersData = z.object({ - body: z.record(z.string(), z.unknown()).nullable(), - path: z.object({ - parameterPath: z.string().nullable(), - 'api-version': z.string().nullable() - }), - query: z.object({ - foo_ref_enum: zModelWithNestedArrayEnumsDataFoo.optional(), - foo_all_of_enum: zModelWithNestedArrayEnumsDataFoo, - cursor: z.string().nullable() - }), - headers: z.object({ - parameterHeader: z.string().nullable() - }) +export const zCallWithWeirdParameterNamesQuery = z.object({ + default: z.string().optional(), + 'parameter-query': z.string().nullable() }); -export const zCallWithWeirdParameterNamesData = z.object({ - 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.string().nullable() - }), - query: z.object({ - default: z.string().optional(), - 'parameter-query': z.string().nullable() - }), - headers: z.object({ - 'parameter.header': z.string().nullable() - }) +/** + * This is a required parameter + */ +export const zGetCallWithOptionalParamBody = zModelWithOneOfEnum; + +export const zGetCallWithOptionalParamQuery = z.object({ + page: z.number().optional() }); -export const zGetCallWithOptionalParamData = z.object({ - body: zModelWithOneOfEnum, - path: z.never().optional(), - query: z.object({ - page: z.number().optional() - }).optional() +/** + * This is an optional parameter + */ +export const zPostCallWithOptionalParamBody = z.object({ + offset: z.number().nullish() }); -export const zPostCallWithOptionalParamData = z.object({ - body: z.object({ - offset: z.number().nullish() - }).optional(), - path: z.never().optional(), - query: z.object({ - parameter: zPageable - }) +export const zPostCallWithOptionalParamQuery = z.object({ + parameter: zPageable }); export const zPostCallWithOptionalParamResponse = z.union([ @@ -1287,97 +1211,57 @@ export const zPostCallWithOptionalParamResponse = z.union([ z.void() ]); -export const zPostApiVbyApiVersionRequestBodyData = z.object({ - body: zSimpleRequestBody.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zPostApiVbyApiVersionFormDataData = z.object({ - body: zSimpleFormData.optional(), - path: z.never().optional(), - query: z.object({ - parameter: z.string().optional() - }).optional() -}); - -export const zCallWithDefaultParametersData = z.object({ - 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' - ]).optional(), - parameterModel: zModelWithString.nullish() - }).optional() -}); - -export const zCallWithDefaultOptionalParametersData = z.object({ - 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(), - parameterModel: zModelWithString.optional().default({ prop: 'Hello World!' }) - }).optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionRequestBodyBody = zSimpleRequestBody; -export const zCallToTestOrderOfParamsData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.string().nullish(), - parameterStringNullableWithDefault: z.string().nullish().default(null) - }) +export const zPostApiVbyApiVersionRequestBodyQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateNameData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); +/** + * A reusable request body + */ +export const zPostApiVbyApiVersionFormDataBody = zSimpleFormData; -export const zDuplicateName2Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zPostApiVbyApiVersionFormDataQuery = z.object({ + parameter: z.string().optional() }); -export const zDuplicateName3Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultParametersQuery = 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' + ]).optional(), + parameterModel: zModelWithString.nullish() }); -export const zDuplicateName4Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallWithDefaultOptionalParametersQuery = 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(), + parameterModel: zModelWithString.optional().default({ prop: 'Hello World!' }) }); -export const zCallWithNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() +export const zCallToTestOrderOfParamsQuery = z.object({ + 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.string().nullish(), + parameterStringNullableWithDefault: z.string().nullish().default(null) }); /** @@ -1385,61 +1269,25 @@ export const zCallWithNoContentResponseData = z.object({ */ export const zCallWithNoContentResponseResponse = z.void(); -export const zCallWithResponseAndNoContentResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseAndNoContentResponseResponse = z.union([ z.number(), z.void() ]); -export const zDummyAData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zDummyAResponse = z400; -export const zDummyBData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * Success */ export const zDummyBResponse = z.void(); -export const zCallWithResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponseResponse = zImport; -export const zCallWithDuplicateResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithDuplicateResponsesResponse = z.union([ zModelWithBoolean.and(zModelWithInteger), zModelWithString ]); -export const zCallWithResponsesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - export const zCallWithResponsesResponse = z.union([ z.object({ '@namespace.string': z.string().readonly().optional(), @@ -1450,36 +1298,30 @@ export const zCallWithResponsesResponse = z.union([ zModelThatExtendsExtends ]); -export const zCollectionFormatData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - 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.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().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') - ]).nullable() - }) +export const zCollectionFormatQuery = z.object({ + 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 zTypesPath = 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() +}); + +export const zTypesQuery = z.object({ + parameterNumber: z.number().default(123), + 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') + ]).nullable() }); export const zTypesResponse = z.union([ @@ -1489,23 +1331,17 @@ export const zTypesResponse = z.union([ z.record(z.string(), z.unknown()) ]); -export const zUploadFileData = z.object({ - body: z.string(), - path: z.object({ - 'api-version': z.string().nullable() - }), - query: z.never().optional() +export const zUploadFileBody = z.string(); + +export const zUploadFilePath = z.object({ + 'api-version': z.string().nullable() }); export const zUploadFileResponse = z.boolean(); -export const zFileResponseData = z.object({ - body: z.never().optional(), - path: z.object({ - id: z.string(), - 'api-version': z.string() - }), - query: z.never().optional() +export const zFileResponsePath = z.object({ + id: z.string(), + 'api-version': z.string() }); /** @@ -1513,19 +1349,15 @@ export const zFileResponseData = z.object({ */ export const zFileResponseResponse = z.string(); -export const zComplexTypesData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - parameterObject: z.object({ - first: z.object({ - second: z.object({ - third: z.string().optional() - }).optional() +export const zComplexTypesQuery = z.object({ + parameterObject: z.object({ + first: z.object({ + second: z.object({ + third: z.string().optional() }).optional() - }), - parameterReference: zModelWithString - }) + }).optional() + }), + parameterReference: zModelWithString }); /** @@ -1533,12 +1365,6 @@ export const zComplexTypesData = z.object({ */ export const zComplexTypesResponse = z.array(zModelWithString); -export const zMultipartResponseData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ @@ -1550,43 +1376,37 @@ export const zMultipartResponseResponse = z.object({ }).optional() }); -export const zMultipartRequestData = z.object({ - 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.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.array(zModelWithString).nullish(), - listOfStrings: z.array(z.string()).nullish(), - parameters: z.union([ - zModelWithString, - zModelWithEnum, - zModelWithArray, - zModelWithDictionary - ]), - 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.never().optional() +export const zMultipartRequestBody = z.object({ + content: z.string().optional(), + data: zModelWithString.nullish() +}); + +export const zComplexParamsBody = 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.array(zModelWithString).nullish(), + listOfStrings: z.array(z.string()).nullish(), + parameters: z.union([ + zModelWithString, + zModelWithEnum, + zModelWithArray, + zModelWithDictionary + ]), + 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() +}); + +export const zComplexParamsPath = 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() }); /** @@ -1594,26 +1414,12 @@ export const zComplexParamsData = z.object({ */ export const zComplexParamsResponse = zModelWithString; -export const zCallWithResultFromHeaderData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - -export const zTestErrorCodeData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - status: z.int() - }) +export const zTestErrorCodeQuery = z.object({ + status: z.int() }); -export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.object({ - nonAsciiParamæøåÆØÅöôêÊ: z.int() - }) +export const zNonAsciiæøåÆøÅöôêÊ字符串Query = z.object({ + nonAsciiParamæøåÆØÅöôêÊ: z.int() }); /** @@ -1621,8 +1427,4 @@ export const zNonAsciiæøåÆøÅöôêÊ字符串Data = z.object({ */ export const zNonAsciiæøåÆøÅöôêÊ字符串Response = z.array(zNonAsciiStringæøåÆøÅöôêÊ字符串); -export const zPutWithFormUrlEncodedData = z.object({ - body: zArrayWithStrings, - path: z.never().optional(), - query: z.never().optional() -}); +export const zPutWithFormUrlEncodedBody = zArrayWithStrings; diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/string-with-guid-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/string-with-guid-format/zod.gen.ts index 0b9153430..f9bdb80f8 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/string-with-guid-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/string-with-guid-format/zod.gen.ts @@ -2,10 +2,6 @@ import * as z from 'zod'; -export const zGetFooData = z.object({ - body: z.never().optional(), - path: z.object({ - guidId: z.guid() - }), - query: z.never().optional() +export const zGetFooPath = z.object({ + guidId: z.guid() }); diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/type-format/sdk.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/type-format/sdk.gen.ts index aadc85c9f..f1b1a1e06 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/type-format/sdk.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/type-format/sdk.gen.ts @@ -1,10 +1,12 @@ // This file is auto-generated by @hey-api/openapi-ts +import * as z from 'zod'; + import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; import { postFooResponseTransformer } from './transformers.gen'; import type { PostFooData, PostFooResponses } from './types.gen'; -import { zPostFooData, zPostFooResponse } from './zod.gen'; +import { zPostFooResponse } from './zod.gen'; export type Options = Options2 & { /** @@ -21,7 +23,11 @@ export type Options(options?: Options) => (options?.client ?? client).post({ - requestValidator: async (data) => await zPostFooData.parseAsync(data), + requestValidator: async (data) => await z.object({ + body: z.never().optional(), + path: z.never().optional(), + query: z.never().optional() + }).parseAsync(data), responseTransformer: postFooResponseTransformer, responseValidator: async (data) => await zPostFooResponse.parseAsync(data), url: '/foo', diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/type-format/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/type-format/zod.gen.ts index bb1956f79..6173cb820 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/type-format/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/type-format/zod.gen.ts @@ -12,12 +12,6 @@ export const zBar = z.object({ foo: z.int() }); -export const zPostFooData = z.object({ - body: z.never().optional(), - path: z.never().optional(), - query: z.never().optional() -}); - /** * OK */ 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 cc4b41933..52d2c6713 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: zBar.optional() }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - 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 zPatchFooBody = z.object({ + foo: z.string().optional() }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = 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() }); + +export const zPostFooBody = zFoo3; diff --git a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-metadata-fn/zod.gen.ts b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-metadata-fn/zod.gen.ts index c024fae0e..a7d788926 100644 --- a/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-metadata-fn/zod.gen.ts +++ b/packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v4/validators-metadata-fn/zod.gen.ts @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: zBar.optional() }).register(z.globalRegistry, { custom: 'value', title: 'object' }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().register(z.globalRegistry, { custom: 'value', title: 'string' }).optional() - }).register(z.globalRegistry, { custom: 'value', title: 'object' }), - path: z.never().register(z.globalRegistry, { custom: 'value', title: 'never' }).optional(), - query: z.object({ - foo: z.string().register(z.globalRegistry, { custom: 'value', title: 'This is Foo parameter.' }).optional(), - bar: zBar.optional(), - baz: z.object({ - baz: z.string().register(z.globalRegistry, { custom: 'value', title: 'string' }).optional() - }).register(z.globalRegistry, { custom: 'value', title: 'object' }).optional(), - qux: z.iso.date().register(z.globalRegistry, { custom: 'value', title: 'string' }).optional(), - quux: z.iso.datetime().register(z.globalRegistry, { custom: 'value', title: 'string' }).optional() - }).register(z.globalRegistry, { custom: 'value', title: 'object' }).optional() +export const zPatchFooBody = z.object({ + foo: z.string().register(z.globalRegistry, { custom: 'value', title: 'string' }).optional() }).register(z.globalRegistry, { custom: 'value', title: 'object' }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().register(z.globalRegistry, { custom: 'value', title: 'never' }).optional(), - query: z.never().register(z.globalRegistry, { custom: 'value', title: 'never' }).optional() +export const zPatchFooQuery = z.object({ + foo: z.string().register(z.globalRegistry, { custom: 'value', title: 'This is Foo parameter.' }).optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().register(z.globalRegistry, { custom: 'value', title: 'string' }).optional() + }).register(z.globalRegistry, { custom: 'value', title: 'object' }).optional(), + qux: z.iso.date().register(z.globalRegistry, { custom: 'value', title: 'string' }).optional(), + quux: z.iso.datetime().register(z.globalRegistry, { custom: 'value', title: 'string' }).optional() }).register(z.globalRegistry, { custom: 'value', title: 'object' }); + +export const zPostFooBody = zFoo3; 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 ebee5444a..3792b9089 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 @@ -44,26 +44,20 @@ export const zFoo3 = z.object({ foo: zBar.optional() }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - path: z.never().optional(), - query: z.object({ - foo: z.string().register(z.globalRegistry, { - description: 'This is Foo parameter.' - }).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 zPatchFooBody = z.object({ + foo: z.string().optional() }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = z.object({ + foo: z.string().register(z.globalRegistry, { + description: 'This is Foo parameter.' + }).optional(), + bar: zBar.optional(), + baz: z.object({ + baz: z.string().optional() + }).optional(), + qux: z.iso.date().optional(), + quux: z.iso.datetime().optional() }); + +export const zPostFooBody = zFoo3; 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 75fc6f38a..917e0735d 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 @@ -46,28 +46,24 @@ export const zFoo3 = z.object({ export type FooZodType3 = z.infer; -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - 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 zPatchFooBody = z.object({ + foo: z.string().optional() }); -export type PatchFooDataZodType = z.infer; +export type PatchFooBodyZodType = z.infer; -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = 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() }); -export type PostFooDataZodType = z.infer; +export type PatchFooQueryZodType = z.infer; + +export const zPostFooBody = zFoo3; + +export type PostFooBodyZodType = z.infer; 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 7c70ac7f1..edbf35b7c 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 @@ -34,24 +34,18 @@ export const zFoo3 = z.object({ foo: zBar.optional() }); -export const zPatchFooData = z.object({ - body: z.object({ - foo: z.string().optional() - }), - 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 zPatchFooBody = z.object({ + foo: z.string().optional() }); -export const zPostFooData = z.object({ - body: zFoo3, - path: z.never().optional(), - query: z.never().optional() +export const zPatchFooQuery = 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() }); + +export const zPostFooBody = zFoo3; diff --git a/packages/openapi-ts/src/plugins/@angular/common/shared/node.ts b/packages/openapi-ts/src/plugins/@angular/common/shared/node.ts index 3188ce280..c37403910 100644 --- a/packages/openapi-ts/src/plugins/@angular/common/shared/node.ts +++ b/packages/openapi-ts/src/plugins/@angular/common/shared/node.ts @@ -206,7 +206,7 @@ function implementHttpRequestFn => { - const symClient = plugin.getSymbol({ category: 'client' }); + const symClient = plugin.querySymbol({ category: 'client' }); const optionalClient = Boolean(plugin.config.client && symClient); const symbolClient = plugin.external('client.Client'); return $.class(symbol) diff --git a/packages/openapi-ts/src/plugins/@hey-api/sdk/shared/operation.ts b/packages/openapi-ts/src/plugins/@hey-api/sdk/shared/operation.ts index 2aadb932b..3e54a3625 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/sdk/shared/operation.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/sdk/shared/operation.ts @@ -448,7 +448,7 @@ export function operationStatements({ } const symbolClient = plugin.config.client - ? plugin.getSymbol({ + ? plugin.querySymbol({ category: 'client', }) : undefined; diff --git a/packages/openapi-ts/src/plugins/@hey-api/sdk/shared/validator.ts b/packages/openapi-ts/src/plugins/@hey-api/sdk/shared/validator.ts index 5961fee5d..c66fac330 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/sdk/shared/validator.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/sdk/shared/validator.ts @@ -1,33 +1,33 @@ -import type { IR } from '@hey-api/shared'; +import type { IR, RequestSchemaContext } from '@hey-api/shared'; import type { $ } from '../../../../ts-dsl'; import type { HeyApiSdkPlugin } from '../types'; -interface ValidatorProps { - operation: IR.OperationObject; - plugin: HeyApiSdkPlugin['Instance']; -} - -export const createRequestValidator = ({ - operation, +export function createRequestValidator({ plugin, -}: ValidatorProps): ReturnType | undefined => { + ...args +}: RequestSchemaContext): ReturnType | undefined { if (!plugin.config.validator.request) return; const validator = plugin.getPluginOrThrow(plugin.config.validator.request); if (!validator.api.createRequestValidator) return; return validator.api.createRequestValidator({ - operation, + ...args, // @ts-expect-error plugin: validator, }); -}; +} -export const createResponseValidator = ({ +export function createResponseValidator({ operation, plugin, -}: ValidatorProps): ReturnType | undefined => { +}: { + /** The operation object. */ + operation: IR.OperationObject; + /** The plugin instance. */ + plugin: HeyApiSdkPlugin['Instance']; +}): ReturnType | undefined { if (!plugin.config.validator.response) return; const validator = plugin.getPluginOrThrow(plugin.config.validator.response); @@ -38,4 +38,4 @@ export const createResponseValidator = ({ // @ts-expect-error plugin: validator, }); -}; +} diff --git a/packages/openapi-ts/src/plugins/@hey-api/sdk/v1/node.ts b/packages/openapi-ts/src/plugins/@hey-api/sdk/v1/node.ts index b1fff5436..e93792196 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/sdk/v1/node.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/sdk/v1/node.ts @@ -193,7 +193,7 @@ function enrichRootClass(args: { symbol: symbolRegistry, }), ); - const isClientRequired = !plugin.config.client || !plugin.getSymbol({ category: 'client' }); + const isClientRequired = !plugin.config.client || !plugin.querySymbol({ category: 'client' }); const registry = plugin.symbol('__registry'); node.toAccessNode = (node, options) => { if (options.context) return; diff --git a/packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts b/packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts index fbf77a299..18777967c 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts @@ -56,7 +56,7 @@ function processSchemaType({ resourceId: schema.$ref, }; const symbol = - plugin.getSymbol(query) ?? + plugin.querySymbol(query) ?? plugin.symbol( applyNaming(refToName(schema.$ref), { case: 'camelCase', diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/shared/export.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/shared/export.ts index b42166552..446636e85 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/shared/export.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/shared/export.ts @@ -202,7 +202,10 @@ export function exportAst({ plugin, schema, tags, -}: ProcessorContext & { +}: Pick< + ProcessorContext, + 'meta' | 'naming' | 'namingAnchor' | 'path' | 'plugin' | 'schema' | 'tags' +> & { final: TypeScriptFinal; }): void { const $ref = meta.resourceId || pathToJsonPointer(path); diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/shared/processor.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/shared/processor.ts index b29f0d2d6..ac285936c 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/shared/processor.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/shared/processor.ts @@ -1,4 +1,4 @@ -import type { IR, NamingConfig, SchemaProcessorContext } from '@hey-api/shared'; +import type { NamingConfig, SchemaProcessorContext } from '@hey-api/shared'; import type { HeyApiTypeScriptPlugin } from '../types'; import type { TypeScriptFinal } from './types'; @@ -9,7 +9,6 @@ export type ProcessorContext = SchemaProcessorContext & { naming: NamingConfig; /** The plugin instance. */ plugin: HeyApiTypeScriptPlugin['Instance']; - schema: IR.SchemaObject; }; export type ProcessorResult = { diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/processor.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/processor.ts index 425869cb4..5357c76e7 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/processor.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/processor.ts @@ -22,7 +22,7 @@ export function createProcessor(plugin: HeyApiTypeScriptPlugin['Instance']): Pro } for (const hook of extractorHooks) { - const result = hook?.(ctx); + const result = typeof hook === 'boolean' ? hook : (hook?.(ctx) ?? false); if (result) { process({ namingAnchor: processor.context.anchor, diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/string.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/string.ts index 6b5040fc3..575d878ec 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/string.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/toAst/string.ts @@ -41,7 +41,7 @@ function formatNode(ctx: StringResolverContext): Type | undefined { resourceId: typeidBase, tool: 'typescript', }; - if (!plugin.getSymbol(typeidQuery)) { + if (!plugin.querySymbol(typeidQuery)) { const containerQuery: SymbolMeta = { category: 'type', resource: 'type-id', @@ -49,7 +49,7 @@ function formatNode(ctx: StringResolverContext): Type | undefined { variant: 'container', }; - if (!plugin.getSymbol(containerQuery)) { + if (!plugin.querySymbol(containerQuery)) { const symbolTypeId = plugin.symbol('TypeID', { meta: containerQuery, }); diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/walker.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/walker.ts index 2f7059574..f43cad6e9 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/walker.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/v1/walker.ts @@ -28,7 +28,7 @@ export interface VisitorConfig { } export function createVisitor( - config: VisitorConfig, + config: VisitorConfig = {}, ): SchemaVisitor { const { schemaExtractor } = config; diff --git a/packages/openapi-ts/src/plugins/@pinia/colada/queryKey.ts b/packages/openapi-ts/src/plugins/@pinia/colada/queryKey.ts index 645993a36..1bd6a5217 100644 --- a/packages/openapi-ts/src/plugins/@pinia/colada/queryKey.ts +++ b/packages/openapi-ts/src/plugins/@pinia/colada/queryKey.ts @@ -40,7 +40,7 @@ export const createQueryKeyFunction = ({ plugin }: { plugin: PiniaColadaPlugin[' resource: 'client-options', tool: 'sdk', }); - const symbolClient = plugin.getSymbol({ + const symbolClient = plugin.querySymbol({ category: 'client', }); diff --git a/packages/openapi-ts/src/plugins/@pinia/colada/queryOptions.ts b/packages/openapi-ts/src/plugins/@pinia/colada/queryOptions.ts index 6889a107e..4c931962c 100644 --- a/packages/openapi-ts/src/plugins/@pinia/colada/queryOptions.ts +++ b/packages/openapi-ts/src/plugins/@pinia/colada/queryOptions.ts @@ -34,7 +34,7 @@ export const createQueryOptions = ({ operation, }); if ( - !plugin.getSymbol({ + !plugin.querySymbol({ category: 'utility', resource: 'createQueryKey', tool: plugin.name, diff --git a/packages/openapi-ts/src/plugins/@tanstack/query-core/queryKey.ts b/packages/openapi-ts/src/plugins/@tanstack/query-core/queryKey.ts index f27a483eb..4e239615b 100644 --- a/packages/openapi-ts/src/plugins/@tanstack/query-core/queryKey.ts +++ b/packages/openapi-ts/src/plugins/@tanstack/query-core/queryKey.ts @@ -33,7 +33,7 @@ export const createQueryKeyFunction = ({ plugin }: { plugin: PluginInstance }) = const baseUrlKey = getClientBaseUrlKey(getTypedConfig(plugin)); - const symbolClient = plugin.getSymbol({ + const symbolClient = plugin.querySymbol({ category: 'client', }); diff --git a/packages/openapi-ts/src/plugins/@tanstack/query-core/v5/infiniteQueryOptions.ts b/packages/openapi-ts/src/plugins/@tanstack/query-core/v5/infiniteQueryOptions.ts index 4b124afa2..a00b45bb6 100644 --- a/packages/openapi-ts/src/plugins/@tanstack/query-core/v5/infiniteQueryOptions.ts +++ b/packages/openapi-ts/src/plugins/@tanstack/query-core/v5/infiniteQueryOptions.ts @@ -113,7 +113,7 @@ export const createInfiniteQueryOptions = ({ }); if ( - !plugin.getSymbol({ + !plugin.querySymbol({ category: 'utility', resource: 'createQueryKey', tool: plugin.name, @@ -124,7 +124,7 @@ export const createInfiniteQueryOptions = ({ } if ( - !plugin.getSymbol({ + !plugin.querySymbol({ category: 'utility', resource: 'createInfiniteParams', tool: plugin.name, diff --git a/packages/openapi-ts/src/plugins/@tanstack/query-core/v5/queryOptions.ts b/packages/openapi-ts/src/plugins/@tanstack/query-core/v5/queryOptions.ts index 01fc9ac80..a630e9a6e 100644 --- a/packages/openapi-ts/src/plugins/@tanstack/query-core/v5/queryOptions.ts +++ b/packages/openapi-ts/src/plugins/@tanstack/query-core/v5/queryOptions.ts @@ -32,7 +32,7 @@ export const createQueryOptions = ({ }); if ( - !plugin.getSymbol({ + !plugin.querySymbol({ category: 'utility', resource: 'createQueryKey', tool: plugin.name, diff --git a/packages/openapi-ts/src/plugins/arktype/api.ts b/packages/openapi-ts/src/plugins/arktype/api.ts index a638a09d0..08efb3b03 100644 --- a/packages/openapi-ts/src/plugins/arktype/api.ts +++ b/packages/openapi-ts/src/plugins/arktype/api.ts @@ -1,14 +1,21 @@ +import type { RequestSchemaContext } from '@hey-api/shared'; + import type { $ } from '../../ts-dsl'; import type { ValidatorArgs } from './shared/types'; +import type { ArktypePlugin } from './types'; import { createRequestValidatorV2, createResponseValidatorV2 } from './v2/api'; export type IApi = { - createRequestValidator: (args: ValidatorArgs) => ReturnType | undefined; + createRequestValidator: ( + args: RequestSchemaContext, + ) => ReturnType | undefined; createResponseValidator: (args: ValidatorArgs) => ReturnType | undefined; }; export class Api implements IApi { - createRequestValidator(args: ValidatorArgs): ReturnType | undefined { + createRequestValidator( + args: RequestSchemaContext, + ): ReturnType | undefined { return createRequestValidatorV2(args); } diff --git a/packages/openapi-ts/src/plugins/arktype/shared/types.ts b/packages/openapi-ts/src/plugins/arktype/shared/types.ts index 5679c6c52..f5410f1e7 100644 --- a/packages/openapi-ts/src/plugins/arktype/shared/types.ts +++ b/packages/openapi-ts/src/plugins/arktype/shared/types.ts @@ -5,6 +5,12 @@ import type ts from 'typescript'; import type { $ } from '../../../ts-dsl'; import type { ArktypePlugin } from '../types'; +export type ValidatorArgs = { + operation: IR.OperationObject; + /** The plugin instance. */ + plugin: ArktypePlugin['Instance']; +}; + export type Ast = { def: string; expression: ReturnType; @@ -25,8 +31,3 @@ export type PluginState = Pick, 'path'> & Pick, 'tags'> & { hasLazyExpression: boolean; }; - -export type ValidatorArgs = { - operation: IR.OperationObject; - plugin: ArktypePlugin['Instance']; -}; diff --git a/packages/openapi-ts/src/plugins/arktype/v2/api.ts b/packages/openapi-ts/src/plugins/arktype/v2/api.ts index 26e952a83..9fca3a4c9 100644 --- a/packages/openapi-ts/src/plugins/arktype/v2/api.ts +++ b/packages/openapi-ts/src/plugins/arktype/v2/api.ts @@ -1,11 +1,14 @@ +import type { RequestSchemaContext } from '@hey-api/shared'; + import { $ } from '../../../ts-dsl'; import type { ValidatorArgs } from '../shared/types'; +import type { ArktypePlugin } from '../types'; -export const createRequestValidatorV2 = ({ +export function createRequestValidatorV2({ operation, plugin, -}: ValidatorArgs): ReturnType | undefined => { - const symbol = plugin.getSymbol({ +}: RequestSchemaContext): ReturnType | undefined { + const symbol = plugin.querySymbol({ category: 'schema', resource: 'operation', resourceId: operation.id, @@ -33,13 +36,13 @@ export const createRequestValidatorV2 = ({ .async() .param(dataParameterName) .do($(symbol).attr('parseAsync').call(dataParameterName).await().return()); -}; +} -export const createResponseValidatorV2 = ({ +export function createResponseValidatorV2({ operation, plugin, -}: ValidatorArgs): ReturnType | undefined => { - const symbol = plugin.getSymbol({ +}: ValidatorArgs): ReturnType | undefined { + const symbol = plugin.querySymbol({ category: 'schema', resource: 'operation', resourceId: operation.id, @@ -53,4 +56,4 @@ export const createResponseValidatorV2 = ({ .async() .param(dataParameterName) .do($(symbol).attr('parseAsync').call(dataParameterName).await().return()); -}; +} diff --git a/packages/openapi-ts/src/plugins/orpc/contracts/node.ts b/packages/openapi-ts/src/plugins/orpc/contracts/node.ts index a19a0590f..d3dd22a51 100644 --- a/packages/openapi-ts/src/plugins/orpc/contracts/node.ts +++ b/packages/openapi-ts/src/plugins/orpc/contracts/node.ts @@ -77,15 +77,23 @@ function createContractExpression( ); if (hasInput(operation) && plugin.config.validator.input) { - expression = expression.attr('input').call( - plugin.referenceSymbol({ - category: 'schema', - resource: 'operation', - resourceId: operation.id, - role: 'data', - tool: plugin.config.validator.input, - }), - ); + const validator = plugin.getPluginOrThrow(plugin.config.validator.input); + if ('createRequestSchema' in validator.api) { + const requestSchema = validator.api.createRequestSchema({ + layers: { + body: { whenEmpty: 'omit' }, + headers: { whenEmpty: 'omit' }, + path: { as: 'params', whenEmpty: 'omit' }, + query: { whenEmpty: 'omit' }, + }, + operation, + // @ts-expect-error + plugin: validator, + }); + if (requestSchema) { + expression = expression.attr('input').call(requestSchema); + } + } } if (successResponse.hasOutput && plugin.config.validator.output) { diff --git a/packages/openapi-ts/src/plugins/valibot/api.ts b/packages/openapi-ts/src/plugins/valibot/api.ts index bf2598cdf..47d0b227f 100644 --- a/packages/openapi-ts/src/plugins/valibot/api.ts +++ b/packages/openapi-ts/src/plugins/valibot/api.ts @@ -1,14 +1,40 @@ +import type { Symbol } from '@hey-api/codegen-core'; +import type { RequestSchemaContext } from '@hey-api/shared'; + import type { $ } from '../../ts-dsl'; +import type { Pipe } from './shared/pipes'; import type { ValidatorArgs } from './shared/types'; -import { createRequestValidatorV1, createResponseValidatorV1 } from './v1/api'; +import type { ValibotPlugin } from './types'; +import { + createRequestSchemaV1, + createRequestValidatorV1, + createResponseValidatorV1, +} from './v1/api'; export type IApi = { - createRequestValidator: (args: ValidatorArgs) => ReturnType | undefined; + createRequestSchema: ( + ctx: RequestSchemaContext, + ) => Symbol | Pipe | undefined; + createRequestValidator: ( + args: RequestSchemaContext, + ) => ReturnType | undefined; createResponseValidator: (args: ValidatorArgs) => ReturnType | undefined; }; export class Api implements IApi { - createRequestValidator(args: ValidatorArgs): ReturnType | undefined { + createRequestSchema( + ctx: RequestSchemaContext, + ): Symbol | Pipe | undefined { + const { plugin } = ctx; + if (!plugin.config.requests.enabled) return; + return createRequestSchemaV1(ctx); + } + + createRequestValidator( + args: RequestSchemaContext, + ): ReturnType | undefined { + const { plugin } = args; + if (!plugin.config.requests.enabled) return; return createRequestValidatorV1(args); } diff --git a/packages/openapi-ts/src/plugins/valibot/config.ts b/packages/openapi-ts/src/plugins/valibot/config.ts index 8345ed878..0fb126ce0 100644 --- a/packages/openapi-ts/src/plugins/valibot/config.ts +++ b/packages/openapi-ts/src/plugins/valibot/config.ts @@ -27,11 +27,75 @@ export const defaultConfig: ValibotPlugin['Config'] = { plugin.config.requests = context.valueToObject({ defaultValue: { + body: { + case: plugin.config.case ?? 'camelCase', + enabled: true, + name: 'v{{name}}Body', + }, case: plugin.config.case ?? 'camelCase', enabled: true, + headers: { + case: plugin.config.case ?? 'camelCase', + enabled: true, + name: 'v{{name}}Headers', + }, name: 'v{{name}}Data', + path: { + case: plugin.config.case ?? 'camelCase', + enabled: true, + name: 'v{{name}}Path', + }, + query: { + case: plugin.config.case ?? 'camelCase', + enabled: true, + name: 'v{{name}}Query', + }, + shouldExtract: () => false, + }, + mappers: { + ...mappers, + object: (fields, defaultValue) => ({ + ...fields, + body: context.valueToObject({ + defaultValue: defaultValue.body as Extract< + typeof defaultValue.body, + Record + >, + mappers, + value: fields.body, + }), + headers: context.valueToObject({ + defaultValue: defaultValue.headers as Extract< + typeof defaultValue.headers, + Record + >, + mappers, + value: fields.headers, + }), + path: context.valueToObject({ + defaultValue: defaultValue.path as Extract< + typeof defaultValue.path, + Record + >, + mappers, + value: fields.path, + }), + query: context.valueToObject({ + defaultValue: defaultValue.query as Extract< + typeof defaultValue.query, + Record + >, + mappers, + value: fields.query, + }), + shouldExtract: + fields.shouldExtract !== undefined + ? typeof fields.shouldExtract === 'function' + ? fields.shouldExtract + : () => Boolean(fields.shouldExtract) + : defaultValue.shouldExtract, + }), }, - mappers, value: plugin.config.requests, }); diff --git a/packages/openapi-ts/src/plugins/valibot/resolvers.ts b/packages/openapi-ts/src/plugins/valibot/resolvers.ts index a3eebf709..4fa427008 100644 --- a/packages/openapi-ts/src/plugins/valibot/resolvers.ts +++ b/packages/openapi-ts/src/plugins/valibot/resolvers.ts @@ -1,5 +1,13 @@ import type { Symbol } from '@hey-api/codegen-core'; -import type { IR, Plugin, SchemaVisitorContext, SchemaWithType, Walker } from '@hey-api/shared'; +import type { + IR, + Plugin, + RequestSchemaContext, + ResolvedRequestValidatorLayer, + SchemaVisitorContext, + SchemaWithType, + Walker, +} from '@hey-api/shared'; import type { MaybeBigInt, ShouldCoerceToBigInt } from '../../plugins/shared/utils/coerce'; import type { GetIntegerLimit } from '../../plugins/shared/utils/formats'; @@ -118,25 +126,23 @@ export type ValibotResolvers = Plugin.Resolvers<{ * * Allow customization of validator function bodies. * - * Example path: `~resolvers.validator.request` or `~resolvers.validator.response` - * * Returning `undefined` will execute the default resolver logic. */ validator?: - | ValidatorResolver + | ((ctx: ValidatorResolverContext) => PipeResult | null | undefined) | { /** * Controls how the request validator function body is generated. * * Returning `undefined` will execute the default resolver logic. */ - request?: ValidatorResolver; + request?: (ctx: RequestValidatorResolverContext) => PipeResult | null | undefined; /** * Controls how the response validator function body is generated. * * Returning `undefined` will execute the default resolver logic. */ - response?: ValidatorResolver; + response?: (ctx: ResponseValidatorResolverContext) => PipeResult | null | undefined; }; /** * Resolver for void schemas. @@ -148,9 +154,7 @@ export type ValibotResolvers = Plugin.Resolvers<{ void?: (ctx: VoidResolverContext) => PipeResult; }>; -type ValidatorResolver = (ctx: ValidatorResolverContext) => PipeResult | null | undefined; - -interface BaseContext extends DollarTsDsl { +export interface BaseContext extends DollarTsDsl { /** * Functions for working with pipes. */ @@ -363,16 +367,74 @@ export interface UnknownResolverContext extends BaseContext { schema: SchemaWithType<'unknown'>; } -export interface ValidatorResolverContext extends BaseContext { +export interface RequestValidatorResolverContext + extends BaseContext, RequestSchemaContext { + /** + * Nodes used to build different parts of the result. + */ + nodes: { + /** + * Returns the composite schema combining all layers. + * + * Returns `undefined` if all layers are omitted. + */ + composite: (ctx: RequestValidatorResolverContext) => Pipe | undefined; + /** + * Returns an empty/fallback schema for a layer based on its `whenEmpty` config. + * + * @throws if `whenEmpty` is `'omit'` (no schema should be generated) + */ + empty: ( + ctx: RequestValidatorResolverContext & { + /** Resolved configuration for the request layer. */ + layer: ResolvedRequestValidatorLayer; + }, + ) => Pipe; + /** + * Returns an optional schema based on the layer's config. + */ + optional: ( + ctx: RequestValidatorResolverContext & { + /** Resolved configuration for the request layer. */ + layer: ResolvedRequestValidatorLayer; + /** The schema to conditionally wrap. */ + schema: Pipe; + }, + ) => Pipe; + }; + /** + * Provides access to commonly used symbols within the plugin. + */ + symbols: BaseContext['symbols'] & { + /** + * The schema to use in the validator body. + * + * This is either: + * - an inline AST expression + * - a Symbol reference to a named export + */ + schema: Symbol | Pipe; + }; +} + +export interface ResponseValidatorResolverContext extends BaseContext { + /** The operation being processed. */ operation: IR.OperationObject; /** * Provides access to commonly used symbols within the plugin. */ symbols: BaseContext['symbols'] & { + /** + * The response schema symbol. + */ schema: Symbol; }; } +export type ValidatorResolverContext = + | RequestValidatorResolverContext + | ResponseValidatorResolverContext; + export interface VoidResolverContext extends BaseContext { /** * Nodes used to build different parts of the result. diff --git a/packages/openapi-ts/src/plugins/valibot/shared/export.ts b/packages/openapi-ts/src/plugins/valibot/shared/export.ts index e2971af91..cc30c0723 100644 --- a/packages/openapi-ts/src/plugins/valibot/shared/export.ts +++ b/packages/openapi-ts/src/plugins/valibot/shared/export.ts @@ -1,3 +1,4 @@ +import type { Symbol } from '@hey-api/codegen-core'; import { buildSymbolIn, pathToName } from '@hey-api/shared'; import { createSchemaComment } from '../../../plugins/shared/utils/schema'; @@ -15,9 +16,12 @@ export function exportAst({ plugin, schema, tags, -}: ProcessorContext & { +}: Pick< + ProcessorContext, + 'meta' | 'naming' | 'namingAnchor' | 'path' | 'plugin' | 'schema' | 'tags' +> & { final: ValibotFinal; -}): void { +}): Symbol { const v = plugin.external('valibot.v'); const name = pathToName(path, { anchor: namingAnchor }); @@ -45,4 +49,6 @@ export function exportAst({ .assign(pipesToNode(final.pipes, plugin)); plugin.node(statement); + + return symbol; } diff --git a/packages/openapi-ts/src/plugins/valibot/shared/operation.ts b/packages/openapi-ts/src/plugins/valibot/shared/operation.ts index cfb18c11c..8462e3d38 100644 --- a/packages/openapi-ts/src/plugins/valibot/shared/operation.ts +++ b/packages/openapi-ts/src/plugins/valibot/shared/operation.ts @@ -17,19 +17,71 @@ export function irOperationToAst({ if (plugin.config.requests.enabled) { const { schema } = buildOperationSchema(operation); - processor.process({ - meta: { - resource: 'operation', - resourceId: operation.id, - role: 'data', - }, - naming: plugin.config.requests, - namingAnchor: operation.id, - path, - plugin, - schema, - tags, - }); + if (schema.properties?.body && schema.properties.body.type !== 'never') { + processor.process({ + meta: { + resource: 'operation', + resourceId: operation.id, + role: 'request-body', + }, + naming: plugin.config.requests.body, + namingAnchor: operation.id, + path: [...path, 'body'], + plugin, + schema: schema.properties.body, + tags, + }); + } + + // TODO: add support for cookies + + if (schema.properties?.headers && schema.properties.headers.type === 'object') { + processor.process({ + meta: { + resource: 'operation', + resourceId: operation.id, + role: 'request-headers', + }, + naming: plugin.config.requests.headers, + namingAnchor: operation.id, + path: [...path, 'headers'], + plugin, + schema: schema.properties.headers, + tags, + }); + } + + if (schema.properties?.path && schema.properties.path.type === 'object') { + processor.process({ + meta: { + resource: 'operation', + resourceId: operation.id, + role: 'request-path', + }, + naming: plugin.config.requests.path, + namingAnchor: operation.id, + path: [...path, 'path'], + plugin, + schema: schema.properties.path, + tags, + }); + } + + if (schema.properties?.query && schema.properties.query.type === 'object') { + processor.process({ + meta: { + resource: 'operation', + resourceId: operation.id, + role: 'request-query', + }, + naming: plugin.config.requests.query, + namingAnchor: operation.id, + path: [...path, 'query'], + plugin, + schema: schema.properties.query, + tags, + }); + } } if (plugin.config.responses.enabled) { diff --git a/packages/openapi-ts/src/plugins/valibot/shared/processor.ts b/packages/openapi-ts/src/plugins/valibot/shared/processor.ts index 5955fc8f2..a9f1a507a 100644 --- a/packages/openapi-ts/src/plugins/valibot/shared/processor.ts +++ b/packages/openapi-ts/src/plugins/valibot/shared/processor.ts @@ -1,4 +1,4 @@ -import type { IR, NamingConfig, SchemaProcessorContext } from '@hey-api/shared'; +import type { NamingConfig, SchemaProcessorContext } from '@hey-api/shared'; import type { ValibotPlugin } from '../types'; import type { ValibotFinal } from './types'; @@ -9,7 +9,6 @@ export type ProcessorContext = SchemaProcessorContext & { naming: NamingConfig; /** The plugin instance. */ plugin: ValibotPlugin['Instance']; - schema: IR.SchemaObject; }; export type ProcessorResult = { diff --git a/packages/openapi-ts/src/plugins/valibot/shared/validator.ts b/packages/openapi-ts/src/plugins/valibot/shared/validator.ts new file mode 100644 index 000000000..2efc30a2e --- /dev/null +++ b/packages/openapi-ts/src/plugins/valibot/shared/validator.ts @@ -0,0 +1,31 @@ +import type { DefaultRequestValidatorLayers, IR } from '@hey-api/shared'; + +import { buildOperationSchema } from './operation-schema'; + +export function getDefaultRequestValidatorLayers( + operation: IR.OperationObject, +): DefaultRequestValidatorLayers { + const { schema } = buildOperationSchema(operation); + return { + body: { + as: 'body', + optional: !schema.required?.includes('body'), + whenEmpty: 'strict', + }, + headers: { + as: 'headers', + optional: !schema.required?.includes('headers'), + whenEmpty: 'omit', + }, + path: { + as: 'path', + optional: !schema.required?.includes('path'), + whenEmpty: 'strict', + }, + query: { + as: 'query', + optional: !schema.required?.includes('query'), + whenEmpty: 'strict', + }, + }; +} diff --git a/packages/openapi-ts/src/plugins/valibot/types.ts b/packages/openapi-ts/src/plugins/valibot/types.ts index e55a19a3e..08b854911 100644 --- a/packages/openapi-ts/src/plugins/valibot/types.ts +++ b/packages/openapi-ts/src/plugins/valibot/types.ts @@ -7,6 +7,7 @@ import type { NamingOptions, Plugin, } from '@hey-api/shared'; +import type { MaybeFunc } from '@hey-api/types'; import type { $, DollarTsDsl } from '../../ts-dsl'; import type { IApi } from './api'; @@ -97,6 +98,39 @@ export type UserConfig = Plugin.Name<'valibot'> & | boolean | NameTransformer | { + /** + * Configuration for request body Valibot schemas. + * + * Can be: + * - `boolean`: Shorthand for `{ enabled: boolean }` + * - `string` or `function`: Shorthand for `{ name: string | function }` + * - `object`: Full configuration object + * + * @default true + */ + body?: + | boolean + | NameTransformer + | { + /** + * Casing convention for generated names. + * + * @default 'camelCase' + */ + case?: Casing; + /** + * Whether this feature is enabled. + * + * @default true + */ + enabled?: boolean; + /** + * Naming pattern for generated names. + * + * @default 'v{{name}}Body' + */ + name?: NameTransformer; + }; /** * Casing convention for generated names. * @@ -109,12 +143,140 @@ export type UserConfig = Plugin.Name<'valibot'> & * @default true */ enabled?: boolean; + /** + * Configuration for request headers Valibot schemas. + * + * Can be: + * - `boolean`: Shorthand for `{ enabled: boolean }` + * - `string` or `function`: Shorthand for `{ name: string | function }` + * - `object`: Full configuration object + * + * @default true + */ + headers?: + | boolean + | NameTransformer + | { + /** + * Casing convention for generated names. + * + * @default 'camelCase' + */ + case?: Casing; + /** + * Whether this feature is enabled. + * + * @default true + */ + enabled?: boolean; + /** + * Naming pattern for generated names. + * + * @default 'v{{name}}Headers' + */ + name?: NameTransformer; + }; /** * Naming pattern for generated names. * * @default 'v{{name}}Data' */ name?: NameTransformer; + /** + * Configuration for request path parameters Valibot schemas. + * + * Can be: + * - `boolean`: Shorthand for `{ enabled: boolean }` + * - `string` or `function`: Shorthand for `{ name: string | function }` + * - `object`: Full configuration object + * + * @default true + */ + path?: + | boolean + | NameTransformer + | { + /** + * Casing convention for generated names. + * + * @default 'camelCase' + */ + case?: Casing; + /** + * Whether this feature is enabled. + * + * @default true + */ + enabled?: boolean; + /** + * Naming pattern for generated names. + * + * @default 'v{{name}}Path' + */ + name?: NameTransformer; + }; + /** + * Configuration for request query parameters Valibot schemas. + * + * Can be: + * - `boolean`: Shorthand for `{ enabled: boolean }` + * - `string` or `function`: Shorthand for `{ name: string | function }` + * - `object`: Full configuration object + * + * @default true + */ + query?: + | boolean + | NameTransformer + | { + /** + * Casing convention for generated names. + * + * @default 'camelCase' + */ + case?: Casing; + /** + * Whether this feature is enabled. + * + * @default true + */ + enabled?: boolean; + /** + * Naming pattern for generated names. + * + * @default 'v{{name}}Query' + */ + name?: NameTransformer; + }; + /** + * Whether to extract the request schema into a named export. + * + * When `true`, generates a reusable schema like `vProjectListData`. + * When `false`, the schema is built inline within the caller plugin. + * + * Can be a boolean or a function for per-operation control. + * + * @default false + * @example + * ```ts + * // Always extract + * shouldExtract: true + * + * // Extract only for operations with complex request bodies + * shouldExtract: ({ operation }) => + * operation.body !== undefined && operation.parameters !== undefined + * + * // Extract based on custom extension + * shouldExtract: ({ operation }) => + * operation['x-custom']?.extractRequestSchema === true + * ``` + */ + shouldExtract?: MaybeFunc< + (ctx: { + /** The operation being processed */ + operation: IR.OperationObject; + }) => boolean + >; }; /** * Configuration for response-specific Valibot schemas. @@ -205,7 +367,22 @@ export type Config = Plugin.Name<'valibot'> & ctx: DollarTsDsl & { node: ReturnType; schema: IR.SchemaObject }, ) => void); /** Configuration for request-specific Valibot schemas. */ - requests: NamingOptions & FeatureToggle; + requests: NamingOptions & + FeatureToggle & { + /** Configuration for request body Valibot schemas. */ + body: NamingOptions & FeatureToggle; + /** Configuration for request headers Valibot schemas. */ + headers: NamingOptions & FeatureToggle; + /** Configuration for request path parameters Valibot schemas. */ + path: NamingOptions & FeatureToggle; + /** Configuration for request query parameters Valibot schemas. */ + query: NamingOptions & FeatureToggle; + /** Whether to extract the request schema into a named export. */ + shouldExtract: (ctx: { + /** The operation being processed */ + operation: IR.OperationObject; + }) => boolean; + }; /** Configuration for response-specific Valibot schemas. */ responses: NamingOptions & FeatureToggle; /** Configuration for webhook-specific Valibot schemas. */ diff --git a/packages/openapi-ts/src/plugins/valibot/v1/api.ts b/packages/openapi-ts/src/plugins/valibot/v1/api.ts index 7a1c86eb7..a8f6baf31 100644 --- a/packages/openapi-ts/src/plugins/valibot/v1/api.ts +++ b/packages/openapi-ts/src/plugins/valibot/v1/api.ts @@ -1,43 +1,122 @@ +import type { Symbol } from '@hey-api/codegen-core'; +import type { RequestSchemaContext, ResolvedRequestValidatorLayer } from '@hey-api/shared'; +import { requestValidatorLayers, resolveValidatorLayer } from '@hey-api/shared'; + import { $ } from '../../../ts-dsl'; -import type { ValidatorResolverContext } from '../resolvers'; +import type { + RequestValidatorResolverContext, + ResponseValidatorResolverContext, +} from '../resolvers'; +import { exportAst } from '../shared/export'; +import type { Pipe } from '../shared/pipes'; import { pipes } from '../shared/pipes'; import type { ValidatorArgs } from '../shared/types'; +import { getDefaultRequestValidatorLayers } from '../shared/validator'; +import type { ValibotPlugin } from '../types'; import { identifiers } from './constants'; -const validatorResolver = (ctx: ValidatorResolverContext): ReturnType => { +function emptyNode( + ctx: RequestValidatorResolverContext & { + layer: ResolvedRequestValidatorLayer; + }, +): Pipe { + const { v } = ctx.symbols; + if (ctx.layer.whenEmpty === 'omit') { + throw new Error( + `Cannot create empty schema for layer "${ctx.layer.as}" with whenEmpty: 'omit'`, + ); + } + if (ctx.layer.whenEmpty === 'strict') { + return $(v).attr(identifiers.schemas.never).call(); + } + return $(v).attr(identifiers.schemas.object).call($.object()); +} + +function optionalNode( + ctx: RequestValidatorResolverContext & { + layer: ResolvedRequestValidatorLayer; + schema: Pipe; + }, +): Pipe { + if (!ctx.layer.optional) return ctx.schema; + const v = ctx.symbols.v; + return $(v).attr(identifiers.schemas.optional).call(ctx.schema); +} + +function compositeNode(ctx: RequestValidatorResolverContext): Pipe | undefined { + const { v } = ctx.symbols; + const obj = $.object(); + + const defaultValues = getDefaultRequestValidatorLayers(ctx.operation); + for (const key of requestValidatorLayers) { + const layer = resolveValidatorLayer(ctx.layers, key, defaultValues); + + const layerSchema = ctx.plugin.querySymbol({ + category: 'schema', + resource: 'operation', + resourceId: ctx.operation.id, + role: `request-${key}`, + tool: 'valibot', + }); + + if (layerSchema) { + obj.prop(layer.as, ctx.nodes.optional({ ...ctx, layer, schema: $(layerSchema) })); + continue; + } + + if (layer.whenEmpty === 'omit') { + continue; + } + + const empty = ctx.nodes.empty({ ...ctx, layer }); + obj.prop(layer.as, ctx.nodes.optional({ ...ctx, layer, schema: empty })); + } + + if (obj.isEmpty) { + return; + } + + return $(v).attr(identifiers.schemas.object).call(obj); +} + +function requestValidatorResolver( + ctx: RequestValidatorResolverContext, +): ReturnType { const { schema, v } = ctx.symbols; return $(v).attr(identifiers.async.parseAsync).call(schema, 'data').await().return(); -}; +} -export const createRequestValidatorV1 = ({ - operation, - plugin, -}: ValidatorArgs): ReturnType | undefined => { - const symbol = plugin.getSymbol({ - category: 'schema', - resource: 'operation', - resourceId: operation.id, - role: 'data', - tool: 'valibot', - }); - if (!symbol) return; +function responseValidatorResolver( + ctx: ResponseValidatorResolverContext, +): ReturnType { + const { schema, v } = ctx.symbols; + return $(v).attr(identifiers.async.parseAsync).call(schema, 'data').await().return(); +} - const ctx: ValidatorResolverContext = { - $, - operation, - pipes: { - ...pipes, - current: [], - }, - plugin, - symbols: { - schema: symbol, - v: plugin.external('valibot.v'), - }, - }; - const validator = plugin.config['~resolvers']?.validator; +function runRequestResolver( + ctx: RequestValidatorResolverContext, +): ReturnType | undefined { + const validator = ctx.plugin.config['~resolvers']?.validator; const resolver = typeof validator === 'function' ? validator : validator?.request; - const candidates = [resolver, validatorResolver]; + const candidates = [resolver, requestValidatorResolver]; + for (const candidate of candidates) { + const statements = candidate?.(ctx); + if (statements === null) return; + if (statements !== undefined) { + return $.func() + .async() + .param('data') + .do(...(statements instanceof Array ? statements : [statements])); + } + } +} + +function runResponseResolver( + ctx: ResponseValidatorResolverContext, +): ReturnType | undefined { + const validator = ctx.plugin.config['~resolvers']?.validator; + const resolver = typeof validator === 'function' ? validator : validator?.response; + const candidates = [resolver, responseValidatorResolver]; for (const candidate of candidates) { const statements = candidate?.(ctx); if (statements === null) return; @@ -48,13 +127,85 @@ export const createRequestValidatorV1 = ({ .do(...(statements instanceof Array ? statements : [statements])); } } -}; +} + +function createRequestSchemaContext( + ctx: RequestSchemaContext, +): RequestValidatorResolverContext { + const { plugin } = ctx; + const v = plugin.external('valibot.v'); + + return { + ...ctx, + $, + nodes: { + composite: compositeNode, + empty: emptyNode, + optional: optionalNode, + }, + pipes: { + ...pipes, + current: [], + }, + symbols: { + schema: $(''), + v, + }, + }; +} + +export function createRequestSchemaV1( + ctx: RequestSchemaContext, +): Symbol | Pipe | undefined { + const { operation, plugin } = ctx; + const baseCtx = createRequestSchemaContext(ctx); + + const schema = baseCtx.nodes.composite(baseCtx); + if (!schema) return; + + if (!plugin.config.requests.shouldExtract({ operation })) { + return schema; + } -export const createResponseValidatorV1 = ({ + return exportAst({ + final: { + pipes: [schema], + }, + meta: { + resource: 'operation', + resourceId: operation.id, + role: 'data', + }, + naming: plugin.config.requests, + namingAnchor: operation.id, + path: [], + plugin, + schema: {}, + }); +} + +export function createRequestValidatorV1( + ctx: RequestSchemaContext, +): ReturnType | undefined { + const symbolOrSchema = createRequestSchemaV1(ctx); + if (!symbolOrSchema) return; + + const baseCtx = createRequestSchemaContext(ctx); + const resolverCtx: RequestValidatorResolverContext = { + ...baseCtx, + symbols: { + ...baseCtx.symbols, + schema: symbolOrSchema, + }, + }; + return runRequestResolver(resolverCtx); +} + +export function createResponseValidatorV1({ operation, plugin, -}: ValidatorArgs): ReturnType | undefined => { - const symbol = plugin.getSymbol({ +}: ValidatorArgs): ReturnType | undefined { + const symbol = plugin.querySymbol({ category: 'schema', resource: 'operation', resourceId: operation.id, @@ -63,7 +214,8 @@ export const createResponseValidatorV1 = ({ }); if (!symbol) return; - const ctx: ValidatorResolverContext = { + const v = plugin.external('valibot.v'); + const resolverCtx: ResponseValidatorResolverContext = { $, operation, pipes: { @@ -73,20 +225,8 @@ export const createResponseValidatorV1 = ({ plugin, symbols: { schema: symbol, - v: plugin.external('valibot.v'), + v, }, }; - const validator = plugin.config['~resolvers']?.validator; - const resolver = typeof validator === 'function' ? validator : validator?.response; - const candidates = [resolver, validatorResolver]; - for (const candidate of candidates) { - const statements = candidate?.(ctx); - if (statements === null) return; - if (statements !== undefined) { - return $.func() - .async() - .param('data') - .do(...(statements instanceof Array ? statements : [statements])); - } - } -}; + return runResponseResolver(resolverCtx); +} diff --git a/packages/openapi-ts/src/plugins/valibot/v1/processor.ts b/packages/openapi-ts/src/plugins/valibot/v1/processor.ts index ad4b6ee34..650223030 100644 --- a/packages/openapi-ts/src/plugins/valibot/v1/processor.ts +++ b/packages/openapi-ts/src/plugins/valibot/v1/processor.ts @@ -22,7 +22,7 @@ export function createProcessor(plugin: ValibotPlugin['Instance']): ProcessorRes } for (const hook of extractorHooks) { - const result = hook?.(ctx); + const result = typeof hook === 'boolean' ? hook : (hook?.(ctx) ?? false); if (result) { process({ namingAnchor: processor.context.anchor, diff --git a/packages/openapi-ts/src/plugins/valibot/v1/walker.ts b/packages/openapi-ts/src/plugins/valibot/v1/walker.ts index 031cccb48..e493dad98 100644 --- a/packages/openapi-ts/src/plugins/valibot/v1/walker.ts +++ b/packages/openapi-ts/src/plugins/valibot/v1/walker.ts @@ -37,7 +37,7 @@ function getDefaultValue(meta: ValibotMeta): ReturnType { } export function createVisitor( - config: VisitorConfig, + config: VisitorConfig = {}, ): SchemaVisitor { const { schemaExtractor } = config; @@ -143,6 +143,12 @@ export function createVisitor( return walk(extracted, ctx); } } + if (schema.symbolRef) { + return { + meta: defaultMeta(schema), + pipes: [$(schema.symbolRef)], + }; + } }, intersection(items, schemas, parentSchema, ctx) { const applyModifiers: Parameters[0]['applyModifiers'] = ( diff --git a/packages/openapi-ts/src/plugins/zod/api.ts b/packages/openapi-ts/src/plugins/zod/api.ts index 4bd35f7e3..097ec1176 100644 --- a/packages/openapi-ts/src/plugins/zod/api.ts +++ b/packages/openapi-ts/src/plugins/zod/api.ts @@ -1,38 +1,79 @@ +import type { Symbol } from '@hey-api/codegen-core'; +import type { RequestSchemaContext } from '@hey-api/shared'; + import type { $ } from '../../ts-dsl'; -import { createRequestValidatorMini, createResponseValidatorMini } from './mini/api'; +import { + createRequestSchemaMini, + createRequestValidatorMini, + createResponseValidatorMini, +} from './mini/api'; +import type { Chain } from './shared/chain'; import type { ValidatorArgs } from './shared/types'; -import { createRequestValidatorV3, createResponseValidatorV3 } from './v3/api'; -import { createRequestValidatorV4, createResponseValidatorV4 } from './v4/api'; +import type { ZodPlugin } from './types'; +import { + createRequestSchemaV3, + createRequestValidatorV3, + createResponseValidatorV3, +} from './v3/api'; +import { + createRequestSchemaV4, + createRequestValidatorV4, + createResponseValidatorV4, +} from './v4/api'; export type IApi = { - createRequestValidator: (args: ValidatorArgs) => ReturnType | undefined; - createResponseValidator: (args: ValidatorArgs) => ReturnType | undefined; + createRequestSchema: ( + ctx: RequestSchemaContext, + ) => Symbol | Chain | undefined; + createRequestValidator: ( + ctx: RequestSchemaContext, + ) => ReturnType | undefined; + createResponseValidator: (ctx: ValidatorArgs) => ReturnType | undefined; }; export class Api implements IApi { - createRequestValidator(args: ValidatorArgs): ReturnType | undefined { - const { plugin } = args; + createRequestSchema( + ctx: RequestSchemaContext, + ): Symbol | Chain | undefined { + const { plugin } = ctx; + if (!plugin.config.requests.enabled) return; + switch (plugin.config.compatibilityVersion) { + case 3: + return createRequestSchemaV3(ctx); + case 'mini': + return createRequestSchemaMini(ctx); + case 4: + default: + return createRequestSchemaV4(ctx); + } + } + + createRequestValidator( + ctx: RequestSchemaContext, + ): ReturnType | undefined { + const { plugin } = ctx; + if (!plugin.config.requests.enabled) return; switch (plugin.config.compatibilityVersion) { case 3: - return createRequestValidatorV3(args); + return createRequestValidatorV3(ctx); case 'mini': - return createRequestValidatorMini(args); + return createRequestValidatorMini(ctx); case 4: default: - return createRequestValidatorV4(args); + return createRequestValidatorV4(ctx); } } - createResponseValidator(args: ValidatorArgs): ReturnType | undefined { - const { plugin } = args; + createResponseValidator(ctx: ValidatorArgs): ReturnType | undefined { + const { plugin } = ctx; switch (plugin.config.compatibilityVersion) { case 3: - return createResponseValidatorV3(args); + return createResponseValidatorV3(ctx); case 'mini': - return createResponseValidatorMini(args); + return createResponseValidatorMini(ctx); case 4: default: - return createResponseValidatorV4(args); + return createResponseValidatorV4(ctx); } } } diff --git a/packages/openapi-ts/src/plugins/zod/config.ts b/packages/openapi-ts/src/plugins/zod/config.ts index 9968e3957..e67ecb5b4 100644 --- a/packages/openapi-ts/src/plugins/zod/config.ts +++ b/packages/openapi-ts/src/plugins/zod/config.ts @@ -159,9 +159,70 @@ export const defaultConfig: ZodPlugin['Config'] = { plugin.config.requests = context.valueToObject({ defaultValue: { + body: { + case: plugin.config.case ?? 'camelCase', + enabled: true, + name: 'z{{name}}Body', + types: { + ...plugin.config.types, + infer: { + ...(plugin.config.types.infer as Extract< + typeof plugin.config.types.infer, + Record + >), + name: '{{name}}BodyZodType', + }, + }, + }, case: plugin.config.case ?? 'camelCase', enabled: true, + headers: { + case: plugin.config.case ?? 'camelCase', + enabled: true, + name: 'z{{name}}Headers', + types: { + ...plugin.config.types, + infer: { + ...(plugin.config.types.infer as Extract< + typeof plugin.config.types.infer, + Record + >), + name: '{{name}}HeadersZodType', + }, + }, + }, name: 'z{{name}}Data', + path: { + case: plugin.config.case ?? 'camelCase', + enabled: true, + name: 'z{{name}}Path', + types: { + ...plugin.config.types, + infer: { + ...(plugin.config.types.infer as Extract< + typeof plugin.config.types.infer, + Record + >), + name: '{{name}}PathZodType', + }, + }, + }, + query: { + case: plugin.config.case ?? 'camelCase', + enabled: true, + name: 'z{{name}}Query', + types: { + ...plugin.config.types, + infer: { + ...(plugin.config.types.infer as Extract< + typeof plugin.config.types.infer, + Record + >), + name: '{{name}}QueryZodType', + }, + }, + }, + shouldExtract: () => false, types: { ...plugin.config.types, infer: { @@ -177,6 +238,176 @@ export const defaultConfig: ZodPlugin['Config'] = { ...mappers, object: (fields, defaultValue) => ({ ...fields, + body: context.valueToObject({ + defaultValue: defaultValue.body as Extract< + typeof defaultValue.body, + Record + >, + mappers: { + ...mappers, + object: (fields, defaultValue) => ({ + ...fields, + types: context.valueToObject({ + defaultValue: defaultValue.types!, + mappers: { + object: (fields, defaultValue) => ({ + ...fields, + infer: context.valueToObject({ + defaultValue: { + ...(defaultValue.infer as Extract< + typeof defaultValue.infer, + Record + >), + enabled: + fields.infer !== undefined + ? Boolean(fields.infer) + : ( + defaultValue.infer as Extract< + typeof defaultValue.infer, + Record + > + ).enabled, + }, + mappers, + value: fields.infer, + }), + }), + }, + value: fields.types, + }), + }), + }, + value: fields.body, + }), + headers: context.valueToObject({ + defaultValue: defaultValue.headers as Extract< + typeof defaultValue.headers, + Record + >, + mappers: { + ...mappers, + object: (fields, defaultValue) => ({ + ...fields, + types: context.valueToObject({ + defaultValue: defaultValue.types!, + mappers: { + object: (fields, defaultValue) => ({ + ...fields, + infer: context.valueToObject({ + defaultValue: { + ...(defaultValue.infer as Extract< + typeof defaultValue.infer, + Record + >), + enabled: + fields.infer !== undefined + ? Boolean(fields.infer) + : ( + defaultValue.infer as Extract< + typeof defaultValue.infer, + Record + > + ).enabled, + }, + mappers, + value: fields.infer, + }), + }), + }, + value: fields.types, + }), + }), + }, + value: fields.headers, + }), + path: context.valueToObject({ + defaultValue: defaultValue.path as Extract< + typeof defaultValue.path, + Record + >, + mappers: { + ...mappers, + object: (fields, defaultValue) => ({ + ...fields, + types: context.valueToObject({ + defaultValue: defaultValue.types!, + mappers: { + object: (fields, defaultValue) => ({ + ...fields, + infer: context.valueToObject({ + defaultValue: { + ...(defaultValue.infer as Extract< + typeof defaultValue.infer, + Record + >), + enabled: + fields.infer !== undefined + ? Boolean(fields.infer) + : ( + defaultValue.infer as Extract< + typeof defaultValue.infer, + Record + > + ).enabled, + }, + mappers, + value: fields.infer, + }), + }), + }, + value: fields.types, + }), + }), + }, + value: fields.path, + }), + query: context.valueToObject({ + defaultValue: defaultValue.query as Extract< + typeof defaultValue.query, + Record + >, + mappers: { + ...mappers, + object: (fields, defaultValue) => ({ + ...fields, + types: context.valueToObject({ + defaultValue: defaultValue.types!, + mappers: { + object: (fields, defaultValue) => ({ + ...fields, + infer: context.valueToObject({ + defaultValue: { + ...(defaultValue.infer as Extract< + typeof defaultValue.infer, + Record + >), + enabled: + fields.infer !== undefined + ? Boolean(fields.infer) + : ( + defaultValue.infer as Extract< + typeof defaultValue.infer, + Record + > + ).enabled, + }, + mappers, + value: fields.infer, + }), + }), + }, + value: fields.types, + }), + }), + }, + value: fields.query, + }), + shouldExtract: + fields.shouldExtract !== undefined + ? typeof fields.shouldExtract === 'function' + ? fields.shouldExtract + : () => Boolean(fields.shouldExtract) + : defaultValue.shouldExtract, types: context.valueToObject({ defaultValue: defaultValue.types!, mappers: { diff --git a/packages/openapi-ts/src/plugins/zod/mini/api.ts b/packages/openapi-ts/src/plugins/zod/mini/api.ts index ace1c85a7..9ff5e7e37 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/api.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/api.ts @@ -1,42 +1,121 @@ +import type { Symbol } from '@hey-api/codegen-core'; +import type { RequestSchemaContext, ResolvedRequestValidatorLayer } from '@hey-api/shared'; +import { requestValidatorLayers, resolveValidatorLayer } from '@hey-api/shared'; + import { $ } from '../../../ts-dsl'; import { identifiers } from '../constants'; -import type { ValidatorResolverContext } from '../resolvers'; +import type { + RequestValidatorResolverContext, + ResponseValidatorResolverContext, +} from '../resolvers'; +import type { Chain } from '../shared/chain'; +import { exportAst } from '../shared/export'; import type { ValidatorArgs } from '../shared/types'; +import { getDefaultRequestValidatorLayers } from '../shared/validator'; +import type { ZodPlugin } from '../types'; + +function emptyNode( + ctx: RequestValidatorResolverContext & { + layer: ResolvedRequestValidatorLayer; + }, +): Chain { + const { z } = ctx.symbols; + if (ctx.layer.whenEmpty === 'omit') { + throw new Error( + `Cannot create empty schema for layer "${ctx.layer.as}" with whenEmpty: 'omit'`, + ); + } + if (ctx.layer.whenEmpty === 'strict') { + return $(z).attr(identifiers.never).call(); + } + return $(z).attr(identifiers.object).call($.object()); +} + +function optionalNode( + ctx: RequestValidatorResolverContext & { + layer: ResolvedRequestValidatorLayer; + schema: Chain; + }, +): Chain { + if (!ctx.layer.optional) return ctx.schema; + const { z } = ctx.symbols; + return $(z).attr(identifiers.optional).call(ctx.schema); +} + +function compositeNode(ctx: RequestValidatorResolverContext): Chain | undefined { + const { z } = ctx.symbols; + const obj = $.object(); + + const defaultValues = getDefaultRequestValidatorLayers(ctx.operation); + for (const key of requestValidatorLayers) { + const layer = resolveValidatorLayer(ctx.layers, key, defaultValues); + + const layerSchema = ctx.plugin.querySymbol({ + category: 'schema', + resource: 'operation', + resourceId: ctx.operation.id, + role: `request-${key}`, + tool: 'zod', + }); + + if (layerSchema) { + obj.prop(layer.as, ctx.nodes.optional({ ...ctx, layer, schema: $(layerSchema) })); + continue; + } + + if (layer.whenEmpty === 'omit') { + continue; + } + + const empty = ctx.nodes.empty({ ...ctx, layer }); + obj.prop(layer.as, ctx.nodes.optional({ ...ctx, layer, schema: empty })); + } + + if (obj.isEmpty) { + return; + } + + return $(z).attr(identifiers.object).call(obj); +} -const validatorResolver = (ctx: ValidatorResolverContext): ReturnType => { +function requestValidatorResolver( + ctx: RequestValidatorResolverContext, +): ReturnType { const { schema } = ctx.symbols; return $(schema).attr(identifiers.parseAsync).call('data').await().return(); -}; +} -export const createRequestValidatorMini = ({ - operation, - plugin, -}: ValidatorArgs): ReturnType | undefined => { - const symbol = plugin.getSymbol({ - category: 'schema', - resource: 'operation', - resourceId: operation.id, - role: 'data', - tool: 'zod', - }); - if (!symbol) return; +function responseValidatorResolver( + ctx: ResponseValidatorResolverContext, +): ReturnType { + const { schema } = ctx.symbols; + return $(schema).attr(identifiers.parseAsync).call('data').await().return(); +} - const z = plugin.external('zod.z'); - const ctx: ValidatorResolverContext = { - $, - chain: { - current: $(z), - }, - operation, - plugin, - symbols: { - schema: symbol, - z, - }, - }; - const validator = plugin.config['~resolvers']?.validator; +function runRequestResolver( + ctx: RequestValidatorResolverContext, +): ReturnType | undefined { + const validator = ctx.plugin.config['~resolvers']?.validator; const resolver = typeof validator === 'function' ? validator : validator?.request; - const candidates = [resolver, validatorResolver]; + const candidates = [resolver, requestValidatorResolver]; + for (const candidate of candidates) { + const statements = candidate?.(ctx); + if (statements === null) return; + if (statements !== undefined) { + return $.func() + .async() + .param('data') + .do(...(statements instanceof Array ? statements : [statements])); + } + } +} + +function runResponseResolver( + ctx: ResponseValidatorResolverContext, +): ReturnType | undefined { + const validator = ctx.plugin.config['~resolvers']?.validator; + const resolver = typeof validator === 'function' ? validator : validator?.response; + const candidates = [resolver, responseValidatorResolver]; for (const candidate of candidates) { const statements = candidate?.(ctx); if (statements === null) return; @@ -47,14 +126,84 @@ export const createRequestValidatorMini = ({ .do(...(statements instanceof Array ? statements : [statements])); } } - return; -}; +} + +function createRequestSchemaContext( + ctx: RequestSchemaContext, +): RequestValidatorResolverContext { + const { plugin } = ctx; + const z = plugin.external('zod.z'); + + return { + ...ctx, + $, + chain: { + current: $(z), + }, + nodes: { + composite: compositeNode, + empty: emptyNode, + optional: optionalNode, + }, + symbols: { + schema: $(''), + z, + }, + }; +} + +export function createRequestSchemaMini( + ctx: RequestSchemaContext, +): Symbol | Chain | undefined { + const { operation, plugin } = ctx; + const baseCtx = createRequestSchemaContext(ctx); + + const schema = baseCtx.nodes.composite(baseCtx); + if (!schema) return; + + if (!plugin.config.requests.shouldExtract({ operation })) { + return schema; + } + + return exportAst({ + final: { + expression: schema, + }, + meta: { + resource: 'operation', + resourceId: operation.id, + role: 'data', + }, + naming: plugin.config.requests, + namingAnchor: operation.id, + path: [], + plugin, + schema: {}, + }); +} + +export function createRequestValidatorMini( + ctx: RequestSchemaContext, +): ReturnType | undefined { + const symbolOrSchema = createRequestSchemaMini(ctx); + if (!symbolOrSchema) return; + + const baseCtx = createRequestSchemaContext(ctx); + const resolverCtx: RequestValidatorResolverContext = { + ...baseCtx, + symbols: { + ...baseCtx.symbols, + schema: symbolOrSchema, + }, + }; + return runRequestResolver(resolverCtx); +} -export const createResponseValidatorMini = ({ +export function createResponseValidatorMini({ operation, plugin, -}: ValidatorArgs): ReturnType | undefined => { - const symbol = plugin.getSymbol({ +}: ValidatorArgs): ReturnType | undefined { + const symbol = plugin.querySymbol({ category: 'schema', resource: 'operation', resourceId: operation.id, @@ -64,7 +213,7 @@ export const createResponseValidatorMini = ({ if (!symbol) return; const z = plugin.external('zod.z'); - const ctx: ValidatorResolverContext = { + const resolverCtx: ResponseValidatorResolverContext = { $, chain: { current: $(z), @@ -76,18 +225,5 @@ export const createResponseValidatorMini = ({ z, }, }; - const validator = plugin.config['~resolvers']?.validator; - const resolver = typeof validator === 'function' ? validator : validator?.response; - const candidates = [resolver, validatorResolver]; - for (const candidate of candidates) { - const statements = candidate?.(ctx); - if (statements === null) return; - if (statements !== undefined) { - return $.func() - .async() - .param('data') - .do(...(statements instanceof Array ? statements : [statements])); - } - } - return; -}; + return runResponseResolver(resolverCtx); +} diff --git a/packages/openapi-ts/src/plugins/zod/mini/processor.ts b/packages/openapi-ts/src/plugins/zod/mini/processor.ts index b2fdb66ee..89e6166b9 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/processor.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/processor.ts @@ -1,5 +1,5 @@ import { ref } from '@hey-api/codegen-core'; -import type { IR } from '@hey-api/shared'; +import type { Hooks, IR } from '@hey-api/shared'; import { createSchemaProcessor, createSchemaWalker, pathToJsonPointer } from '@hey-api/shared'; import { exportAst } from '../shared/export'; @@ -11,15 +11,18 @@ import { createVisitor } from './walker'; export function createProcessor(plugin: ZodPlugin['Instance']): ProcessorResult { const processor = createSchemaProcessor(); - const hooks = [plugin.config['~hooks']?.schemas, plugin.context.config.parser.hooks.schemas]; + const extractorHooks: ReadonlyArray['shouldExtract']> = [ + plugin.config['~hooks']?.schemas?.shouldExtract, + plugin.context.config.parser.hooks.schemas?.shouldExtract, + ]; function extractor(ctx: ProcessorContext): IR.SchemaObject { if (processor.hasEmitted(ctx.path)) { return ctx.schema; } - for (const hook of hooks) { - const result = hook?.shouldExtract?.(ctx); + for (const hook of extractorHooks) { + const result = typeof hook === 'boolean' ? hook : (hook?.(ctx) ?? false); if (result) { process({ namingAnchor: processor.context.anchor, diff --git a/packages/openapi-ts/src/plugins/zod/mini/walker.ts b/packages/openapi-ts/src/plugins/zod/mini/walker.ts index b8078643a..3d30781d6 100644 --- a/packages/openapi-ts/src/plugins/zod/mini/walker.ts +++ b/packages/openapi-ts/src/plugins/zod/mini/walker.ts @@ -30,7 +30,7 @@ export interface VisitorConfig { } export function createVisitor( - config: VisitorConfig, + config: VisitorConfig = {}, ): SchemaVisitor { const { schemaExtractor } = config; @@ -131,6 +131,12 @@ export function createVisitor( return walk(extracted, ctx); } } + if (schema.symbolRef) { + return { + expression: $(schema.symbolRef), + meta: defaultMeta(schema), + }; + } }, intersection(items, schemas, parentSchema, ctx) { const z = ctx.plugin.external('zod.z'); diff --git a/packages/openapi-ts/src/plugins/zod/resolvers.ts b/packages/openapi-ts/src/plugins/zod/resolvers.ts index 50bfa72e6..9f7e76bff 100644 --- a/packages/openapi-ts/src/plugins/zod/resolvers.ts +++ b/packages/openapi-ts/src/plugins/zod/resolvers.ts @@ -1,5 +1,13 @@ import type { Symbol } from '@hey-api/codegen-core'; -import type { IR, Plugin, SchemaVisitorContext, SchemaWithType, Walker } from '@hey-api/shared'; +import type { + IR, + Plugin, + RequestSchemaContext, + ResolvedRequestValidatorLayer, + SchemaVisitorContext, + SchemaWithType, + Walker, +} from '@hey-api/shared'; import type { MaybeArray } from '@hey-api/types'; import type ts from 'typescript'; @@ -120,25 +128,27 @@ export type ZodResolvers = Plugin.Resolvers<{ * * Allow customization of validator function bodies. * - * Example path: `~resolvers.validator.request` or `~resolvers.validator.response` - * * Returning `undefined` will execute the default resolver logic. */ validator?: - | ValidatorResolver + | ((ctx: ValidatorResolverContext) => MaybeArray> | null | undefined) | { /** * Controls how the request validator function body is generated. * * Returning `undefined` will execute the default resolver logic. */ - request?: ValidatorResolver; + request?: ( + ctx: RequestValidatorResolverContext, + ) => MaybeArray> | null | undefined; /** * Controls how the response validator function body is generated. * * Returning `undefined` will execute the default resolver logic. */ - response?: ValidatorResolver; + response?: ( + ctx: ResponseValidatorResolverContext, + ) => MaybeArray> | null | undefined; }; /** * Resolver for void schemas. @@ -150,11 +160,7 @@ export type ZodResolvers = Plugin.Resolvers<{ void?: (ctx: VoidResolverContext) => ChainResult; }>; -type ValidatorResolver = ( - ctx: ValidatorResolverContext, -) => MaybeArray> | null | undefined; - -interface BaseContext extends DollarTsDsl { +export interface BaseContext extends DollarTsDsl { /** * Functions for working with chains. */ @@ -470,16 +476,74 @@ export interface UnknownResolverContext extends BaseContext { schema: SchemaWithType<'unknown'>; } -export interface ValidatorResolverContext extends BaseContext { +export interface RequestValidatorResolverContext + extends BaseContext, RequestSchemaContext { + /** + * Nodes used to build different parts of the result. + */ + nodes: { + /** + * Returns the composite schema combining all layers. + * + * Returns `undefined` if all layers are omitted. + */ + composite: (ctx: RequestValidatorResolverContext) => Chain | undefined; + /** + * Returns an empty/fallback schema for a layer based on its `whenEmpty` config. + * + * @throws if `whenEmpty` is `'omit'` (no schema should be generated) + */ + empty: ( + ctx: RequestValidatorResolverContext & { + /** Resolved configuration for the request layer. */ + layer: ResolvedRequestValidatorLayer; + }, + ) => Chain; + /** + * Returns an optional schema based on the layer's config. + */ + optional: ( + ctx: RequestValidatorResolverContext & { + /** Resolved configuration for the request layer. */ + layer: ResolvedRequestValidatorLayer; + /** The schema to conditionally wrap. */ + schema: Chain; + }, + ) => Chain; + }; + /** + * Provides access to commonly used symbols within the plugin. + */ + symbols: BaseContext['symbols'] & { + /** + * The schema to use in the validator body. + * + * This is either: + * - an inline AST expression + * - a Symbol reference to a named export + */ + schema: Symbol | Chain; + }; +} + +export interface ResponseValidatorResolverContext extends BaseContext { + /** The operation being processed. */ operation: IR.OperationObject; /** * Provides access to commonly used symbols within the plugin. */ symbols: BaseContext['symbols'] & { + /** + * The response schema symbol. + */ schema: Symbol; }; } +export type ValidatorResolverContext = + | RequestValidatorResolverContext + | ResponseValidatorResolverContext; + export interface VoidResolverContext extends BaseContext { /** * Nodes used to build different parts of the result. diff --git a/packages/openapi-ts/src/plugins/zod/shared/export.ts b/packages/openapi-ts/src/plugins/zod/shared/export.ts index 07b811cd6..dff62e6dd 100644 --- a/packages/openapi-ts/src/plugins/zod/shared/export.ts +++ b/packages/openapi-ts/src/plugins/zod/shared/export.ts @@ -1,3 +1,4 @@ +import type { Symbol } from '@hey-api/codegen-core'; import { buildSymbolIn, pathToName } from '@hey-api/shared'; import { createSchemaComment } from '../../../plugins/shared/utils/schema'; @@ -15,10 +16,10 @@ export function exportAst({ plugin, schema, tags, -}: ProcessorContext & { +}: Pick & { final: ZodFinal; meta?: Record; -}): void { +}): Symbol { const z = plugin.external('zod.z'); const name = pathToName(path, { anchor: namingAnchor }); @@ -72,4 +73,6 @@ export function exportAst({ .type($.type(z).attr(identifiers.infer).generic($(symbol).typeofType())); plugin.node(inferType); } + + return symbol; } diff --git a/packages/openapi-ts/src/plugins/zod/shared/operation.ts b/packages/openapi-ts/src/plugins/zod/shared/operation.ts index cfb18c11c..8462e3d38 100644 --- a/packages/openapi-ts/src/plugins/zod/shared/operation.ts +++ b/packages/openapi-ts/src/plugins/zod/shared/operation.ts @@ -17,19 +17,71 @@ export function irOperationToAst({ if (plugin.config.requests.enabled) { const { schema } = buildOperationSchema(operation); - processor.process({ - meta: { - resource: 'operation', - resourceId: operation.id, - role: 'data', - }, - naming: plugin.config.requests, - namingAnchor: operation.id, - path, - plugin, - schema, - tags, - }); + if (schema.properties?.body && schema.properties.body.type !== 'never') { + processor.process({ + meta: { + resource: 'operation', + resourceId: operation.id, + role: 'request-body', + }, + naming: plugin.config.requests.body, + namingAnchor: operation.id, + path: [...path, 'body'], + plugin, + schema: schema.properties.body, + tags, + }); + } + + // TODO: add support for cookies + + if (schema.properties?.headers && schema.properties.headers.type === 'object') { + processor.process({ + meta: { + resource: 'operation', + resourceId: operation.id, + role: 'request-headers', + }, + naming: plugin.config.requests.headers, + namingAnchor: operation.id, + path: [...path, 'headers'], + plugin, + schema: schema.properties.headers, + tags, + }); + } + + if (schema.properties?.path && schema.properties.path.type === 'object') { + processor.process({ + meta: { + resource: 'operation', + resourceId: operation.id, + role: 'request-path', + }, + naming: plugin.config.requests.path, + namingAnchor: operation.id, + path: [...path, 'path'], + plugin, + schema: schema.properties.path, + tags, + }); + } + + if (schema.properties?.query && schema.properties.query.type === 'object') { + processor.process({ + meta: { + resource: 'operation', + resourceId: operation.id, + role: 'request-query', + }, + naming: plugin.config.requests.query, + namingAnchor: operation.id, + path: [...path, 'query'], + plugin, + schema: schema.properties.query, + tags, + }); + } } if (plugin.config.responses.enabled) { diff --git a/packages/openapi-ts/src/plugins/zod/shared/processor.ts b/packages/openapi-ts/src/plugins/zod/shared/processor.ts index 04963a14e..cb9c0334d 100644 --- a/packages/openapi-ts/src/plugins/zod/shared/processor.ts +++ b/packages/openapi-ts/src/plugins/zod/shared/processor.ts @@ -1,4 +1,4 @@ -import type { IR, NamingConfig, SchemaProcessorContext } from '@hey-api/shared'; +import type { NamingConfig, SchemaProcessorContext } from '@hey-api/shared'; import type { ZodPlugin } from '../types'; import type { TypeOptions, ZodFinal } from './types'; @@ -9,7 +9,6 @@ export type ProcessorContext = SchemaProcessorContext & { naming: NamingConfig & TypeOptions; /** The plugin instance. */ plugin: ZodPlugin['Instance']; - schema: IR.SchemaObject; }; export type ProcessorResult = { diff --git a/packages/openapi-ts/src/plugins/zod/shared/validator.ts b/packages/openapi-ts/src/plugins/zod/shared/validator.ts new file mode 100644 index 000000000..2efc30a2e --- /dev/null +++ b/packages/openapi-ts/src/plugins/zod/shared/validator.ts @@ -0,0 +1,31 @@ +import type { DefaultRequestValidatorLayers, IR } from '@hey-api/shared'; + +import { buildOperationSchema } from './operation-schema'; + +export function getDefaultRequestValidatorLayers( + operation: IR.OperationObject, +): DefaultRequestValidatorLayers { + const { schema } = buildOperationSchema(operation); + return { + body: { + as: 'body', + optional: !schema.required?.includes('body'), + whenEmpty: 'strict', + }, + headers: { + as: 'headers', + optional: !schema.required?.includes('headers'), + whenEmpty: 'omit', + }, + path: { + as: 'path', + optional: !schema.required?.includes('path'), + whenEmpty: 'strict', + }, + query: { + as: 'query', + optional: !schema.required?.includes('query'), + whenEmpty: 'strict', + }, + }; +} diff --git a/packages/openapi-ts/src/plugins/zod/types.ts b/packages/openapi-ts/src/plugins/zod/types.ts index 49f831f63..3886bc90f 100644 --- a/packages/openapi-ts/src/plugins/zod/types.ts +++ b/packages/openapi-ts/src/plugins/zod/types.ts @@ -7,6 +7,7 @@ import type { NamingOptions, Plugin, } from '@hey-api/shared'; +import type { MaybeFunc } from '@hey-api/types'; import type { $, DollarTsDsl } from '../../ts-dsl'; import type { IApi } from './api'; @@ -162,7 +163,7 @@ export type UserConfig = Plugin.Name<'zod'> & /** * Configuration for request-specific Zod schemas. * - * Controls generation of Zod schemas for request bodies, query parameters, path + * Controls generation of Zod schemas for request bodies, path parameters, query * parameters, and headers. * * Can be: @@ -176,6 +177,79 @@ export type UserConfig = Plugin.Name<'zod'> & | boolean | NameTransformer | { + /** + * Configuration for request body Zod schemas. + * + * Can be: + * - `boolean`: Shorthand for `{ enabled: boolean }` + * - `string` or `function`: Shorthand for `{ name: string | function }` + * - `object`: Full configuration object + * + * @default true + */ + body?: + | boolean + | NameTransformer + | { + /** + * Casing convention for generated names. + * + * @default 'camelCase' + */ + case?: Casing; + /** + * Whether this feature is enabled. + * + * @default true + */ + enabled?: boolean; + /** + * Naming pattern for generated names. + * + * @default 'z{{name}}Body' + */ + name?: NameTransformer; + /** + * Configuration for TypeScript type generation from Zod schemas. + * + * Controls generation of TypeScript types based on the generated Zod schemas. + */ + types?: { + /** + * Configuration for `infer` types. + * + * Can be: + * - `boolean`: Shorthand for `{ enabled: boolean }` + * - `string` or `function`: Shorthand for `{ name: string | function }` + * - `object`: Full configuration object + * + * @default false + */ + infer?: + | boolean + | NameTransformer + | { + /** + * Casing convention for generated names. + * + * @default 'PascalCase' + */ + case?: Casing; + /** + * Whether this feature is enabled. + * + * @default true + */ + enabled?: boolean; + /** + * Naming pattern for generated names. + * + * @default '{{name}}BodyZodType' + */ + name?: NameTransformer; + }; + }; + }; /** * Casing convention for generated names. * @@ -188,12 +262,260 @@ export type UserConfig = Plugin.Name<'zod'> & * @default true */ enabled?: boolean; + /** + * Configuration for request headers Zod schemas. + * + * Can be: + * - `boolean`: Shorthand for `{ enabled: boolean }` + * - `string` or `function`: Shorthand for `{ name: string | function }` + * - `object`: Full configuration object + * + * @default true + */ + headers?: + | boolean + | NameTransformer + | { + /** + * Casing convention for generated names. + * + * @default 'camelCase' + */ + case?: Casing; + /** + * Whether this feature is enabled. + * + * @default true + */ + enabled?: boolean; + /** + * Naming pattern for generated names. + * + * @default 'z{{name}}Headers' + */ + name?: NameTransformer; + /** + * Configuration for TypeScript type generation from Zod schemas. + * + * Controls generation of TypeScript types based on the generated Zod schemas. + */ + types?: { + /** + * Configuration for `infer` types. + * + * Can be: + * - `boolean`: Shorthand for `{ enabled: boolean }` + * - `string` or `function`: Shorthand for `{ name: string | function }` + * - `object`: Full configuration object + * + * @default false + */ + infer?: + | boolean + | NameTransformer + | { + /** + * Casing convention for generated names. + * + * @default 'PascalCase' + */ + case?: Casing; + /** + * Whether this feature is enabled. + * + * @default true + */ + enabled?: boolean; + /** + * Naming pattern for generated names. + * + * @default '{{name}}HeadersZodType' + */ + name?: NameTransformer; + }; + }; + }; /** * Naming pattern for generated names. * * @default 'z{{name}}Data' */ name?: NameTransformer; + /** + * Configuration for request path parameters Zod schemas. + * + * Can be: + * - `boolean`: Shorthand for `{ enabled: boolean }` + * - `string` or `function`: Shorthand for `{ name: string | function }` + * - `object`: Full configuration object + * + * @default true + */ + path?: + | boolean + | NameTransformer + | { + /** + * Casing convention for generated names. + * + * @default 'camelCase' + */ + case?: Casing; + /** + * Whether this feature is enabled. + * + * @default true + */ + enabled?: boolean; + /** + * Naming pattern for generated names. + * + * @default 'z{{name}}Path' + */ + name?: NameTransformer; + /** + * Configuration for TypeScript type generation from Zod schemas. + * + * Controls generation of TypeScript types based on the generated Zod schemas. + */ + types?: { + /** + * Configuration for `infer` types. + * + * Can be: + * - `boolean`: Shorthand for `{ enabled: boolean }` + * - `string` or `function`: Shorthand for `{ name: string | function }` + * - `object`: Full configuration object + * + * @default false + */ + infer?: + | boolean + | NameTransformer + | { + /** + * Casing convention for generated names. + * + * @default 'PascalCase' + */ + case?: Casing; + /** + * Whether this feature is enabled. + * + * @default true + */ + enabled?: boolean; + /** + * Naming pattern for generated names. + * + * @default '{{name}}PathZodType' + */ + name?: NameTransformer; + }; + }; + }; + /** + * Configuration for request query parameters Zod schemas. + * + * Can be: + * - `boolean`: Shorthand for `{ enabled: boolean }` + * - `string` or `function`: Shorthand for `{ name: string | function }` + * - `object`: Full configuration object + * + * @default true + */ + query?: + | boolean + | NameTransformer + | { + /** + * Casing convention for generated names. + * + * @default 'camelCase' + */ + case?: Casing; + /** + * Whether this feature is enabled. + * + * @default true + */ + enabled?: boolean; + /** + * Naming pattern for generated names. + * + * @default 'z{{name}}Query' + */ + name?: NameTransformer; + /** + * Configuration for TypeScript type generation from Zod schemas. + * + * Controls generation of TypeScript types based on the generated Zod schemas. + */ + types?: { + /** + * Configuration for `infer` types. + * + * Can be: + * - `boolean`: Shorthand for `{ enabled: boolean }` + * - `string` or `function`: Shorthand for `{ name: string | function }` + * - `object`: Full configuration object + * + * @default false + */ + infer?: + | boolean + | NameTransformer + | { + /** + * Casing convention for generated names. + * + * @default 'PascalCase' + */ + case?: Casing; + /** + * Whether this feature is enabled. + * + * @default true + */ + enabled?: boolean; + /** + * Naming pattern for generated names. + * + * @default '{{name}}QueryZodType' + */ + name?: NameTransformer; + }; + }; + }; + /** + * Whether to extract the request schema into a named export. + * + * When `true`, generates a reusable schema like `zProjectListData`. + * When `false`, the schema is built inline within the caller plugin. + * + * Can be a boolean or a function for per-operation control. + * + * @default false + * @example + * ```ts + * // Always extract + * shouldExtract: true + * + * // Extract only for operations with complex request bodies + * shouldExtract: ({ operation }) => + * operation.body !== undefined && operation.parameters !== undefined + * + * // Extract based on custom extension + * shouldExtract: ({ operation }) => + * operation['x-custom']?.extractRequestSchema === true + * ``` + */ + shouldExtract?: MaybeFunc< + (ctx: { + /** The operation being processed */ + operation: IR.OperationObject; + }) => boolean + >; /** * Configuration for TypeScript type generation from Zod schemas. * @@ -447,7 +769,23 @@ export type Config = Plugin.Name<'zod'> & ctx: DollarTsDsl & { node: ReturnType; schema: IR.SchemaObject }, ) => void); /** Configuration for request-specific Zod schemas. */ - requests: NamingOptions & FeatureToggle & TypeOptions; + requests: NamingOptions & + FeatureToggle & + TypeOptions & { + /** Configuration for request body Zod schemas. */ + body: NamingOptions & FeatureToggle & TypeOptions; + /** Configuration for request headers Zod schemas. */ + headers: NamingOptions & FeatureToggle & TypeOptions; + /** Configuration for request path parameters Zod schemas. */ + path: NamingOptions & FeatureToggle & TypeOptions; + /** Configuration for request query parameters Zod schemas. */ + query: NamingOptions & FeatureToggle & TypeOptions; + /** Whether to extract the request schema into a named export. */ + shouldExtract: (ctx: { + /** The operation being processed */ + operation: IR.OperationObject; + }) => boolean; + }; /** Configuration for response-specific Zod schemas. */ responses: NamingOptions & FeatureToggle & TypeOptions; /** Configuration for TypeScript type generation from Zod schemas. */ diff --git a/packages/openapi-ts/src/plugins/zod/v3/api.ts b/packages/openapi-ts/src/plugins/zod/v3/api.ts index 286544f9e..7200e4816 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/api.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/api.ts @@ -1,42 +1,120 @@ +import type { Symbol } from '@hey-api/codegen-core'; +import type { RequestSchemaContext, ResolvedRequestValidatorLayer } from '@hey-api/shared'; +import { requestValidatorLayers, resolveValidatorLayer } from '@hey-api/shared'; + import { $ } from '../../../ts-dsl'; import { identifiers } from '../constants'; -import type { ValidatorResolverContext } from '../resolvers'; +import type { + RequestValidatorResolverContext, + ResponseValidatorResolverContext, +} from '../resolvers'; +import type { Chain } from '../shared/chain'; +import { exportAst } from '../shared/export'; import type { ValidatorArgs } from '../shared/types'; +import { getDefaultRequestValidatorLayers } from '../shared/validator'; +import type { ZodPlugin } from '../types'; + +function emptyNode( + ctx: RequestValidatorResolverContext & { + layer: ResolvedRequestValidatorLayer; + }, +): Chain { + const { z } = ctx.symbols; + if (ctx.layer.whenEmpty === 'omit') { + throw new Error( + `Cannot create empty schema for layer "${ctx.layer.as}" with whenEmpty: 'omit'`, + ); + } + if (ctx.layer.whenEmpty === 'strict') { + return $(z).attr(identifiers.never).call(); + } + return $(z).attr(identifiers.object).call($.object()); +} + +function optionalNode( + ctx: RequestValidatorResolverContext & { + layer: ResolvedRequestValidatorLayer; + schema: Chain; + }, +): Chain { + if (!ctx.layer.optional) return ctx.schema; + return $(ctx.schema).attr(identifiers.optional).call(); +} + +function compositeNode(ctx: RequestValidatorResolverContext): Chain | undefined { + const { z } = ctx.symbols; + const obj = $.object(); + + const defaultValues = getDefaultRequestValidatorLayers(ctx.operation); + for (const key of requestValidatorLayers) { + const layer = resolveValidatorLayer(ctx.layers, key, defaultValues); + + const layerSchema = ctx.plugin.querySymbol({ + category: 'schema', + resource: 'operation', + resourceId: ctx.operation.id, + role: `request-${key}`, + tool: 'zod', + }); + + if (layerSchema) { + obj.prop(layer.as, ctx.nodes.optional({ ...ctx, layer, schema: $(layerSchema) })); + continue; + } + + if (layer.whenEmpty === 'omit') { + continue; + } + + const empty = ctx.nodes.empty({ ...ctx, layer }); + obj.prop(layer.as, ctx.nodes.optional({ ...ctx, layer, schema: empty })); + } + + if (obj.isEmpty) { + return; + } + + return $(z).attr(identifiers.object).call(obj); +} -const validatorResolver = (ctx: ValidatorResolverContext): ReturnType => { +function requestValidatorResolver( + ctx: RequestValidatorResolverContext, +): ReturnType { const { schema } = ctx.symbols; return $(schema).attr(identifiers.parseAsync).call('data').await().return(); -}; +} -export const createRequestValidatorV3 = ({ - operation, - plugin, -}: ValidatorArgs): ReturnType | undefined => { - const symbol = plugin.getSymbol({ - category: 'schema', - resource: 'operation', - resourceId: operation.id, - role: 'data', - tool: 'zod', - }); - if (!symbol) return; +function responseValidatorResolver( + ctx: ResponseValidatorResolverContext, +): ReturnType { + const { schema } = ctx.symbols; + return $(schema).attr(identifiers.parseAsync).call('data').await().return(); +} - const z = plugin.external('zod.z'); - const ctx: ValidatorResolverContext = { - $, - chain: { - current: $(z), - }, - operation, - plugin, - symbols: { - schema: symbol, - z, - }, - }; - const validator = plugin.config['~resolvers']?.validator; +function runRequestResolver( + ctx: RequestValidatorResolverContext, +): ReturnType | undefined { + const validator = ctx.plugin.config['~resolvers']?.validator; const resolver = typeof validator === 'function' ? validator : validator?.request; - const candidates = [resolver, validatorResolver]; + const candidates = [resolver, requestValidatorResolver]; + for (const candidate of candidates) { + const statements = candidate?.(ctx); + if (statements === null) return; + if (statements !== undefined) { + return $.func() + .async() + .param('data') + .do(...(statements instanceof Array ? statements : [statements])); + } + } +} + +function runResponseResolver( + ctx: ResponseValidatorResolverContext, +): ReturnType | undefined { + const validator = ctx.plugin.config['~resolvers']?.validator; + const resolver = typeof validator === 'function' ? validator : validator?.response; + const candidates = [resolver, responseValidatorResolver]; for (const candidate of candidates) { const statements = candidate?.(ctx); if (statements === null) return; @@ -47,14 +125,84 @@ export const createRequestValidatorV3 = ({ .do(...(statements instanceof Array ? statements : [statements])); } } - return; -}; +} + +function createRequestSchemaContext( + ctx: RequestSchemaContext, +): RequestValidatorResolverContext { + const { plugin } = ctx; + const z = plugin.external('zod.z'); + + return { + ...ctx, + $, + chain: { + current: $(z), + }, + nodes: { + composite: compositeNode, + empty: emptyNode, + optional: optionalNode, + }, + symbols: { + schema: $(''), + z, + }, + }; +} + +export function createRequestSchemaV3( + ctx: RequestSchemaContext, +): Symbol | Chain | undefined { + const { operation, plugin } = ctx; + const baseCtx = createRequestSchemaContext(ctx); + + const schema = baseCtx.nodes.composite(baseCtx); + if (!schema) return; + + if (!plugin.config.requests.shouldExtract({ operation })) { + return schema; + } + + return exportAst({ + final: { + expression: schema, + }, + meta: { + resource: 'operation', + resourceId: operation.id, + role: 'data', + }, + naming: plugin.config.requests, + namingAnchor: operation.id, + path: [], + plugin, + schema: {}, + }); +} + +export function createRequestValidatorV3( + ctx: RequestSchemaContext, +): ReturnType | undefined { + const symbolOrSchema = createRequestSchemaV3(ctx); + if (!symbolOrSchema) return; + + const baseCtx = createRequestSchemaContext(ctx); + const resolverCtx: RequestValidatorResolverContext = { + ...baseCtx, + symbols: { + ...baseCtx.symbols, + schema: symbolOrSchema, + }, + }; + return runRequestResolver(resolverCtx); +} -export const createResponseValidatorV3 = ({ +export function createResponseValidatorV3({ operation, plugin, -}: ValidatorArgs): ReturnType | undefined => { - const symbol = plugin.getSymbol({ +}: ValidatorArgs): ReturnType | undefined { + const symbol = plugin.querySymbol({ category: 'schema', resource: 'operation', resourceId: operation.id, @@ -64,7 +212,7 @@ export const createResponseValidatorV3 = ({ if (!symbol) return; const z = plugin.external('zod.z'); - const ctx: ValidatorResolverContext = { + const resolverCtx: ResponseValidatorResolverContext = { $, chain: { current: $(z), @@ -76,18 +224,5 @@ export const createResponseValidatorV3 = ({ z, }, }; - const validator = plugin.config['~resolvers']?.validator; - const resolver = typeof validator === 'function' ? validator : validator?.response; - const candidates = [resolver, validatorResolver]; - for (const candidate of candidates) { - const statements = candidate?.(ctx); - if (statements === null) return; - if (statements !== undefined) { - return $.func() - .async() - .param('data') - .do(...(statements instanceof Array ? statements : [statements])); - } - } - return; -}; + return runResponseResolver(resolverCtx); +} diff --git a/packages/openapi-ts/src/plugins/zod/v3/processor.ts b/packages/openapi-ts/src/plugins/zod/v3/processor.ts index b2fdb66ee..89e6166b9 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/processor.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/processor.ts @@ -1,5 +1,5 @@ import { ref } from '@hey-api/codegen-core'; -import type { IR } from '@hey-api/shared'; +import type { Hooks, IR } from '@hey-api/shared'; import { createSchemaProcessor, createSchemaWalker, pathToJsonPointer } from '@hey-api/shared'; import { exportAst } from '../shared/export'; @@ -11,15 +11,18 @@ import { createVisitor } from './walker'; export function createProcessor(plugin: ZodPlugin['Instance']): ProcessorResult { const processor = createSchemaProcessor(); - const hooks = [plugin.config['~hooks']?.schemas, plugin.context.config.parser.hooks.schemas]; + const extractorHooks: ReadonlyArray['shouldExtract']> = [ + plugin.config['~hooks']?.schemas?.shouldExtract, + plugin.context.config.parser.hooks.schemas?.shouldExtract, + ]; function extractor(ctx: ProcessorContext): IR.SchemaObject { if (processor.hasEmitted(ctx.path)) { return ctx.schema; } - for (const hook of hooks) { - const result = hook?.shouldExtract?.(ctx); + for (const hook of extractorHooks) { + const result = typeof hook === 'boolean' ? hook : (hook?.(ctx) ?? false); if (result) { process({ namingAnchor: processor.context.anchor, diff --git a/packages/openapi-ts/src/plugins/zod/v3/walker.ts b/packages/openapi-ts/src/plugins/zod/v3/walker.ts index 452ec644e..17265ba25 100644 --- a/packages/openapi-ts/src/plugins/zod/v3/walker.ts +++ b/packages/openapi-ts/src/plugins/zod/v3/walker.ts @@ -30,7 +30,7 @@ export interface VisitorConfig { } export function createVisitor( - config: VisitorConfig, + config: VisitorConfig = {}, ): SchemaVisitor { const { schemaExtractor } = config; @@ -134,6 +134,12 @@ export function createVisitor( return walk(extracted, ctx); } } + if (schema.symbolRef) { + return { + expression: $(schema.symbolRef), + meta: defaultMeta(schema), + }; + } }, intersection(items, schemas, parentSchema, ctx) { const z = ctx.plugin.external('zod.z'); diff --git a/packages/openapi-ts/src/plugins/zod/v4/api.ts b/packages/openapi-ts/src/plugins/zod/v4/api.ts index 00ff1450f..7e3c84149 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/api.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/api.ts @@ -1,42 +1,120 @@ +import type { Symbol } from '@hey-api/codegen-core'; +import type { RequestSchemaContext, ResolvedRequestValidatorLayer } from '@hey-api/shared'; +import { requestValidatorLayers, resolveValidatorLayer } from '@hey-api/shared'; + import { $ } from '../../../ts-dsl'; import { identifiers } from '../constants'; -import type { ValidatorResolverContext } from '../resolvers'; +import type { + RequestValidatorResolverContext, + ResponseValidatorResolverContext, +} from '../resolvers'; +import type { Chain } from '../shared/chain'; +import { exportAst } from '../shared/export'; import type { ValidatorArgs } from '../shared/types'; +import { getDefaultRequestValidatorLayers } from '../shared/validator'; +import type { ZodPlugin } from '../types'; + +function emptyNode( + ctx: RequestValidatorResolverContext & { + layer: ResolvedRequestValidatorLayer; + }, +): Chain { + const { z } = ctx.symbols; + if (ctx.layer.whenEmpty === 'omit') { + throw new Error( + `Cannot create empty schema for layer "${ctx.layer.as}" with whenEmpty: 'omit'`, + ); + } + if (ctx.layer.whenEmpty === 'strict') { + return $(z).attr(identifiers.never).call(); + } + return $(z).attr(identifiers.object).call($.object()); +} + +function optionalNode( + ctx: RequestValidatorResolverContext & { + layer: ResolvedRequestValidatorLayer; + schema: Chain; + }, +): Chain { + if (!ctx.layer.optional) return ctx.schema; + return $(ctx.schema).attr(identifiers.optional).call(); +} + +function compositeNode(ctx: RequestValidatorResolverContext): Chain | undefined { + const { z } = ctx.symbols; + const obj = $.object(); + + const defaultValues = getDefaultRequestValidatorLayers(ctx.operation); + for (const key of requestValidatorLayers) { + const layer = resolveValidatorLayer(ctx.layers, key, defaultValues); + + const layerSchema = ctx.plugin.querySymbol({ + category: 'schema', + resource: 'operation', + resourceId: ctx.operation.id, + role: `request-${key}`, + tool: 'zod', + }); + + if (layerSchema) { + obj.prop(layer.as, ctx.nodes.optional({ ...ctx, layer, schema: $(layerSchema) })); + continue; + } + + if (layer.whenEmpty === 'omit') { + continue; + } + + const empty = ctx.nodes.empty({ ...ctx, layer }); + obj.prop(layer.as, ctx.nodes.optional({ ...ctx, layer, schema: empty })); + } + + if (obj.isEmpty) { + return; + } + + return $(z).attr(identifiers.object).call(obj); +} -const validatorResolver = (ctx: ValidatorResolverContext): ReturnType => { +function requestValidatorResolver( + ctx: RequestValidatorResolverContext, +): ReturnType { const { schema } = ctx.symbols; return $(schema).attr(identifiers.parseAsync).call('data').await().return(); -}; +} -export const createRequestValidatorV4 = ({ - operation, - plugin, -}: ValidatorArgs): ReturnType | undefined => { - const symbol = plugin.getSymbol({ - category: 'schema', - resource: 'operation', - resourceId: operation.id, - role: 'data', - tool: 'zod', - }); - if (!symbol) return; +function responseValidatorResolver( + ctx: ResponseValidatorResolverContext, +): ReturnType { + const { schema } = ctx.symbols; + return $(schema).attr(identifiers.parseAsync).call('data').await().return(); +} - const z = plugin.external('zod.z'); - const ctx: ValidatorResolverContext = { - $, - chain: { - current: $(z), - }, - operation, - plugin, - symbols: { - schema: symbol, - z, - }, - }; - const validator = plugin.config['~resolvers']?.validator; +function runRequestResolver( + ctx: RequestValidatorResolverContext, +): ReturnType | undefined { + const validator = ctx.plugin.config['~resolvers']?.validator; const resolver = typeof validator === 'function' ? validator : validator?.request; - const candidates = [resolver, validatorResolver]; + const candidates = [resolver, requestValidatorResolver]; + for (const candidate of candidates) { + const statements = candidate?.(ctx); + if (statements === null) return; + if (statements !== undefined) { + return $.func() + .async() + .param('data') + .do(...(statements instanceof Array ? statements : [statements])); + } + } +} + +function runResponseResolver( + ctx: ResponseValidatorResolverContext, +): ReturnType | undefined { + const validator = ctx.plugin.config['~resolvers']?.validator; + const resolver = typeof validator === 'function' ? validator : validator?.response; + const candidates = [resolver, responseValidatorResolver]; for (const candidate of candidates) { const statements = candidate?.(ctx); if (statements === null) return; @@ -47,14 +125,84 @@ export const createRequestValidatorV4 = ({ .do(...(statements instanceof Array ? statements : [statements])); } } - return; -}; +} + +function createRequestSchemaContext( + ctx: RequestSchemaContext, +): RequestValidatorResolverContext { + const { plugin } = ctx; + const z = plugin.external('zod.z'); + + return { + ...ctx, + $, + chain: { + current: $(z), + }, + nodes: { + composite: compositeNode, + empty: emptyNode, + optional: optionalNode, + }, + symbols: { + schema: $(''), + z, + }, + }; +} + +export function createRequestSchemaV4( + ctx: RequestSchemaContext, +): Symbol | Chain | undefined { + const { operation, plugin } = ctx; + const baseCtx = createRequestSchemaContext(ctx); + + const schema = baseCtx.nodes.composite(baseCtx); + if (!schema) return; + + if (!plugin.config.requests.shouldExtract({ operation })) { + return schema; + } + + return exportAst({ + final: { + expression: schema, + }, + meta: { + resource: 'operation', + resourceId: operation.id, + role: 'data', + }, + naming: plugin.config.requests, + namingAnchor: operation.id, + path: [], + plugin, + schema: {}, + }); +} + +export function createRequestValidatorV4( + ctx: RequestSchemaContext, +): ReturnType | undefined { + const symbolOrSchema = createRequestSchemaV4(ctx); + if (!symbolOrSchema) return; + + const baseCtx = createRequestSchemaContext(ctx); + const resolverCtx: RequestValidatorResolverContext = { + ...baseCtx, + symbols: { + ...baseCtx.symbols, + schema: symbolOrSchema, + }, + }; + return runRequestResolver(resolverCtx); +} -export const createResponseValidatorV4 = ({ +export function createResponseValidatorV4({ operation, plugin, -}: ValidatorArgs): ReturnType | undefined => { - const symbol = plugin.getSymbol({ +}: ValidatorArgs): ReturnType | undefined { + const symbol = plugin.querySymbol({ category: 'schema', resource: 'operation', resourceId: operation.id, @@ -64,7 +212,7 @@ export const createResponseValidatorV4 = ({ if (!symbol) return; const z = plugin.external('zod.z'); - const ctx: ValidatorResolverContext = { + const resolverCtx: ResponseValidatorResolverContext = { $, chain: { current: $(z), @@ -76,18 +224,5 @@ export const createResponseValidatorV4 = ({ z, }, }; - const validator = plugin.config['~resolvers']?.validator; - const resolver = typeof validator === 'function' ? validator : validator?.response; - const candidates = [resolver, validatorResolver]; - for (const candidate of candidates) { - const statements = candidate?.(ctx); - if (statements === null) return; - if (statements !== undefined) { - return $.func() - .async() - .param('data') - .do(...(statements instanceof Array ? statements : [statements])); - } - } - return; -}; + return runResponseResolver(resolverCtx); +} diff --git a/packages/openapi-ts/src/plugins/zod/v4/processor.ts b/packages/openapi-ts/src/plugins/zod/v4/processor.ts index b2fdb66ee..89e6166b9 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/processor.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/processor.ts @@ -1,5 +1,5 @@ import { ref } from '@hey-api/codegen-core'; -import type { IR } from '@hey-api/shared'; +import type { Hooks, IR } from '@hey-api/shared'; import { createSchemaProcessor, createSchemaWalker, pathToJsonPointer } from '@hey-api/shared'; import { exportAst } from '../shared/export'; @@ -11,15 +11,18 @@ import { createVisitor } from './walker'; export function createProcessor(plugin: ZodPlugin['Instance']): ProcessorResult { const processor = createSchemaProcessor(); - const hooks = [plugin.config['~hooks']?.schemas, plugin.context.config.parser.hooks.schemas]; + const extractorHooks: ReadonlyArray['shouldExtract']> = [ + plugin.config['~hooks']?.schemas?.shouldExtract, + plugin.context.config.parser.hooks.schemas?.shouldExtract, + ]; function extractor(ctx: ProcessorContext): IR.SchemaObject { if (processor.hasEmitted(ctx.path)) { return ctx.schema; } - for (const hook of hooks) { - const result = hook?.shouldExtract?.(ctx); + for (const hook of extractorHooks) { + const result = typeof hook === 'boolean' ? hook : (hook?.(ctx) ?? false); if (result) { process({ namingAnchor: processor.context.anchor, diff --git a/packages/openapi-ts/src/plugins/zod/v4/walker.ts b/packages/openapi-ts/src/plugins/zod/v4/walker.ts index 364bd31c1..fcf45afd5 100644 --- a/packages/openapi-ts/src/plugins/zod/v4/walker.ts +++ b/packages/openapi-ts/src/plugins/zod/v4/walker.ts @@ -30,7 +30,7 @@ export interface VisitorConfig { } export function createVisitor( - config: VisitorConfig, + config: VisitorConfig = {}, ): SchemaVisitor { const { schemaExtractor } = config; @@ -129,6 +129,12 @@ export function createVisitor( return walk(extracted, ctx); } } + if (schema.symbolRef) { + return { + expression: $(schema.symbolRef), + meta: defaultMeta(schema), + }; + } }, intersection(items, schemas, parentSchema, ctx) { const z = ctx.plugin.external('zod.z'); diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 4cf329cf6..c42c97805 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -110,6 +110,16 @@ export type { PluginContext, PluginNames, } from './plugins/types'; +export type { + DefaultRequestValidatorLayers, + DefaultValidatorLayers, + RequestSchemaContext, + RequestValidatorLayer, + RequestValidatorLayers, + ResolvedRequestValidatorLayer, + ValidatorLayers, +} from './plugins/validator'; +export { requestValidatorLayers, resolveValidatorLayer } from './plugins/validator'; export { findPackageJson, findTsConfigPath, loadPackageJson } from './tsConfig'; export type { Logs } from './types/logs'; export type { WatchValues } from './types/watch'; diff --git a/packages/shared/src/parser/hooks.ts b/packages/shared/src/parser/hooks.ts index e0e55b06e..aded4d142 100644 --- a/packages/shared/src/parser/hooks.ts +++ b/packages/shared/src/parser/hooks.ts @@ -174,8 +174,6 @@ export type Hooks = { * * This affects how schemas are processed and output. * - * **Default behavior:** No schemas are extracted. - * * @param ctx - The processing context for the schema. * @returns true to extract the schema, false to keep it inline, or undefined to fallback to default behavior. * @example @@ -188,7 +186,7 @@ export type Hooks = { * } * ``` */ - shouldExtract?: (ctx: SchemaProcessorContext) => boolean; + shouldExtract?: MaybeFunc<(ctx: SchemaProcessorContext) => boolean>; }; /** * Hooks specifically for overriding symbols behavior. diff --git a/packages/shared/src/plugins/shared/utils/instance.ts b/packages/shared/src/plugins/shared/utils/instance.ts index 55cadbe14..d662bf25c 100644 --- a/packages/shared/src/plugins/shared/utils/instance.ts +++ b/packages/shared/src/plugins/shared/utils/instance.ts @@ -296,10 +296,6 @@ export class PluginInstance { return plugin as any; } - getSymbol(identifier: SymbolIdentifier): Symbol | undefined { - return this.gen.symbols.get(identifier); - } - hooks = { operation: { isMutation: (operation: IR.OperationObject): boolean => diff --git a/packages/shared/src/plugins/validator.ts b/packages/shared/src/plugins/validator.ts new file mode 100644 index 000000000..a926a364d --- /dev/null +++ b/packages/shared/src/plugins/validator.ts @@ -0,0 +1,121 @@ +import type { IR } from '../ir/types'; +import type { PluginInstance } from './shared/utils/instance'; + +/** + * Configuration for a single validator layer (e.g. body, headers, path, query). + */ +export interface RequestValidatorLayer { + /** + * Output property name in the composite schema. + * + * @default Same as the layer name ('body', 'path', 'query') + */ + as?: string; + /** + * Wrap the layer schema in an optional modifier. + * + * @default true + */ + optional?: boolean; + /** + * Behavior when this layer has no schema defined. + * + * Can be: + * - `'strict'` — Generate a schema that rejects any value + * - `'passthrough'` — Generate a schema that accepts any object + * - `'omit'` — Exclude this property from the composite shape + * + * @default 'strict' + */ + whenEmpty?: 'strict' | 'passthrough' | 'omit'; +} + +/** + * A {@link RequestValidatorLayer} with all optional properties resolved to their required form. + */ +export type ResolvedRequestValidatorLayer = Required; + +/** + * A map from a set of layer keys to optional layer configuration objects. + * + * @template Keys - The union of layer key names. + * @template Layer - The shape of an individual layer configuration. + */ +export type ValidatorLayers = { + [K in Keys]?: Layer; +}; + +/** + * A map from a set of layer keys to fully-resolved (required) layer configuration objects. + * Represents the default fallback values used when a layer is not explicitly configured. + * + * @template Keys - The union of layer key names. + * @template Layer - The shape of an individual layer configuration. + */ +export type DefaultValidatorLayers = { + [K in Keys]: Required; +}; + +/** + * The ordered list of standard HTTP request layer keys. + */ +export const requestValidatorLayers = ['body', 'headers', 'path', 'query'] as const; + +/** + * Optional per-layer configuration for the standard HTTP request layers + * (body, headers, path, query). + */ +export type RequestValidatorLayers = ValidatorLayers< + (typeof requestValidatorLayers)[number], + RequestValidatorLayer +>; + +/** + * Required default configuration for all standard HTTP request layers + * (body, headers, path, query). + */ +export type DefaultRequestValidatorLayers = DefaultValidatorLayers< + (typeof requestValidatorLayers)[number], + RequestValidatorLayer +>; + +/** + * Context passed to request schema helpers. + * + * @template Plugin - The plugin instance type. + */ +export interface RequestSchemaContext { + /** + * Per-layer configuration. Omitted layers use defaults. + * + * @default { body: {}, headers: {}, path: {}, query: {} } + */ + layers?: RequestValidatorLayers; + /** The operation object. */ + operation: IR.OperationObject; + /** The plugin instance. */ + plugin: Plugin; +} + +/** + * Resolves the effective configuration for a single layer by merging the + * layer's defaults with any explicit overrides supplied in `layers`. + * + * @param layers - Optional map of per-layer overrides. + * @param key - The layer key to resolve. + * @param defaultValues - Required fallback values for every layer key. + * @returns The fully-resolved layer configuration. + */ +export function resolveValidatorLayer< + Layers extends Record, + Key extends keyof Layers, +>( + layers: Layers | undefined, + key: Key, + defaultValues: { [K in keyof Layers]-?: Required> }, +): Required> { + const override = Object.fromEntries( + Object.entries(layers?.[key] ?? {}).filter(([, v]) => v !== undefined), + ); + return { ...defaultValues[key], ...override }; +}