diff --git a/.changeset/chatty-owls-grow.md b/.changeset/chatty-owls-grow.md
new file mode 100644
index 000000000..329f4b707
--- /dev/null
+++ b/.changeset/chatty-owls-grow.md
@@ -0,0 +1,5 @@
+---
+"@kubb/swagger-tanstack-query": minor
+---
+
+useQuery with Zod validation
diff --git a/docs/plugins/swagger-tanstack-query/index.md b/docs/plugins/swagger-tanstack-query/index.md
index 5eb233ba8..f0f5e4e2c 100644
--- a/docs/plugins/swagger-tanstack-query/index.md
+++ b/docs/plugins/swagger-tanstack-query/index.md
@@ -365,6 +365,68 @@ export default defineConfig({
:::
+### parser
+
+Which parser can be used before returning the data to `@tanstack/query`.
+
+`'zod'` will use `@kubb/swagger-zod` to parse the data.
+
+::: info type
+
+::: code-group
+
+```typescript ['zod']
+export function getPetByIdQueryOptions() {
+ const queryKey = getPetByIdQueryKey(petId)
+ return {
+ queryKey,
+ queryFn: async () => {
+ const res = await client({
+ method: 'get',
+ url: `/pet/${petId}`,
+ })
+
+ return getPetByIdQueryResponseSchema.parse(res.data)
+ },
+ }
+}
+```
+
+:::
+
+::: info
+
+Type: `'zod'`
+
+::: code-group
+
+```typescript ['zod']
+import { defineConfig } from '@kubb/core'
+import createSwagger from '@kubb/swagger'
+import createSwaggerTanstackQuery from '@kubb/swagger-tanstack-query'
+import createSwaggerTS from '@kubb/swagger-ts'
+
+export default defineConfig({
+ input: {
+ path: './petStore.yaml',
+ },
+ output: {
+ path: './src/gen',
+ },
+ plugins: [
+ createSwagger({ output: false }),
+ createSwaggerTS({}),
+ createSwaggerTanstackQuery(
+ {
+ parser: 'zod',
+ },
+ ),
+ ],
+})
+```
+
+:::
+
### framework
Framework to be generated for.
diff --git a/examples/advanced/configs/kubb.config.ts b/examples/advanced/configs/kubb.config.ts
index 282b7e41f..60bbe88c9 100644
--- a/examples/advanced/configs/kubb.config.ts
+++ b/examples/advanced/configs/kubb.config.ts
@@ -84,6 +84,7 @@ export default defineConfig(async () => {
},
infinite: {},
dataReturnType: 'full',
+ parser: 'zod',
},
],
[
diff --git a/examples/advanced/src/gen/clients/hooks/petController/useFindPetsByStatus.ts b/examples/advanced/src/gen/clients/hooks/petController/useFindPetsByStatus.ts
index 8edfd71fe..ead69e771 100644
--- a/examples/advanced/src/gen/clients/hooks/petController/useFindPetsByStatus.ts
+++ b/examples/advanced/src/gen/clients/hooks/petController/useFindPetsByStatus.ts
@@ -1,3 +1,4 @@
+import { findPetsByStatusQueryResponseSchema } from '../../../zod/petController/findPetsByStatusSchema'
import client from '../../../../tanstack-query-client.ts'
import { useQuery, useInfiniteQuery } from '@tanstack/react-query'
import type { FindPetsByStatusQueryResponse, FindPetsByStatusQueryParams, FindPetsByStatus400 } from '../../../models/ts/petController/FindPetsByStatus'
@@ -41,7 +42,7 @@ export function findPetsByStatusQueryOptions addressSchema)).optional(),
-}).optional()
+})
diff --git a/examples/advanced/src/gen/zod/orderSchema.ts b/examples/advanced/src/gen/zod/orderSchema.ts
index 26d84dad9..3eb669ff8 100644
--- a/examples/advanced/src/gen/zod/orderSchema.ts
+++ b/examples/advanced/src/gen/zod/orderSchema.ts
@@ -8,4 +8,4 @@ export const orderSchema = z.object({
'status': z.enum([`placed`, `approved`, `delivered`]).describe(`Order Status`).optional(),
'http_status': z.enum([`ok`, `not_found`]).describe(`HTTP Status`).optional(),
'complete': z.boolean().optional(),
-}).optional()
+})
diff --git a/examples/advanced/src/gen/zod/petController/addPetSchema.ts b/examples/advanced/src/gen/zod/petController/addPetSchema.ts
index b9cccec02..f8c101de4 100644
--- a/examples/advanced/src/gen/zod/petController/addPetSchema.ts
+++ b/examples/advanced/src/gen/zod/petController/addPetSchema.ts
@@ -2,7 +2,7 @@ import { z } from 'zod'
import { addPetRequestSchema } from '../addPetRequestSchema'
import { petSchema } from '../petSchema'
-export const addPet405Schema = z.object({ 'code': z.number().optional(), 'message': z.string().optional() }).optional()
+export const addPet405Schema = z.object({ 'code': z.number().optional(), 'message': z.string().optional() })
/**
* @description Create a new pet in the store
diff --git a/examples/advanced/src/gen/zod/petController/deletePetSchema.ts b/examples/advanced/src/gen/zod/petController/deletePetSchema.ts
index bedb75f24..04030039b 100644
--- a/examples/advanced/src/gen/zod/petController/deletePetSchema.ts
+++ b/examples/advanced/src/gen/zod/petController/deletePetSchema.ts
@@ -4,6 +4,6 @@ import { z } from 'zod'
* @description Invalid pet value
*/
export const deletePet400Schema = z.any()
-export const deletePetHeaderParamsSchema = z.object({ 'api_key': z.string().optional() }).optional()
+export const deletePetHeaderParamsSchema = z.object({ 'api_key': z.string().optional() })
export const deletePetMutationResponseSchema = z.any()
export const deletePetPathParamsSchema = z.object({ 'petId': z.number().describe(`Pet id to delete`) })
diff --git a/examples/advanced/src/gen/zod/petController/findPetsByStatusSchema.ts b/examples/advanced/src/gen/zod/petController/findPetsByStatusSchema.ts
index 1c4d2c4ff..e9c98eec4 100644
--- a/examples/advanced/src/gen/zod/petController/findPetsByStatusSchema.ts
+++ b/examples/advanced/src/gen/zod/petController/findPetsByStatusSchema.ts
@@ -7,7 +7,7 @@ import { petSchema } from '../petSchema'
export const findPetsByStatus400Schema = z.any()
export const findPetsByStatusQueryParamsSchema = z.object({
'status': z.enum([`available`, `pending`, `sold`]).default('available').describe(`Status values that need to be considered for filter`).optional(),
-}).optional()
+})
/**
* @description successful operation
diff --git a/examples/advanced/src/gen/zod/petController/findPetsByTagsSchema.ts b/examples/advanced/src/gen/zod/petController/findPetsByTagsSchema.ts
index ddf31d375..210f7b3ed 100644
--- a/examples/advanced/src/gen/zod/petController/findPetsByTagsSchema.ts
+++ b/examples/advanced/src/gen/zod/petController/findPetsByTagsSchema.ts
@@ -10,7 +10,7 @@ export const findPetsByTagsQueryParamsSchema = z.object({
'tags': z.array(z.string()).describe(`Tags to filter by`).optional(),
'page': z.string().describe(`to request with required page number or pagination`).optional(),
'pageSize': z.string().describe(`to request with required page size`).optional(),
-}).optional()
+})
/**
* @description successful operation
diff --git a/examples/advanced/src/gen/zod/petController/updatePetWithFormSchema.ts b/examples/advanced/src/gen/zod/petController/updatePetWithFormSchema.ts
index bab344794..8a0533383 100644
--- a/examples/advanced/src/gen/zod/petController/updatePetWithFormSchema.ts
+++ b/examples/advanced/src/gen/zod/petController/updatePetWithFormSchema.ts
@@ -9,4 +9,4 @@ export const updatePetWithFormPathParamsSchema = z.object({ 'petId': z.number().
export const updatePetWithFormQueryParamsSchema = z.object({
'name': z.string().describe(`Name of pet that needs to be updated`).optional(),
'status': z.string().describe(`Status of pet that needs to be updated`).optional(),
-}).optional()
+})
diff --git a/examples/advanced/src/gen/zod/petController/uploadFileSchema.ts b/examples/advanced/src/gen/zod/petController/uploadFileSchema.ts
index 6502c983e..1c27d28ed 100644
--- a/examples/advanced/src/gen/zod/petController/uploadFileSchema.ts
+++ b/examples/advanced/src/gen/zod/petController/uploadFileSchema.ts
@@ -3,7 +3,7 @@ import { apiResponseSchema } from '../apiResponseSchema'
export const uploadFileMutationRequestSchema = z.string()
export const uploadFilePathParamsSchema = z.object({ 'petId': z.number().describe(`ID of pet to update`) })
-export const uploadFileQueryParamsSchema = z.object({ 'additionalMetadata': z.string().describe(`Additional Metadata`).optional() }).optional()
+export const uploadFileQueryParamsSchema = z.object({ 'additionalMetadata': z.string().describe(`Additional Metadata`).optional() })
/**
* @description successful operation
diff --git a/examples/advanced/src/gen/zod/petNotFoundSchema.ts b/examples/advanced/src/gen/zod/petNotFoundSchema.ts
index 336558eb1..9a930ca89 100644
--- a/examples/advanced/src/gen/zod/petNotFoundSchema.ts
+++ b/examples/advanced/src/gen/zod/petNotFoundSchema.ts
@@ -1,3 +1,3 @@
import { z } from 'zod'
-export const petNotFoundSchema = z.object({ 'code': z.number().optional(), 'message': z.string().optional() }).optional()
+export const petNotFoundSchema = z.object({ 'code': z.number().optional(), 'message': z.string().optional() })
diff --git a/examples/advanced/src/gen/zod/petsController/createPetsSchema.ts b/examples/advanced/src/gen/zod/petsController/createPetsSchema.ts
index 2ae242ba1..d00f4ec68 100644
--- a/examples/advanced/src/gen/zod/petsController/createPetsSchema.ts
+++ b/examples/advanced/src/gen/zod/petsController/createPetsSchema.ts
@@ -9,7 +9,7 @@ export const createPetsHeaderParamsSchema = z.object({ 'X-EXAMPLE': z.enum([`ONE
export const createPetsMutationRequestSchema = z.object({ 'name': z.string(), 'tag': z.string() })
export const createPetsMutationResponseSchema = z.any()
export const createPetsPathParamsSchema = z.object({ 'uuid': z.string().describe(`UUID`) })
-export const createPetsQueryParamsSchema = z.object({ 'offset': z.number().describe(`Offset`).optional() }).optional()
+export const createPetsQueryParamsSchema = z.object({ 'offset': z.number().describe(`Offset`).optional() })
/**
* @description unexpected error
diff --git a/examples/advanced/src/gen/zod/tagSchema.ts b/examples/advanced/src/gen/zod/tagSchema.ts
index 1fa3bd6eb..2886a2b85 100644
--- a/examples/advanced/src/gen/zod/tagSchema.ts
+++ b/examples/advanced/src/gen/zod/tagSchema.ts
@@ -1,3 +1,3 @@
import { z } from 'zod'
-export const tagSchema = z.object({ 'id': z.number().optional(), 'name': z.string().optional() }).optional()
+export const tagSchema = z.object({ 'id': z.number().optional(), 'name': z.string().optional() })
diff --git a/examples/advanced/src/gen/zod/userController/loginUserSchema.ts b/examples/advanced/src/gen/zod/userController/loginUserSchema.ts
index b94e32d43..3aecd59c2 100644
--- a/examples/advanced/src/gen/zod/userController/loginUserSchema.ts
+++ b/examples/advanced/src/gen/zod/userController/loginUserSchema.ts
@@ -7,7 +7,7 @@ export const loginUser400Schema = z.any()
export const loginUserQueryParamsSchema = z.object({
'username': z.string().describe(`The user name for login`).optional(),
'password': z.string().describe(`The password for login in clear text`).optional(),
-}).optional()
+})
/**
* @description successful operation
diff --git a/examples/advanced/src/gen/zod/userSchema.ts b/examples/advanced/src/gen/zod/userSchema.ts
index 38d1366b7..a051dcf63 100644
--- a/examples/advanced/src/gen/zod/userSchema.ts
+++ b/examples/advanced/src/gen/zod/userSchema.ts
@@ -9,4 +9,4 @@ export const userSchema = z.object({
'password': z.string().optional(),
'phone': z.string().optional(),
'userStatus': z.number().describe(`User Status`).optional(),
-}).optional()
+})
diff --git a/examples/advanced/src/gen/zodios.ts b/examples/advanced/src/gen/zodios.ts
index 8f80a4bb8..7eef78bb5 100644
--- a/examples/advanced/src/gen/zodios.ts
+++ b/examples/advanced/src/gen/zodios.ts
@@ -74,7 +74,7 @@ export const endpoints = makeApi([
name: 'offset',
description: `Offset`,
type: 'Query',
- schema: createPetsQueryParamsSchema.unwrap().shape['offset'],
+ schema: createPetsQueryParamsSchema.shape['offset'],
},
{
name: 'X-EXAMPLE',
@@ -162,7 +162,7 @@ export const endpoints = makeApi([
name: 'status',
description: `Status values that need to be considered for filter`,
type: 'Query',
- schema: findPetsByStatusQueryParamsSchema.unwrap().shape['status'],
+ schema: findPetsByStatusQueryParamsSchema.shape['status'],
},
],
response: findPetsByStatusQueryResponseSchema,
@@ -184,19 +184,19 @@ export const endpoints = makeApi([
name: 'tags',
description: `Tags to filter by`,
type: 'Query',
- schema: findPetsByTagsQueryParamsSchema.unwrap().shape['tags'],
+ schema: findPetsByTagsQueryParamsSchema.shape['tags'],
},
{
name: 'page',
description: `to request with required page number or pagination`,
type: 'Query',
- schema: findPetsByTagsQueryParamsSchema.unwrap().shape['page'],
+ schema: findPetsByTagsQueryParamsSchema.shape['page'],
},
{
name: 'pageSize',
description: `to request with required page size`,
type: 'Query',
- schema: findPetsByTagsQueryParamsSchema.unwrap().shape['pageSize'],
+ schema: findPetsByTagsQueryParamsSchema.shape['pageSize'],
},
{
name: 'X-EXAMPLE',
@@ -257,13 +257,13 @@ export const endpoints = makeApi([
name: 'name',
description: `Name of pet that needs to be updated`,
type: 'Query',
- schema: updatePetWithFormQueryParamsSchema.unwrap().shape['name'],
+ schema: updatePetWithFormQueryParamsSchema.shape['name'],
},
{
name: 'status',
description: `Status of pet that needs to be updated`,
type: 'Query',
- schema: updatePetWithFormQueryParamsSchema.unwrap().shape['status'],
+ schema: updatePetWithFormQueryParamsSchema.shape['status'],
},
],
response: updatePetWithFormMutationResponseSchema,
@@ -291,7 +291,7 @@ export const endpoints = makeApi([
name: 'api_key',
description: ``,
type: 'Header',
- schema: deletePetHeaderParamsSchema.unwrap().shape['api_key'],
+ schema: deletePetHeaderParamsSchema.shape['api_key'],
},
],
response: deletePetMutationResponseSchema,
@@ -319,7 +319,7 @@ export const endpoints = makeApi([
name: 'additionalMetadata',
description: `Additional Metadata`,
type: 'Query',
- schema: uploadFileQueryParamsSchema.unwrap().shape['additionalMetadata'],
+ schema: uploadFileQueryParamsSchema.shape['additionalMetadata'],
},
{
name: 'UploadFileMutationRequest',
@@ -373,13 +373,13 @@ export const endpoints = makeApi([
name: 'username',
description: `The user name for login`,
type: 'Query',
- schema: loginUserQueryParamsSchema.unwrap().shape['username'],
+ schema: loginUserQueryParamsSchema.shape['username'],
},
{
name: 'password',
description: `The password for login in clear text`,
type: 'Query',
- schema: loginUserQueryParamsSchema.unwrap().shape['password'],
+ schema: loginUserQueryParamsSchema.shape['password'],
},
],
response: loginUserQueryResponseSchema,
diff --git a/examples/zod/src/gen/zod/addPetSchema.ts b/examples/zod/src/gen/zod/addPetSchema.ts
index 1985c34bc..278770e56 100644
--- a/examples/zod/src/gen/zod/addPetSchema.ts
+++ b/examples/zod/src/gen/zod/addPetSchema.ts
@@ -2,7 +2,7 @@ import { z } from 'zod'
import { addPetRequestSchema } from './addPetRequestSchema'
import { petSchema } from './petSchema'
-export const addPet405Schema = z.object({ code: z.number().optional(), message: z.string().optional() }).optional()
+export const addPet405Schema = z.object({ code: z.number().optional(), message: z.string().optional() })
/**
* @description Create a new pet in the store
diff --git a/examples/zod/src/gen/zod/addressSchema.ts b/examples/zod/src/gen/zod/addressSchema.ts
index 8a72460a7..c00dec91a 100644
--- a/examples/zod/src/gen/zod/addressSchema.ts
+++ b/examples/zod/src/gen/zod/addressSchema.ts
@@ -1,5 +1,3 @@
import { z } from 'zod'
-export const addressSchema = z
- .object({ street: z.string().optional(), city: z.string().optional(), state: z.string().optional(), zip: z.string().optional() })
- .optional()
+export const addressSchema = z.object({ street: z.string().optional(), city: z.string().optional(), state: z.string().optional(), zip: z.string().optional() })
diff --git a/examples/zod/src/gen/zod/apiResponseSchema.ts b/examples/zod/src/gen/zod/apiResponseSchema.ts
index 841d4e9f4..fed9929d2 100644
--- a/examples/zod/src/gen/zod/apiResponseSchema.ts
+++ b/examples/zod/src/gen/zod/apiResponseSchema.ts
@@ -1,3 +1,3 @@
import { z } from 'zod'
-export const apiResponseSchema = z.object({ code: z.number().optional(), type: z.string().optional(), message: z.string().optional() }).optional()
+export const apiResponseSchema = z.object({ code: z.number().optional(), type: z.string().optional(), message: z.string().optional() })
diff --git a/examples/zod/src/gen/zod/categorySchema.ts b/examples/zod/src/gen/zod/categorySchema.ts
index 5bd88583a..747b65f76 100644
--- a/examples/zod/src/gen/zod/categorySchema.ts
+++ b/examples/zod/src/gen/zod/categorySchema.ts
@@ -1,3 +1,3 @@
import { z } from 'zod'
-export const categorySchema = z.object({ id: z.number().optional(), name: z.string().optional() }).optional()
+export const categorySchema = z.object({ id: z.number().optional(), name: z.string().optional() })
diff --git a/examples/zod/src/gen/zod/customerSchema.ts b/examples/zod/src/gen/zod/customerSchema.ts
index f4efcab41..d3d77de43 100644
--- a/examples/zod/src/gen/zod/customerSchema.ts
+++ b/examples/zod/src/gen/zod/customerSchema.ts
@@ -1,6 +1,4 @@
import { addressSchema } from './addressSchema'
import { z } from 'zod'
-export const customerSchema = z
- .object({ id: z.number().optional(), username: z.string().optional(), address: z.array(z.lazy(() => addressSchema)).optional() })
- .optional()
+export const customerSchema = z.object({ id: z.number().optional(), username: z.string().optional(), address: z.array(z.lazy(() => addressSchema)).optional() })
diff --git a/examples/zod/src/gen/zod/deletePetSchema.ts b/examples/zod/src/gen/zod/deletePetSchema.ts
index 2ef4e34cc..07ef7890f 100644
--- a/examples/zod/src/gen/zod/deletePetSchema.ts
+++ b/examples/zod/src/gen/zod/deletePetSchema.ts
@@ -4,6 +4,6 @@ import { z } from 'zod'
* @description Invalid pet value
*/
export const deletePet400Schema = z.any()
-export const deletePetHeaderParamsSchema = z.object({ api_key: z.string().optional() }).optional()
+export const deletePetHeaderParamsSchema = z.object({ api_key: z.string().optional() })
export const deletePetMutationResponseSchema = z.any()
export const deletePetPathParamsSchema = z.object({ petId: z.number().describe(`Pet id to delete`) })
diff --git a/examples/zod/src/gen/zod/findPetsByStatusSchema.ts b/examples/zod/src/gen/zod/findPetsByStatusSchema.ts
index 2e73e8560..da67b51c3 100644
--- a/examples/zod/src/gen/zod/findPetsByStatusSchema.ts
+++ b/examples/zod/src/gen/zod/findPetsByStatusSchema.ts
@@ -5,9 +5,9 @@ import { petSchema } from './petSchema'
* @description Invalid status value
*/
export const findPetsByStatus400Schema = z.any()
-export const findPetsByStatusQueryParamsSchema = z
- .object({ status: z.enum([`available`, `pending`, `sold`]).default('available').describe(`Status values that need to be considered for filter`).optional() })
- .optional()
+export const findPetsByStatusQueryParamsSchema = z.object({
+ status: z.enum([`available`, `pending`, `sold`]).default('available').describe(`Status values that need to be considered for filter`).optional(),
+})
/**
* @description successful operation
diff --git a/examples/zod/src/gen/zod/findPetsByTagsSchema.ts b/examples/zod/src/gen/zod/findPetsByTagsSchema.ts
index 7b2a04c41..b467f6896 100644
--- a/examples/zod/src/gen/zod/findPetsByTagsSchema.ts
+++ b/examples/zod/src/gen/zod/findPetsByTagsSchema.ts
@@ -5,13 +5,11 @@ import { petSchema } from './petSchema'
* @description Invalid tag value
*/
export const findPetsByTags400Schema = z.any()
-export const findPetsByTagsQueryParamsSchema = z
- .object({
- tags: z.array(z.string()).describe(`Tags to filter by`).optional(),
- page: z.string().describe(`to request with required page number or pagination`).optional(),
- pageSize: z.string().describe(`to request with required page size`).optional(),
- })
- .optional()
+export const findPetsByTagsQueryParamsSchema = z.object({
+ tags: z.array(z.string()).describe(`Tags to filter by`).optional(),
+ page: z.string().describe(`to request with required page number or pagination`).optional(),
+ pageSize: z.string().describe(`to request with required page size`).optional(),
+})
/**
* @description successful operation
diff --git a/examples/zod/src/gen/zod/getInventorySchema.ts b/examples/zod/src/gen/zod/getInventorySchema.ts
index 0d1c925ac..2bb41d50e 100644
--- a/examples/zod/src/gen/zod/getInventorySchema.ts
+++ b/examples/zod/src/gen/zod/getInventorySchema.ts
@@ -3,4 +3,4 @@ import { z } from 'zod'
/**
* @description successful operation
*/
-export const getInventoryQueryResponseSchema = z.object({}).catchall(z.number().min(-2147483648).max(2147483647)).optional()
+export const getInventoryQueryResponseSchema = z.object({}).catchall(z.number().min(-2147483648).max(2147483647))
diff --git a/examples/zod/src/gen/zod/loginUserSchema.ts b/examples/zod/src/gen/zod/loginUserSchema.ts
index 28ac9b174..ad825f17a 100644
--- a/examples/zod/src/gen/zod/loginUserSchema.ts
+++ b/examples/zod/src/gen/zod/loginUserSchema.ts
@@ -4,12 +4,10 @@ import { z } from 'zod'
* @description Invalid username/password supplied
*/
export const loginUser400Schema = z.any()
-export const loginUserQueryParamsSchema = z
- .object({
- username: z.string().describe(`The user name for login`).optional(),
- password: z.string().describe(`The password for login in clear text`).optional(),
- })
- .optional()
+export const loginUserQueryParamsSchema = z.object({
+ username: z.string().describe(`The user name for login`).optional(),
+ password: z.string().describe(`The password for login in clear text`).optional(),
+})
/**
* @description successful operation
diff --git a/examples/zod/src/gen/zod/orderSchema.ts b/examples/zod/src/gen/zod/orderSchema.ts
index b3b6e4ff1..a5daaac31 100644
--- a/examples/zod/src/gen/zod/orderSchema.ts
+++ b/examples/zod/src/gen/zod/orderSchema.ts
@@ -1,16 +1,14 @@
import { z } from 'zod'
-export const orderSchema = z
- .object({
- id: z.number().optional(),
- petId: z.number().optional(),
- quantity: z.number().optional(),
- shipDate: z.string().datetime().optional(),
- status: z.enum([`placed`, `approved`, `delivered`]).describe(`Order Status`).optional(),
- http_status: z
- .union([z.literal(200), z.literal(400), z.literal(500)])
- .describe(`HTTP Status`)
- .optional(),
- complete: z.boolean().optional(),
- })
- .optional()
+export const orderSchema = z.object({
+ id: z.number().optional(),
+ petId: z.number().optional(),
+ quantity: z.number().optional(),
+ shipDate: z.string().datetime().optional(),
+ status: z.enum([`placed`, `approved`, `delivered`]).describe(`Order Status`).optional(),
+ http_status: z
+ .union([z.literal(200), z.literal(400), z.literal(500)])
+ .describe(`HTTP Status`)
+ .optional(),
+ complete: z.boolean().optional(),
+})
diff --git a/examples/zod/src/gen/zod/petNotFoundSchema.ts b/examples/zod/src/gen/zod/petNotFoundSchema.ts
index d9a74a9e8..9151f5f71 100644
--- a/examples/zod/src/gen/zod/petNotFoundSchema.ts
+++ b/examples/zod/src/gen/zod/petNotFoundSchema.ts
@@ -1,3 +1,3 @@
import { z } from 'zod'
-export const petNotFoundSchema = z.object({ code: z.number().optional(), message: z.string().optional() }).optional()
+export const petNotFoundSchema = z.object({ code: z.number().optional(), message: z.string().optional() })
diff --git a/examples/zod/src/gen/zod/tagSchema.ts b/examples/zod/src/gen/zod/tagSchema.ts
index def7ccaaa..e96b64fe2 100644
--- a/examples/zod/src/gen/zod/tagSchema.ts
+++ b/examples/zod/src/gen/zod/tagSchema.ts
@@ -1,3 +1,3 @@
import { z } from 'zod'
-export const tagSchema = z.object({ id: z.number().optional(), name: z.string().optional() }).optional()
+export const tagSchema = z.object({ id: z.number().optional(), name: z.string().optional() })
diff --git a/examples/zod/src/gen/zod/updatePetWithFormSchema.ts b/examples/zod/src/gen/zod/updatePetWithFormSchema.ts
index fd33cddc5..050c716e7 100644
--- a/examples/zod/src/gen/zod/updatePetWithFormSchema.ts
+++ b/examples/zod/src/gen/zod/updatePetWithFormSchema.ts
@@ -6,9 +6,7 @@ import { z } from 'zod'
export const updatePetWithForm405Schema = z.any()
export const updatePetWithFormMutationResponseSchema = z.any()
export const updatePetWithFormPathParamsSchema = z.object({ petId: z.number().describe(`ID of pet that needs to be updated`) })
-export const updatePetWithFormQueryParamsSchema = z
- .object({
- name: z.string().describe(`Name of pet that needs to be updated`).optional(),
- status: z.string().describe(`Status of pet that needs to be updated`).optional(),
- })
- .optional()
+export const updatePetWithFormQueryParamsSchema = z.object({
+ name: z.string().describe(`Name of pet that needs to be updated`).optional(),
+ status: z.string().describe(`Status of pet that needs to be updated`).optional(),
+})
diff --git a/examples/zod/src/gen/zod/uploadFileSchema.ts b/examples/zod/src/gen/zod/uploadFileSchema.ts
index ce4c80037..8e19b84ea 100644
--- a/examples/zod/src/gen/zod/uploadFileSchema.ts
+++ b/examples/zod/src/gen/zod/uploadFileSchema.ts
@@ -3,7 +3,7 @@ import { apiResponseSchema } from './apiResponseSchema'
export const uploadFileMutationRequestSchema = z.string()
export const uploadFilePathParamsSchema = z.object({ petId: z.number().describe(`ID of pet to update`) })
-export const uploadFileQueryParamsSchema = z.object({ additionalMetadata: z.string().describe(`Additional Metadata`).optional() }).optional()
+export const uploadFileQueryParamsSchema = z.object({ additionalMetadata: z.string().describe(`Additional Metadata`).optional() })
/**
* @description successful operation
diff --git a/examples/zod/src/gen/zod/userSchema.ts b/examples/zod/src/gen/zod/userSchema.ts
index e23a94869..28fe8a997 100644
--- a/examples/zod/src/gen/zod/userSchema.ts
+++ b/examples/zod/src/gen/zod/userSchema.ts
@@ -1,14 +1,12 @@
import { z } from 'zod'
-export const userSchema = z
- .object({
- id: z.number().optional(),
- username: z.string().optional(),
- firstName: z.string().optional(),
- lastName: z.string().optional(),
- email: z.string().email().optional(),
- password: z.string().optional(),
- phone: z.string().optional(),
- userStatus: z.number().describe(`User Status`).optional(),
- })
- .optional()
+export const userSchema = z.object({
+ id: z.number().optional(),
+ username: z.string().optional(),
+ firstName: z.string().optional(),
+ lastName: z.string().optional(),
+ email: z.string().email().optional(),
+ password: z.string().optional(),
+ phone: z.string().optional(),
+ userStatus: z.number().describe(`User Status`).optional(),
+})
diff --git a/examples/zodios/src/gen/zod/addPetSchema.ts b/examples/zodios/src/gen/zod/addPetSchema.ts
index 1985c34bc..278770e56 100644
--- a/examples/zodios/src/gen/zod/addPetSchema.ts
+++ b/examples/zodios/src/gen/zod/addPetSchema.ts
@@ -2,7 +2,7 @@ import { z } from 'zod'
import { addPetRequestSchema } from './addPetRequestSchema'
import { petSchema } from './petSchema'
-export const addPet405Schema = z.object({ code: z.number().optional(), message: z.string().optional() }).optional()
+export const addPet405Schema = z.object({ code: z.number().optional(), message: z.string().optional() })
/**
* @description Create a new pet in the store
diff --git a/examples/zodios/src/gen/zod/addressSchema.ts b/examples/zodios/src/gen/zod/addressSchema.ts
index 8a72460a7..c00dec91a 100644
--- a/examples/zodios/src/gen/zod/addressSchema.ts
+++ b/examples/zodios/src/gen/zod/addressSchema.ts
@@ -1,5 +1,3 @@
import { z } from 'zod'
-export const addressSchema = z
- .object({ street: z.string().optional(), city: z.string().optional(), state: z.string().optional(), zip: z.string().optional() })
- .optional()
+export const addressSchema = z.object({ street: z.string().optional(), city: z.string().optional(), state: z.string().optional(), zip: z.string().optional() })
diff --git a/examples/zodios/src/gen/zod/apiResponseSchema.ts b/examples/zodios/src/gen/zod/apiResponseSchema.ts
index 841d4e9f4..fed9929d2 100644
--- a/examples/zodios/src/gen/zod/apiResponseSchema.ts
+++ b/examples/zodios/src/gen/zod/apiResponseSchema.ts
@@ -1,3 +1,3 @@
import { z } from 'zod'
-export const apiResponseSchema = z.object({ code: z.number().optional(), type: z.string().optional(), message: z.string().optional() }).optional()
+export const apiResponseSchema = z.object({ code: z.number().optional(), type: z.string().optional(), message: z.string().optional() })
diff --git a/examples/zodios/src/gen/zod/categorySchema.ts b/examples/zodios/src/gen/zod/categorySchema.ts
index 5bd88583a..747b65f76 100644
--- a/examples/zodios/src/gen/zod/categorySchema.ts
+++ b/examples/zodios/src/gen/zod/categorySchema.ts
@@ -1,3 +1,3 @@
import { z } from 'zod'
-export const categorySchema = z.object({ id: z.number().optional(), name: z.string().optional() }).optional()
+export const categorySchema = z.object({ id: z.number().optional(), name: z.string().optional() })
diff --git a/examples/zodios/src/gen/zod/customerSchema.ts b/examples/zodios/src/gen/zod/customerSchema.ts
index f4efcab41..d3d77de43 100644
--- a/examples/zodios/src/gen/zod/customerSchema.ts
+++ b/examples/zodios/src/gen/zod/customerSchema.ts
@@ -1,6 +1,4 @@
import { addressSchema } from './addressSchema'
import { z } from 'zod'
-export const customerSchema = z
- .object({ id: z.number().optional(), username: z.string().optional(), address: z.array(z.lazy(() => addressSchema)).optional() })
- .optional()
+export const customerSchema = z.object({ id: z.number().optional(), username: z.string().optional(), address: z.array(z.lazy(() => addressSchema)).optional() })
diff --git a/examples/zodios/src/gen/zod/deletePetSchema.ts b/examples/zodios/src/gen/zod/deletePetSchema.ts
index 2ef4e34cc..07ef7890f 100644
--- a/examples/zodios/src/gen/zod/deletePetSchema.ts
+++ b/examples/zodios/src/gen/zod/deletePetSchema.ts
@@ -4,6 +4,6 @@ import { z } from 'zod'
* @description Invalid pet value
*/
export const deletePet400Schema = z.any()
-export const deletePetHeaderParamsSchema = z.object({ api_key: z.string().optional() }).optional()
+export const deletePetHeaderParamsSchema = z.object({ api_key: z.string().optional() })
export const deletePetMutationResponseSchema = z.any()
export const deletePetPathParamsSchema = z.object({ petId: z.number().describe(`Pet id to delete`) })
diff --git a/examples/zodios/src/gen/zod/findPetsByStatusSchema.ts b/examples/zodios/src/gen/zod/findPetsByStatusSchema.ts
index 2e73e8560..da67b51c3 100644
--- a/examples/zodios/src/gen/zod/findPetsByStatusSchema.ts
+++ b/examples/zodios/src/gen/zod/findPetsByStatusSchema.ts
@@ -5,9 +5,9 @@ import { petSchema } from './petSchema'
* @description Invalid status value
*/
export const findPetsByStatus400Schema = z.any()
-export const findPetsByStatusQueryParamsSchema = z
- .object({ status: z.enum([`available`, `pending`, `sold`]).default('available').describe(`Status values that need to be considered for filter`).optional() })
- .optional()
+export const findPetsByStatusQueryParamsSchema = z.object({
+ status: z.enum([`available`, `pending`, `sold`]).default('available').describe(`Status values that need to be considered for filter`).optional(),
+})
/**
* @description successful operation
diff --git a/examples/zodios/src/gen/zod/findPetsByTagsSchema.ts b/examples/zodios/src/gen/zod/findPetsByTagsSchema.ts
index 7b2a04c41..b467f6896 100644
--- a/examples/zodios/src/gen/zod/findPetsByTagsSchema.ts
+++ b/examples/zodios/src/gen/zod/findPetsByTagsSchema.ts
@@ -5,13 +5,11 @@ import { petSchema } from './petSchema'
* @description Invalid tag value
*/
export const findPetsByTags400Schema = z.any()
-export const findPetsByTagsQueryParamsSchema = z
- .object({
- tags: z.array(z.string()).describe(`Tags to filter by`).optional(),
- page: z.string().describe(`to request with required page number or pagination`).optional(),
- pageSize: z.string().describe(`to request with required page size`).optional(),
- })
- .optional()
+export const findPetsByTagsQueryParamsSchema = z.object({
+ tags: z.array(z.string()).describe(`Tags to filter by`).optional(),
+ page: z.string().describe(`to request with required page number or pagination`).optional(),
+ pageSize: z.string().describe(`to request with required page size`).optional(),
+})
/**
* @description successful operation
diff --git a/examples/zodios/src/gen/zod/getInventorySchema.ts b/examples/zodios/src/gen/zod/getInventorySchema.ts
index 0d1c925ac..2bb41d50e 100644
--- a/examples/zodios/src/gen/zod/getInventorySchema.ts
+++ b/examples/zodios/src/gen/zod/getInventorySchema.ts
@@ -3,4 +3,4 @@ import { z } from 'zod'
/**
* @description successful operation
*/
-export const getInventoryQueryResponseSchema = z.object({}).catchall(z.number().min(-2147483648).max(2147483647)).optional()
+export const getInventoryQueryResponseSchema = z.object({}).catchall(z.number().min(-2147483648).max(2147483647))
diff --git a/examples/zodios/src/gen/zod/loginUserSchema.ts b/examples/zodios/src/gen/zod/loginUserSchema.ts
index 28ac9b174..ad825f17a 100644
--- a/examples/zodios/src/gen/zod/loginUserSchema.ts
+++ b/examples/zodios/src/gen/zod/loginUserSchema.ts
@@ -4,12 +4,10 @@ import { z } from 'zod'
* @description Invalid username/password supplied
*/
export const loginUser400Schema = z.any()
-export const loginUserQueryParamsSchema = z
- .object({
- username: z.string().describe(`The user name for login`).optional(),
- password: z.string().describe(`The password for login in clear text`).optional(),
- })
- .optional()
+export const loginUserQueryParamsSchema = z.object({
+ username: z.string().describe(`The user name for login`).optional(),
+ password: z.string().describe(`The password for login in clear text`).optional(),
+})
/**
* @description successful operation
diff --git a/examples/zodios/src/gen/zod/orderSchema.ts b/examples/zodios/src/gen/zod/orderSchema.ts
index b3b6e4ff1..a5daaac31 100644
--- a/examples/zodios/src/gen/zod/orderSchema.ts
+++ b/examples/zodios/src/gen/zod/orderSchema.ts
@@ -1,16 +1,14 @@
import { z } from 'zod'
-export const orderSchema = z
- .object({
- id: z.number().optional(),
- petId: z.number().optional(),
- quantity: z.number().optional(),
- shipDate: z.string().datetime().optional(),
- status: z.enum([`placed`, `approved`, `delivered`]).describe(`Order Status`).optional(),
- http_status: z
- .union([z.literal(200), z.literal(400), z.literal(500)])
- .describe(`HTTP Status`)
- .optional(),
- complete: z.boolean().optional(),
- })
- .optional()
+export const orderSchema = z.object({
+ id: z.number().optional(),
+ petId: z.number().optional(),
+ quantity: z.number().optional(),
+ shipDate: z.string().datetime().optional(),
+ status: z.enum([`placed`, `approved`, `delivered`]).describe(`Order Status`).optional(),
+ http_status: z
+ .union([z.literal(200), z.literal(400), z.literal(500)])
+ .describe(`HTTP Status`)
+ .optional(),
+ complete: z.boolean().optional(),
+})
diff --git a/examples/zodios/src/gen/zod/petNotFoundSchema.ts b/examples/zodios/src/gen/zod/petNotFoundSchema.ts
index d9a74a9e8..9151f5f71 100644
--- a/examples/zodios/src/gen/zod/petNotFoundSchema.ts
+++ b/examples/zodios/src/gen/zod/petNotFoundSchema.ts
@@ -1,3 +1,3 @@
import { z } from 'zod'
-export const petNotFoundSchema = z.object({ code: z.number().optional(), message: z.string().optional() }).optional()
+export const petNotFoundSchema = z.object({ code: z.number().optional(), message: z.string().optional() })
diff --git a/examples/zodios/src/gen/zod/tagSchema.ts b/examples/zodios/src/gen/zod/tagSchema.ts
index def7ccaaa..e96b64fe2 100644
--- a/examples/zodios/src/gen/zod/tagSchema.ts
+++ b/examples/zodios/src/gen/zod/tagSchema.ts
@@ -1,3 +1,3 @@
import { z } from 'zod'
-export const tagSchema = z.object({ id: z.number().optional(), name: z.string().optional() }).optional()
+export const tagSchema = z.object({ id: z.number().optional(), name: z.string().optional() })
diff --git a/examples/zodios/src/gen/zod/updatePetWithFormSchema.ts b/examples/zodios/src/gen/zod/updatePetWithFormSchema.ts
index fd33cddc5..050c716e7 100644
--- a/examples/zodios/src/gen/zod/updatePetWithFormSchema.ts
+++ b/examples/zodios/src/gen/zod/updatePetWithFormSchema.ts
@@ -6,9 +6,7 @@ import { z } from 'zod'
export const updatePetWithForm405Schema = z.any()
export const updatePetWithFormMutationResponseSchema = z.any()
export const updatePetWithFormPathParamsSchema = z.object({ petId: z.number().describe(`ID of pet that needs to be updated`) })
-export const updatePetWithFormQueryParamsSchema = z
- .object({
- name: z.string().describe(`Name of pet that needs to be updated`).optional(),
- status: z.string().describe(`Status of pet that needs to be updated`).optional(),
- })
- .optional()
+export const updatePetWithFormQueryParamsSchema = z.object({
+ name: z.string().describe(`Name of pet that needs to be updated`).optional(),
+ status: z.string().describe(`Status of pet that needs to be updated`).optional(),
+})
diff --git a/examples/zodios/src/gen/zod/uploadFileSchema.ts b/examples/zodios/src/gen/zod/uploadFileSchema.ts
index ce4c80037..8e19b84ea 100644
--- a/examples/zodios/src/gen/zod/uploadFileSchema.ts
+++ b/examples/zodios/src/gen/zod/uploadFileSchema.ts
@@ -3,7 +3,7 @@ import { apiResponseSchema } from './apiResponseSchema'
export const uploadFileMutationRequestSchema = z.string()
export const uploadFilePathParamsSchema = z.object({ petId: z.number().describe(`ID of pet to update`) })
-export const uploadFileQueryParamsSchema = z.object({ additionalMetadata: z.string().describe(`Additional Metadata`).optional() }).optional()
+export const uploadFileQueryParamsSchema = z.object({ additionalMetadata: z.string().describe(`Additional Metadata`).optional() })
/**
* @description successful operation
diff --git a/examples/zodios/src/gen/zod/userSchema.ts b/examples/zodios/src/gen/zod/userSchema.ts
index e23a94869..28fe8a997 100644
--- a/examples/zodios/src/gen/zod/userSchema.ts
+++ b/examples/zodios/src/gen/zod/userSchema.ts
@@ -1,14 +1,12 @@
import { z } from 'zod'
-export const userSchema = z
- .object({
- id: z.number().optional(),
- username: z.string().optional(),
- firstName: z.string().optional(),
- lastName: z.string().optional(),
- email: z.string().email().optional(),
- password: z.string().optional(),
- phone: z.string().optional(),
- userStatus: z.number().describe(`User Status`).optional(),
- })
- .optional()
+export const userSchema = z.object({
+ id: z.number().optional(),
+ username: z.string().optional(),
+ firstName: z.string().optional(),
+ lastName: z.string().optional(),
+ email: z.string().email().optional(),
+ password: z.string().optional(),
+ phone: z.string().optional(),
+ userStatus: z.number().describe(`User Status`).optional(),
+})
diff --git a/examples/zodios/src/gen/zodios.ts b/examples/zodios/src/gen/zodios.ts
index c60e02ec9..7adc07b39 100644
--- a/examples/zodios/src/gen/zodios.ts
+++ b/examples/zodios/src/gen/zodios.ts
@@ -101,7 +101,7 @@ export const endpoints = makeApi([
name: 'status',
description: `Status values that need to be considered for filter`,
type: 'Query',
- schema: findPetsByStatusQueryParamsSchema.unwrap().shape['status'],
+ schema: findPetsByStatusQueryParamsSchema.shape['status'],
},
],
response: findPetsByStatusQueryResponseSchema,
@@ -123,19 +123,19 @@ export const endpoints = makeApi([
name: 'tags',
description: `Tags to filter by`,
type: 'Query',
- schema: findPetsByTagsQueryParamsSchema.unwrap().shape['tags'],
+ schema: findPetsByTagsQueryParamsSchema.shape['tags'],
},
{
name: 'page',
description: `to request with required page number or pagination`,
type: 'Query',
- schema: findPetsByTagsQueryParamsSchema.unwrap().shape['page'],
+ schema: findPetsByTagsQueryParamsSchema.shape['page'],
},
{
name: 'pageSize',
description: `to request with required page size`,
type: 'Query',
- schema: findPetsByTagsQueryParamsSchema.unwrap().shape['pageSize'],
+ schema: findPetsByTagsQueryParamsSchema.shape['pageSize'],
},
],
response: findPetsByTagsQueryResponseSchema,
@@ -190,13 +190,13 @@ export const endpoints = makeApi([
name: 'name',
description: `Name of pet that needs to be updated`,
type: 'Query',
- schema: updatePetWithFormQueryParamsSchema.unwrap().shape['name'],
+ schema: updatePetWithFormQueryParamsSchema.shape['name'],
},
{
name: 'status',
description: `Status of pet that needs to be updated`,
type: 'Query',
- schema: updatePetWithFormQueryParamsSchema.unwrap().shape['status'],
+ schema: updatePetWithFormQueryParamsSchema.shape['status'],
},
],
response: updatePetWithFormMutationResponseSchema,
@@ -224,7 +224,7 @@ export const endpoints = makeApi([
name: 'api_key',
description: ``,
type: 'Header',
- schema: deletePetHeaderParamsSchema.unwrap().shape['api_key'],
+ schema: deletePetHeaderParamsSchema.shape['api_key'],
},
],
response: deletePetMutationResponseSchema,
@@ -252,7 +252,7 @@ export const endpoints = makeApi([
name: 'additionalMetadata',
description: `Additional Metadata`,
type: 'Query',
- schema: uploadFileQueryParamsSchema.unwrap().shape['additionalMetadata'],
+ schema: uploadFileQueryParamsSchema.shape['additionalMetadata'],
},
{
name: 'UploadFileMutationRequest',
@@ -413,13 +413,13 @@ export const endpoints = makeApi([
name: 'username',
description: `The user name for login`,
type: 'Query',
- schema: loginUserQueryParamsSchema.unwrap().shape['username'],
+ schema: loginUserQueryParamsSchema.shape['username'],
},
{
name: 'password',
description: `The password for login in clear text`,
type: 'Query',
- schema: loginUserQueryParamsSchema.unwrap().shape['password'],
+ schema: loginUserQueryParamsSchema.shape['password'],
},
],
response: loginUserQueryResponseSchema,
diff --git a/packages/swagger-tanstack-query/package.json b/packages/swagger-tanstack-query/package.json
index faaab2092..66d09800e 100644
--- a/packages/swagger-tanstack-query/package.json
+++ b/packages/swagger-tanstack-query/package.json
@@ -63,7 +63,8 @@
"@kubb/react": "workspace:*",
"@kubb/swagger": "workspace:*",
"@kubb/swagger-client": "workspace:*",
- "@kubb/swagger-ts": "workspace:*"
+ "@kubb/swagger-ts": "workspace:*",
+ "@kubb/swagger-zod": "workspace:*"
},
"devDependencies": {
"@kubb/eslint-config": "workspace:*",
diff --git a/packages/swagger-tanstack-query/src/components/Query.tsx b/packages/swagger-tanstack-query/src/components/Query.tsx
index a7f2ff99a..43a419b8c 100644
--- a/packages/swagger-tanstack-query/src/components/Query.tsx
+++ b/packages/swagger-tanstack-query/src/components/Query.tsx
@@ -5,6 +5,7 @@ import { File, Function, usePlugin, useResolveName } from '@kubb/react'
import { useOperation, useOperationFile, useOperationName, useSchemas } from '@kubb/swagger/hooks'
import { getASTParams, getComments, getParams, isRequired } from '@kubb/swagger/utils'
import { pluginKey as swaggerTsPluginKey } from '@kubb/swagger-ts'
+import { pluginKey as swaggerZodPluginKey } from '@kubb/swagger-zod'
import { getImportNames } from '../utils.ts'
import { QueryImports } from './QueryImports.tsx'
@@ -430,10 +431,14 @@ type FileProps = {
}
Query.File = function({ templates, imports = QueryImports.templates }: FileProps): ReactNode {
- const { options: { client: { importPath }, framework, infinite, suspense } } = usePlugin()
+ const { options: { client: { importPath }, framework, infinite, suspense, parser } } = usePlugin()
const schemas = useSchemas()
const file = useOperationFile()
const fileType = useOperationFile({ pluginKey: swaggerTsPluginKey })
+
+ const fileZodSchemas = useOperationFile({ pluginKey: swaggerZodPluginKey })
+ const zodResponseName = useResolveName({ name: schemas.response.name, pluginKey: swaggerZodPluginKey, type: 'function' })
+
const factoryName = useOperationName({ type: 'type' })
const importNames = getImportNames()
@@ -453,6 +458,7 @@ Query.File = function({ templates, imports = QueryImports.templates }: FileProps
path={file.path}
meta={file.meta}
>
+ {parser === 'zod' && }
+ parser: string | undefined
}
function Template({
@@ -59,6 +61,7 @@ function Template({
client,
infinite,
dataReturnType,
+ parser,
}: TemplateProps): ReactNode {
const isV5 = new PackageManager().isValidSync(/@tanstack/, '>=5')
@@ -100,6 +103,12 @@ function Template({
const resolvedClientOptions = `${transformers.createIndent(4)}${clientOptions.join(`,\n${transformers.createIndent(4)}`)}`
const resolvedQueryOptions = `${transformers.createIndent(4)}${queryOptions.join(`,\n${transformers.createIndent(4)}`)}`
+ let returnRes = parser ? `return ${parser}(res.data)` : `return res.data`
+
+ if (dataReturnType === 'full') {
+ returnRes = parser ? `return {...res, data: ${parser}(res.data)}` : `return res`
+ }
+
if (infinite) {
if (isV5) {
return (
@@ -115,7 +124,7 @@ function Template({
${resolvedClientOptions}
})
- return ${dataReturnType === 'data' ? 'res.data' : 'res'}
+ ${returnRes}
},
${resolvedQueryOptions}
})
@@ -138,7 +147,7 @@ function Template({
${resolvedClientOptions}
})
- return ${dataReturnType === 'data' ? 'res.data' : 'res'}
+ ${returnRes}
},
${resolvedQueryOptions}
}
@@ -162,7 +171,7 @@ function Template({
${resolvedClientOptions}
})
- return ${dataReturnType === 'data' ? 'res.data' : 'res'}
+ ${returnRes}
},
${resolvedQueryOptions}
})
@@ -185,7 +194,7 @@ function Template({
${resolvedClientOptions}
})
- return ${dataReturnType === 'data' ? 'res.data' : 'res'}
+ ${returnRes}
},
${resolvedQueryOptions}
}
@@ -314,7 +323,7 @@ type Props = {
}
export function QueryOptions({ factory, infinite, suspense, resultType, dataReturnType, Template = defaultTemplates.react }: Props): ReactNode {
- const { key: pluginKey } = usePlugin()
+ const { key: pluginKey, options: { parser } } = usePlugin()
const schemas = useSchemas()
const operation = useOperation()
@@ -327,6 +336,8 @@ export function QueryOptions({ factory, infinite, suspense, resultType, dataRetu
pluginKey,
})
+ const zodResponseName = useResolveName({ name: schemas.response.name, pluginKey: swaggerZodPluginKey, type: 'function' })
+
const generics = new FunctionParams()
const params = new FunctionParams()
@@ -390,6 +401,7 @@ export function QueryOptions({ factory, infinite, suspense, resultType, dataRetu
hook={hook}
infinite={infinite}
dataReturnType={dataReturnType}
+ parser={parser === 'zod' ? `${zodResponseName}.parse` : undefined}
context={{
factory,
queryKey,
diff --git a/packages/swagger-tanstack-query/src/plugin.ts b/packages/swagger-tanstack-query/src/plugin.ts
index 9413d6624..e555da9ce 100644
--- a/packages/swagger-tanstack-query/src/plugin.ts
+++ b/packages/swagger-tanstack-query/src/plugin.ts
@@ -6,6 +6,7 @@ import { renderTemplate } from '@kubb/core/utils'
import { pluginName as swaggerPluginName } from '@kubb/swagger'
import { getGroupedByTagFiles } from '@kubb/swagger/utils'
import { pluginName as swaggerTsPluginName } from '@kubb/swagger-ts'
+import { pluginName as swaggerZodPluginName } from '@kubb/swagger-zod'
import { Mutation, Query, QueryKey, QueryOptions } from './components/index.ts'
import { OperationGenerator } from './OperationGenerator.tsx'
@@ -25,6 +26,7 @@ export const definePlugin = createPlugin((options) => {
include,
override = [],
framework = 'react',
+ parser,
suspense,
infinite,
transformers = {},
@@ -58,8 +60,9 @@ export const definePlugin = createPlugin((options) => {
queryKey: QueryKey.templates,
...templates,
},
+ parser,
},
- pre: [swaggerPluginName, swaggerTsPluginName],
+ pre: [swaggerPluginName, swaggerTsPluginName, parser === 'zod' ? swaggerZodPluginName : undefined].filter(Boolean),
resolvePath(baseName, directory, options) {
const root = path.resolve(this.config.root, this.config.output.path)
const mode = FileManager.getMode(path.resolve(root, output.path))
diff --git a/packages/swagger-tanstack-query/src/types.ts b/packages/swagger-tanstack-query/src/types.ts
index ca0c32d53..ed64341ef 100644
--- a/packages/swagger-tanstack-query/src/types.ts
+++ b/packages/swagger-tanstack-query/src/types.ts
@@ -106,6 +106,11 @@ export type Options = {
* @private
*/
dataReturnType?: 'data' | 'full'
+ /**
+ * Which parser can be used before returning the data to `@tanstack/query`.
+ * `'zod'` will use `@kubb/swagger-zod` to parse the data.
+ */
+ parser?: 'zod'
/**
* Array containing exclude parameters to exclude/skip tags/operations/methods/paths.
*/
@@ -149,6 +154,7 @@ type ResolvedOptions = {
framework: NonNullable
client: Required>
dataReturnType: NonNullable
+ parser: PluginOptions['options']['parser']
/**
* Only used of infinite
*/
diff --git a/packages/swagger-zod/src/ZodBuilder.ts b/packages/swagger-zod/src/ZodBuilder.ts
index 6abd468db..03135d817 100644
--- a/packages/swagger-zod/src/ZodBuilder.ts
+++ b/packages/swagger-zod/src/ZodBuilder.ts
@@ -18,11 +18,14 @@ export class ZodBuilder extends OasBuilder {
.sort(transformers.nameSorter)
.map((operationSchema) => {
const generator = new ZodGenerator(this.options, this.context)
+ const required = Array.isArray(operationSchema.schema?.required) ? !!operationSchema.schema.required.length : !!operationSchema.schema?.required
+
const sources = generator.build({
schema: operationSchema.schema,
baseName: operationSchema.name,
description: operationSchema.description,
keysToOmit: operationSchema.keysToOmit,
+ optional: !required && !!operationSchema.name.includes('Params'),
})
importMeta.push(...generator.imports)
diff --git a/packages/swagger-zod/src/ZodGenerator.ts b/packages/swagger-zod/src/ZodGenerator.ts
index 8663e3ac2..b5d8cbe43 100644
--- a/packages/swagger-zod/src/ZodGenerator.ts
+++ b/packages/swagger-zod/src/ZodGenerator.ts
@@ -33,11 +33,13 @@ export class ZodGenerator extends Generator array
return [{ keyword: zodKeywords.array, args: this.getTypeFromSchema(schema.items as OasTypes.SchemaObject, baseName) }, ...baseItems]
}
@@ -320,11 +324,6 @@ export class ZodGenerator extends Generator literal type
- if (!schema.required?.length) {
- baseItems.push({ keyword: zodKeywords.optional })
- }
-
return [...this.#getTypeFromProperties(schema, baseName), ...baseItems]
}
diff --git a/packages/swagger-zod/src/__snapshots__/ZodGenerator.test.ts.snap b/packages/swagger-zod/src/__snapshots__/ZodGenerator.test.ts.snap
index b93dbbbf8..d82e63195 100644
--- a/packages/swagger-zod/src/__snapshots__/ZodGenerator.test.ts.snap
+++ b/packages/swagger-zod/src/__snapshots__/ZodGenerator.test.ts.snap
@@ -2,7 +2,7 @@
exports[`ZodGenerator PetStore > generate schema for OptionalPet 1`] = `
[
- "export const OptionalPet = z.object({"id": z.number().optional(),"name": z.string().optional(),"tag": z.string().optional()}).optional();",
+ "export const OptionalPet = z.object({"id": z.number().optional(),"name": z.string().optional(),"tag": z.string().optional()});",
]
`;
@@ -80,13 +80,7 @@ exports[`ZodGenerator enums > generate x-enumNames types 1`] = `
exports[`ZodGenerator lazy > generate schema for Example 1`] = `
[
- "export const Example = z.object({"nestedExamples": z.lazy(() => Example).optional()}).optional();",
-]
-`;
-
-exports[`ZodGenerator lazy import > generate schema for Example 1`] = `
-[
- "export const Example = z.object({"nestedExamples": z.lazy(() => Example).optional()}).optional();",
+ "export const Example = z.object({"nestedExamples": z.lazy(() => Example).optional()});",
]
`;
@@ -95,69 +89,3 @@ exports[`ZodGenerator recursive > generate schema for Example 1`] = `
"export const Example = z.object({"name": z.string(),"children": z.array(z.lazy(() => Example))});",
]
`;
-
-exports[`ZodGenerator simple > generate schema for OptionalPet 1`] = `
-[
- "export const OptionalPet = z.object({"id": z.number().optional(),"name": z.string().optional(),"tag": z.string().optional()}).optional();",
-]
-`;
-
-exports[`ZodGenerator simple > generate schema for Pet 1`] = `
-[
- "export const Pet = z.object({"id": z.number(),"name": z.string(),"tag": z.string().min(5).max(100).optional()});",
-]
-`;
-
-exports[`ZodGenerator simple > generate schema for Pets 1`] = `
-[
- "export const Pets = z.array(z.object({"id": z.number(),"name": z.string(),"tag": z.string().optional()}));",
-]
-`;
-
-exports[`ZodGenerator with const > MixedValueTypeConst generates zod literal value correctly, overriding the type constraint 1`] = `
-[
- "export const MixedValueTypeConst = z.object({"foobar": z.literal("foobar")}).describe(\`This probably should fail miserably\`);",
-]
-`;
-
-exports[`ZodGenerator with const > NullConst zodifies correctly 1`] = `
-[
- "export const NullConst = z.literal(z.null());",
-]
-`;
-
-exports[`ZodGenerator with const > NullableString zodifies correctly 1`] = `
-[
- "export const NullableString = z.string().nullable();",
-]
-`;
-
-exports[`ZodGenerator with const > NullableStringUuid zodifies correctly to a uuid or null 1`] = `
-[
- "export const NullableStringUuid = z.string().uuid().nullable();",
-]
-`;
-
-exports[`ZodGenerator with const > NullableStringWithAnyOf results in union of string and null 1`] = `
-[
- "export const NullableStringWithAnyOf = z.union([z.string(),z.null()]);",
-]
-`;
-
-exports[`ZodGenerator with const > NumberValueConst correctly generates zod literal 1`] = `
-[
- "export const NumberValueConst = z.object({"foobar": z.literal(42)}).describe(\`its value is equal to the value of the keyword\`);",
-]
-`;
-
-exports[`ZodGenerator with const > StringValueConst correctly generates zod literal 1`] = `
-[
- "export const StringValueConst = z.object({"foobar": z.literal("foobar")}).describe(\`its value is equal to the value of the keyword\`);",
-]
-`;
-
-exports[`ZodGenerator with const > UuidSchema generates a string with uuid format constraint 1`] = `
-[
- "export const UuidSchema = z.string().uuid();",
-]
-`;
diff --git a/packages/swagger-zod/src/zodParser.ts b/packages/swagger-zod/src/zodParser.ts
index 519096548..675e4a178 100644
--- a/packages/swagger-zod/src/zodParser.ts
+++ b/packages/swagger-zod/src/zodParser.ts
@@ -264,9 +264,7 @@ export function zodParser(items: ZodMeta[], options: { required?: boolean; keysT
}
if (options.keysToOmit?.length) {
- const omitText = options.required
- ? `.schema.omit({ ${options.keysToOmit.map((key) => `${key}: true`).join(',')} })`
- : `.schema.unwrap().omit({ ${options.keysToOmit.map((key) => `${key}: true`).join(',')} })`
+ const omitText = `.schema.omit({ ${options.keysToOmit.map((key) => `${key}: true`).join(',')} })`
return `export const ${options.name} = ${items.map((item) => parseZodMeta(item, { ...zodKeywordMapper, ...options.mapper })).join('')}${omitText};`
}
diff --git a/packages/swagger-zodios/src/components/Definitions.tsx b/packages/swagger-zodios/src/components/Definitions.tsx
index 924abebc8..4eb11dc9c 100644
--- a/packages/swagger-zodios/src/components/Definitions.tsx
+++ b/packages/swagger-zodios/src/components/Definitions.tsx
@@ -44,7 +44,8 @@ const parameters = {
item.keys?.forEach((key) => {
const schema = item.schema?.properties?.[key] as OasTypes.SchemaObject
const shape = item.schema?.$ref ? `schema.shape['${key}']` : `shape['${key}']`
- const definedSchema = Array.isArray(item.schema.required) && item.schema.required?.length ? `${name}.${shape}` : `${name}.unwrap().${shape}`
+ const required = Array.isArray(item.schema.required) ? !!item.schema.required?.length : !!item.schema.required
+ const definedSchema = required ? `${name}.${shape}` : `${name}.unwrap().${shape}`
parameters.push(`
{
@@ -64,7 +65,8 @@ const parameters = {
item.keys?.forEach((key) => {
const schema = item.schema?.properties?.[key] as OasTypes.SchemaObject
const shape = item.schema?.$ref ? `schema.shape['${key}']` : `shape['${key}']`
- const definedSchema = Array.isArray(item.schema.required) && item.schema.required?.length ? `${name}.${shape}` : `${name}.unwrap().${shape}`
+ const required = Array.isArray(item.schema.required) ? !!item.schema.required?.length : !!item.schema.required
+ const definedSchema = required ? `${name}.${shape}` : `${name}.unwrap().${shape}`
parameters.push(`
{
@@ -83,7 +85,8 @@ const parameters = {
item.keys?.forEach((key) => {
const schema = item.schema?.properties?.[key] as OasTypes.SchemaObject
const shape = item.schema?.$ref ? `schema.shape['${key}']` : `shape['${key}']`
- const definedSchema = Array.isArray(item.schema.required) && item.schema.required?.length ? `${name}.${shape}` : `${name}.unwrap().${shape}`
+ const required = Array.isArray(item.schema.required) ? !!item.schema.required?.length : !!item.schema.required
+ const definedSchema = required ? `${name}.${shape}` : `${name}.unwrap().${shape}`
parameters.push(`
{
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 61de30b09..419dd4213 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1487,6 +1487,9 @@ importers:
'@kubb/swagger-ts':
specifier: workspace:*
version: link:../swagger-ts
+ '@kubb/swagger-zod':
+ specifier: workspace:*
+ version: link:../swagger-zod
devDependencies:
'@kubb/eslint-config':
specifier: workspace:*