From efa7c752295848362475a4f18d91e201b14dfa8a Mon Sep 17 00:00:00 2001 From: Stijn Van Hulle Date: Tue, 12 Mar 2024 19:40:14 +0100 Subject: [PATCH] Support mutate with params (#835) --- .changeset/friendly-starfishes-smoke.md | 5 + configs/vitest.config.ts | 1 + docs/plugins/react/hooks/index.md | 18 + docs/plugins/swagger-tanstack-query/index.md | 86 ++ docs/plugins/swagger/hooks/index.md | 38 +- e2e/kubb.config.js | 3 + examples/advanced/configs/kubb.config.ts | 3 + .../clients/hooks/petController/useAddPet.ts | 14 +- .../hooks/petController/useDeletePet.ts | 21 +- .../hooks/petController/useUpdatePet.ts | 14 +- .../petController/useUpdatePetWithForm.ts | 21 +- .../hooks/petController/useUploadFile.ts | 22 +- .../hooks/petsController/useCreatePets.ts | 25 +- .../hooks/userController/useDeleteUser.ts | 8 +- .../src/gen/hooks/useDeleteOrderHook.ts | 4 +- .../src/gen/hooks/useDeletePetHook.ts | 4 +- .../src/gen/hooks/useDeleteUserHook.ts | 4 +- .../src/gen/hooks/useUpdatePetWithFormHook.ts | 4 +- .../templates/operations/index.tsx | 7 +- .../src/gen/hooks/useDeleteOrderHook.ts | 8 +- .../src/gen/hooks/useDeletePetHook.ts | 8 +- .../src/gen/hooks/useDeleteUserHook.ts | 8 +- .../src/gen/hooks/useUpdatePetWithFormHook.ts | 8 +- examples/simple-single/src/gen/hooks.ts | 32 +- .../src/gen/hooks/deleteOrderQuery.ts | 8 +- .../src/gen/hooks/deletePetQuery.ts | 8 +- .../src/gen/hooks/deleteUserQuery.ts | 8 +- .../src/gen/hooks/updatePetWithFormQuery.ts | 8 +- .../src/gen/hooks/deleteOrderQuery.ts | 8 +- .../src/gen/hooks/deletePetQuery.ts | 8 +- .../src/gen/hooks/deleteUserQuery.ts | 8 +- .../src/gen/hooks/updatePetWithFormQuery.ts | 8 +- .../src/gen/hooks/useDeleteOrder.ts | 4 +- .../src/gen/hooks/useDeletePet.ts | 4 +- .../src/gen/hooks/useDeleteUser.ts | 4 +- .../src/gen/hooks/useUpdatePetWithForm.ts | 4 +- .../vue-query/src/gen/hooks/useDeleteOrder.ts | 4 +- .../vue-query/src/gen/hooks/useDeletePet.ts | 4 +- .../vue-query/src/gen/hooks/useDeleteUser.ts | 4 +- .../src/gen/hooks/useUpdatePetWithForm.ts | 4 +- .../core/src/utils/FunctionParams.test.ts | 27 + packages/core/src/utils/FunctionParams.ts | 125 ++- packages/react/src/hooks/useFile.ts | 3 + packages/react/src/hooks/useFileManager.ts | 3 + packages/react/src/hooks/useLanguage.ts | 3 + packages/react/src/hooks/useMeta.ts | 3 + packages/react/src/hooks/usePackageVersion.ts | 4 +- packages/react/src/hooks/usePlugin.ts | 3 + packages/react/src/hooks/usePluginManager.ts | 3 + packages/react/src/hooks/useResolveName.ts | 4 + packages/react/src/hooks/useResolvePath.ts | 4 + packages/react/src/shared/ReactTemplate.tsx | 3 +- .../src/OperationGenerator.test.tsx | 2 +- .../swagger-client/src/components/Client.tsx | 12 +- .../src/components/Operations.tsx | 12 +- .../swagger-faker/src/components/Mutation.tsx | 2 +- .../swagger-faker/src/components/Query.tsx | 2 +- .../swagger-msw/src/components/Operations.tsx | 20 +- .../mocks/petStore.yaml | 965 ++++++++++++++++-- .../src/OperationGenerator.test.tsx | 188 ++++ .../OperationGenerator.test.tsx.snap | 119 +++ .../src/components/Mutation.test.tsx | 120 ++- .../src/components/Mutation.tsx | 137 ++- .../src/components/Operations.tsx | 12 +- .../src/components/Query.test.tsx | 4 +- .../src/components/Query.tsx | 7 +- .../src/components/QueryKey.tsx | 7 +- .../src/components/QueryOptions.tsx | 5 +- .../__snapshots__/Mutation.test.tsx.snap | 64 -- .../Mutation/{Pets.ts => useCreatePets.ts} | 15 +- .../Mutation/useCreatePetsMutate.ts | 55 + .../__snapshots__/Query.test.tsx.snap | 68 -- .../__snapshots__/Query/showPetById.ts | 54 +- packages/swagger-tanstack-query/src/plugin.ts | 7 + packages/swagger-tanstack-query/src/types.ts | 24 + .../swagger-ts/src/components/Mutation.tsx | 2 +- .../swagger-ts/src/components/OasType.tsx | 2 +- packages/swagger-ts/src/components/Query.tsx | 2 +- .../swagger-zod/src/components/Mutation.tsx | 2 +- packages/swagger-zod/src/components/Query.tsx | 2 +- packages/swagger/src/hooks/useOas.ts | 14 +- packages/swagger/src/hooks/useOperation.ts | 29 +- .../swagger/src/hooks/useOperationHelpers.ts | 29 +- packages/swagger/src/hooks/useOperations.ts | 3 + 84 files changed, 2115 insertions(+), 518 deletions(-) create mode 100644 .changeset/friendly-starfishes-smoke.md create mode 100644 packages/swagger-tanstack-query/src/OperationGenerator.test.tsx create mode 100644 packages/swagger-tanstack-query/src/__snapshots__/OperationGenerator.test.tsx.snap delete mode 100644 packages/swagger-tanstack-query/src/components/__snapshots__/Mutation.test.tsx.snap rename packages/swagger-tanstack-query/src/components/__snapshots__/Mutation/{Pets.ts => useCreatePets.ts} (76%) create mode 100644 packages/swagger-tanstack-query/src/components/__snapshots__/Mutation/useCreatePetsMutate.ts delete mode 100644 packages/swagger-tanstack-query/src/components/__snapshots__/Query.test.tsx.snap diff --git a/.changeset/friendly-starfishes-smoke.md b/.changeset/friendly-starfishes-smoke.md new file mode 100644 index 000000000..3c40b79ec --- /dev/null +++ b/.changeset/friendly-starfishes-smoke.md @@ -0,0 +1,5 @@ +--- +"@kubb/swagger-tanstack-query": minor +--- + +use of `mutate.variablesType` to override mutation behaviour(params in the generated hook or mutate function with extra params) diff --git a/configs/vitest.config.ts b/configs/vitest.config.ts index b3d7f2f8a..58491e570 100644 --- a/configs/vitest.config.ts +++ b/configs/vitest.config.ts @@ -27,6 +27,7 @@ export default defineConfig({ '**/packages/swagger-client/client.ts', '**/e2e/**', '**/coverage/**', + '**/__snapshots__/**', '**/packages/*/test?(s)/**', '**/*.d.ts', 'test?(s)/**', diff --git a/docs/plugins/react/hooks/index.md b/docs/plugins/react/hooks/index.md index f45727573..ed17b52e4 100644 --- a/docs/plugins/react/hooks/index.md +++ b/docs/plugins/react/hooks/index.md @@ -32,6 +32,24 @@ function Component() { ::: +## useLanguage + +`useLanguage` will return the current language set by the parent `Editor` component. + +::: code-group + +```typescript +import { useLanguage } from '@kubb/react' + +function Component() { + const language = useLanguage() + + return null +} +``` + +::: + ## usePluginManager `usePluginManager` will return the PluginManager instance. diff --git a/docs/plugins/swagger-tanstack-query/index.md b/docs/plugins/swagger-tanstack-query/index.md index 39e8c3bf3..f767a72a5 100644 --- a/docs/plugins/swagger-tanstack-query/index.md +++ b/docs/plugins/swagger-tanstack-query/index.md @@ -365,6 +365,92 @@ export default defineConfig({ ::: +### variablesType + +Define the way of passing thought the queryParams, headerParams and data. + +`'mutate'` will use the `mutate` or `mutateAsync` function.
+`'hook'` will use the `useMutation` hook. + +::: info type + +::: code-group + +```typescript ['mutate'] +const { mutate } = useDeletePet() + +mutate({ + petId: 1, +}) +``` + +```typescript ['hook'] +const { mutate } = useDeletePet(1) + +mutate() +``` + +::: + +::: info + +Type: `'mutate' | 'hook'`
+Default: `'hook'` + +::: code-group + +```typescript ['mutate'] +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( + { + variablesType: 'mutate', + }, + ), + ], +}) +``` + +```typescript ['hook'] +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( + { + variablesType: 'hook', + }, + ), + ], +}) +``` + +::: + ### parser Which parser can be used before returning the data to `@tanstack/query`. diff --git a/docs/plugins/swagger/hooks/index.md b/docs/plugins/swagger/hooks/index.md index d53fca1cc..29200a370 100644 --- a/docs/plugins/swagger/hooks/index.md +++ b/docs/plugins/swagger/hooks/index.md @@ -20,7 +20,7 @@ See [Oas](https://github.com/readmeio/oas) to understand how to use the `Oas` in import { useOas } from '@kubb/react' function Component() { - const { oas } = useOas() + const oas = useOas() return null } @@ -46,6 +46,24 @@ function Component() { ::: +## useOperations + +`useOperations` will return all the Operations.
+ +::: code-group + +```typescript +import { useOperations } from '@kubb/react' + +function Component() { + const operations = useOperations() + + return null +} +``` + +::: + ## useSchemas `useSchemas` will return the schemas of the current `Operation`.
@@ -64,6 +82,24 @@ function Component() { ::: +## useOperationHelpers + +`useOperationHelpers` will return some helper functions that can be used to get the operation file, get the operation name.
+ +::: code-group + +```typescript +import { useOperationHelpers } from '@kubb/react' + +function Component() { + const { getName, getFile } = useOperationHelpers() + + return null +} +``` + +::: + ## useOperationName `useOperationName` will return the name based on the current operation and plugin(when `pluginKey` is not provided).
diff --git a/e2e/kubb.config.js b/e2e/kubb.config.js index 108a3ca88..651547f5e 100644 --- a/e2e/kubb.config.js +++ b/e2e/kubb.config.js @@ -55,6 +55,9 @@ const baseConfig = { path: './clients/hooks', }, group: { type: 'tag' }, + mutate: { + variablesType: 'mutate', + }, }], ['@kubb/swagger-swr', { output: { diff --git a/examples/advanced/configs/kubb.config.ts b/examples/advanced/configs/kubb.config.ts index 4125bd7e5..6c17bbac5 100644 --- a/examples/advanced/configs/kubb.config.ts +++ b/examples/advanced/configs/kubb.config.ts @@ -81,6 +81,9 @@ export default defineConfig(async () => { queryParam: 'test', initialPageParam: '0', }, + mutate: { + variablesType: 'mutate', + }, }, }, ], diff --git a/examples/advanced/src/gen/clients/hooks/petController/useAddPet.ts b/examples/advanced/src/gen/clients/hooks/petController/useAddPet.ts index ed119563f..fb6d4dbeb 100644 --- a/examples/advanced/src/gen/clients/hooks/petController/useAddPet.ts +++ b/examples/advanced/src/gen/clients/hooks/petController/useAddPet.ts @@ -22,12 +22,18 @@ type AddPet = { * @summary Add a new pet to the store * @link /pet */ export function useAddPet(options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: AddPet['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ - mutationFn: async (data) => { + return useMutation({ + mutationFn: async ({ data }) => { const res = await client({ method: 'post', url: `/pet`, diff --git a/examples/advanced/src/gen/clients/hooks/petController/useDeletePet.ts b/examples/advanced/src/gen/clients/hooks/petController/useDeletePet.ts index 9a7b15d83..0754239a0 100644 --- a/examples/advanced/src/gen/clients/hooks/petController/useDeletePet.ts +++ b/examples/advanced/src/gen/clients/hooks/petController/useDeletePet.ts @@ -21,14 +21,23 @@ type DeletePet = { * @description delete a pet * @summary Deletes a pet * @link /pet/:petId */ -export function useDeletePet(petId: DeletePetPathParams['petId'], headers?: DeletePet['headerParams'], options: { - mutation?: UseMutationOptions +export function useDeletePet(options: { + mutation?: UseMutationOptions client?: DeletePet['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ - mutationFn: async () => { - const res = await client({ + return useMutation({ + mutationFn: async ({ petId, headers }) => { + const res = await client({ method: 'delete', url: `/pet/${petId}`, headers: { ...headers, ...clientOptions.headers }, diff --git a/examples/advanced/src/gen/clients/hooks/petController/useUpdatePet.ts b/examples/advanced/src/gen/clients/hooks/petController/useUpdatePet.ts index 6f9816fb8..d172f0cda 100644 --- a/examples/advanced/src/gen/clients/hooks/petController/useUpdatePet.ts +++ b/examples/advanced/src/gen/clients/hooks/petController/useUpdatePet.ts @@ -22,12 +22,18 @@ type UpdatePet = { * @summary Update an existing pet * @link /pet */ export function useUpdatePet(options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: UpdatePet['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ - mutationFn: async (data) => { + return useMutation({ + mutationFn: async ({ data }) => { const res = await client({ method: 'put', url: `/pet`, diff --git a/examples/advanced/src/gen/clients/hooks/petController/useUpdatePetWithForm.ts b/examples/advanced/src/gen/clients/hooks/petController/useUpdatePetWithForm.ts index c371f25b9..2d1fb669a 100644 --- a/examples/advanced/src/gen/clients/hooks/petController/useUpdatePetWithForm.ts +++ b/examples/advanced/src/gen/clients/hooks/petController/useUpdatePetWithForm.ts @@ -25,14 +25,23 @@ type UpdatePetWithForm = { /** * @summary Updates a pet in the store with form data * @link /pet/:petId */ -export function useUpdatePetWithForm(petId: UpdatePetWithFormPathParams['petId'], params?: UpdatePetWithForm['queryParams'], options: { - mutation?: UseMutationOptions +export function useUpdatePetWithForm(options: { + mutation?: UseMutationOptions client?: UpdatePetWithForm['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ - mutationFn: async () => { - const res = await client({ + return useMutation({ + mutationFn: async ({ petId, params }) => { + const res = await client({ method: 'post', url: `/pet/${petId}`, params, diff --git a/examples/advanced/src/gen/clients/hooks/petController/useUploadFile.ts b/examples/advanced/src/gen/clients/hooks/petController/useUploadFile.ts index 234adaffb..aaca25275 100644 --- a/examples/advanced/src/gen/clients/hooks/petController/useUploadFile.ts +++ b/examples/advanced/src/gen/clients/hooks/petController/useUploadFile.ts @@ -25,13 +25,25 @@ type UploadFile = { /** * @summary uploads an image * @link /pet/:petId/uploadImage */ -export function useUploadFile(petId: UploadFilePathParams['petId'], params?: UploadFile['queryParams'], options: { - mutation?: UseMutationOptions +export function useUploadFile(options: { + mutation?: UseMutationOptions client?: UploadFile['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ - mutationFn: async (data) => { + return useMutation({ + mutationFn: async ({ petId, params, data }) => { const res = await client({ method: 'post', url: `/pet/${petId}/uploadImage`, diff --git a/examples/advanced/src/gen/clients/hooks/petsController/useCreatePets.ts b/examples/advanced/src/gen/clients/hooks/petsController/useCreatePets.ts index 17b171a3b..c238e2b8f 100644 --- a/examples/advanced/src/gen/clients/hooks/petsController/useCreatePets.ts +++ b/examples/advanced/src/gen/clients/hooks/petsController/useCreatePets.ts @@ -26,13 +26,28 @@ type CreatePets = { /** * @summary Create a pet * @link /pets/:uuid */ -export function useCreatePets(uuid: CreatePetsPathParams['uuid'], headers: CreatePets['headerParams'], params?: CreatePets['queryParams'], options: { - mutation?: UseMutationOptions +export function useCreatePets(options: { + mutation?: UseMutationOptions client?: CreatePets['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ - mutationFn: async (data) => { + return useMutation({ + mutationFn: async ({ uuid, headers, data, params }) => { const res = await client({ method: 'post', url: `/pets/${uuid}`, diff --git a/examples/advanced/src/gen/clients/hooks/userController/useDeleteUser.ts b/examples/advanced/src/gen/clients/hooks/userController/useDeleteUser.ts index 7a85a9a98..fd362acfc 100644 --- a/examples/advanced/src/gen/clients/hooks/userController/useDeleteUser.ts +++ b/examples/advanced/src/gen/clients/hooks/userController/useDeleteUser.ts @@ -22,13 +22,13 @@ type DeleteUser = { * @summary Delete user * @link /user/:username */ export function useDeleteUser(username: DeleteUserPathParams['username'], options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: DeleteUser['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ + return useMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/user/${username}`, ...clientOptions, diff --git a/examples/react-query-v5/src/gen/hooks/useDeleteOrderHook.ts b/examples/react-query-v5/src/gen/hooks/useDeleteOrderHook.ts index c0c8c5b4f..e3ab8c2a5 100644 --- a/examples/react-query-v5/src/gen/hooks/useDeleteOrderHook.ts +++ b/examples/react-query-v5/src/gen/hooks/useDeleteOrderHook.ts @@ -23,14 +23,14 @@ type DeleteOrder = { * @summary Delete purchase order by ID * @link /store/order/:orderId */ export function useDeleteOrderHook(orderId: DeleteOrderPathParams['orderId'], options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: DeleteOrder['client']['parameters'] } = {}) { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} const invalidationOnSuccess = useInvalidationForMutation('useDeleteOrderHook') return useMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/store/order/${orderId}`, ...clientOptions, diff --git a/examples/react-query-v5/src/gen/hooks/useDeletePetHook.ts b/examples/react-query-v5/src/gen/hooks/useDeletePetHook.ts index 4d0629cd5..04f4a5e57 100644 --- a/examples/react-query-v5/src/gen/hooks/useDeletePetHook.ts +++ b/examples/react-query-v5/src/gen/hooks/useDeletePetHook.ts @@ -23,14 +23,14 @@ type DeletePet = { * @summary Deletes a pet * @link /pet/:petId */ export function useDeletePetHook(petId: DeletePetPathParams['petId'], headers?: DeletePet['headerParams'], options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: DeletePet['client']['parameters'] } = {}) { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} const invalidationOnSuccess = useInvalidationForMutation('useDeletePetHook') return useMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/pet/${petId}`, headers: { ...headers, ...clientOptions.headers }, diff --git a/examples/react-query-v5/src/gen/hooks/useDeleteUserHook.ts b/examples/react-query-v5/src/gen/hooks/useDeleteUserHook.ts index aeb466020..b7193d48b 100644 --- a/examples/react-query-v5/src/gen/hooks/useDeleteUserHook.ts +++ b/examples/react-query-v5/src/gen/hooks/useDeleteUserHook.ts @@ -23,14 +23,14 @@ type DeleteUser = { * @summary Delete user * @link /user/:username */ export function useDeleteUserHook(username: DeleteUserPathParams['username'], options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: DeleteUser['client']['parameters'] } = {}) { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} const invalidationOnSuccess = useInvalidationForMutation('useDeleteUserHook') return useMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/user/${username}`, ...clientOptions, diff --git a/examples/react-query-v5/src/gen/hooks/useUpdatePetWithFormHook.ts b/examples/react-query-v5/src/gen/hooks/useUpdatePetWithFormHook.ts index f3046728f..8499cc546 100644 --- a/examples/react-query-v5/src/gen/hooks/useUpdatePetWithFormHook.ts +++ b/examples/react-query-v5/src/gen/hooks/useUpdatePetWithFormHook.ts @@ -27,14 +27,14 @@ type UpdatePetWithForm = { * @summary Updates a pet in the store with form data * @link /pet/:petId */ export function useUpdatePetWithFormHook(petId: UpdatePetWithFormPathParams['petId'], params?: UpdatePetWithForm['queryParams'], options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: UpdatePetWithForm['client']['parameters'] } = {}) { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} const invalidationOnSuccess = useInvalidationForMutation('useUpdatePetWithFormHook') return useMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'post', url: `/pet/${petId}`, params, diff --git a/examples/react-query-v5/templates/operations/index.tsx b/examples/react-query-v5/templates/operations/index.tsx index 66f2aeb96..7e67f1b6d 100644 --- a/examples/react-query-v5/templates/operations/index.tsx +++ b/examples/react-query-v5/templates/operations/index.tsx @@ -8,12 +8,11 @@ import { usePluginManager } from '@kubb/react' export const templates = { ...Operations.templates, - editor: function({}: React.ComponentProps) { + root: function({}: React.ComponentProps) { const pluginManager = usePluginManager() const { key: pluginKey } = usePlugin() const operations = useOperations() - const { getSchemas } = useOas() - const { getOperationName } = useOperationHelpers() + const { getName, getSchemas } = useOperationHelpers() const root = path.resolve(pluginManager.config.root, pluginManager.config.output.path) @@ -24,7 +23,7 @@ export const templates = { }).flat().filter(Boolean) const invalidations = operations.reduce((acc, operation) => { - const name = getOperationName(operation, { pluginKey, type: 'function' }) + const name = getName(operation, { pluginKey, type: 'function' }) const schemas = getSchemas(operation) acc[name] = `UseMutationOptions<${schemas.response.name}, unknown, ${schemas.request?.name || 'void'}>['onSuccess']` diff --git a/examples/react-query/src/gen/hooks/useDeleteOrderHook.ts b/examples/react-query/src/gen/hooks/useDeleteOrderHook.ts index e22cd89c8..f309c6ec9 100644 --- a/examples/react-query/src/gen/hooks/useDeleteOrderHook.ts +++ b/examples/react-query/src/gen/hooks/useDeleteOrderHook.ts @@ -22,13 +22,13 @@ type DeleteOrder = { * @summary Delete purchase order by ID * @link /store/order/:orderId */ export function useDeleteOrderHook(orderId: DeleteOrderPathParams['orderId'], options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: DeleteOrder['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ + return useMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/store/order/${orderId}`, ...clientOptions, diff --git a/examples/react-query/src/gen/hooks/useDeletePetHook.ts b/examples/react-query/src/gen/hooks/useDeletePetHook.ts index 48dad7da9..347d9fa05 100644 --- a/examples/react-query/src/gen/hooks/useDeletePetHook.ts +++ b/examples/react-query/src/gen/hooks/useDeletePetHook.ts @@ -22,13 +22,13 @@ type DeletePet = { * @summary Deletes a pet * @link /pet/:petId */ export function useDeletePetHook(petId: DeletePetPathParams['petId'], headers?: DeletePet['headerParams'], options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: DeletePet['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ + return useMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/pet/${petId}`, headers: { ...headers, ...clientOptions.headers }, diff --git a/examples/react-query/src/gen/hooks/useDeleteUserHook.ts b/examples/react-query/src/gen/hooks/useDeleteUserHook.ts index 14e9965e1..cc2b5dc79 100644 --- a/examples/react-query/src/gen/hooks/useDeleteUserHook.ts +++ b/examples/react-query/src/gen/hooks/useDeleteUserHook.ts @@ -22,13 +22,13 @@ type DeleteUser = { * @summary Delete user * @link /user/:username */ export function useDeleteUserHook(username: DeleteUserPathParams['username'], options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: DeleteUser['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ + return useMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/user/${username}`, ...clientOptions, diff --git a/examples/react-query/src/gen/hooks/useUpdatePetWithFormHook.ts b/examples/react-query/src/gen/hooks/useUpdatePetWithFormHook.ts index 0299f8c00..3d56dea46 100644 --- a/examples/react-query/src/gen/hooks/useUpdatePetWithFormHook.ts +++ b/examples/react-query/src/gen/hooks/useUpdatePetWithFormHook.ts @@ -26,13 +26,13 @@ type UpdatePetWithForm = { * @summary Updates a pet in the store with form data * @link /pet/:petId */ export function useUpdatePetWithFormHook(petId: UpdatePetWithFormPathParams['petId'], params?: UpdatePetWithForm['queryParams'], options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: UpdatePetWithForm['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ + return useMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'post', url: `/pet/${petId}`, params, diff --git a/examples/simple-single/src/gen/hooks.ts b/examples/simple-single/src/gen/hooks.ts index 5c28a2559..d6d8a3349 100644 --- a/examples/simple-single/src/gen/hooks.ts +++ b/examples/simple-single/src/gen/hooks.ts @@ -341,13 +341,13 @@ type UpdatePetWithForm = { * @summary Updates a pet in the store with form data * @link /pet/:petId */ export function useUpdatePetWithForm(petId: UpdatePetWithFormPathParams['petId'], params?: UpdatePetWithForm['queryParams'], options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: UpdatePetWithForm['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ + return useMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'post', url: `/pet/${petId}`, params, @@ -378,13 +378,13 @@ type DeletePet = { * @summary Deletes a pet * @link /pet/:petId */ export function useDeletePet(petId: DeletePetPathParams['petId'], headers?: DeletePet['headerParams'], options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: DeletePet['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ + return useMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/pet/${petId}`, headers: { ...headers, ...clientOptions.headers }, @@ -642,13 +642,13 @@ type DeleteOrder = { * @summary Delete purchase order by ID * @link /store/order/:orderId */ export function useDeleteOrder(orderId: DeleteOrderPathParams['orderId'], options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: DeleteOrder['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ + return useMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/store/order/${orderId}`, ...clientOptions, @@ -960,13 +960,13 @@ type DeleteUser = { * @summary Delete user * @link /user/:username */ export function useDeleteUser(username: DeleteUserPathParams['username'], options: { - mutation?: UseMutationOptions + mutation?: UseMutationOptions client?: DeleteUser['client']['parameters'] -} = {}): UseMutationResult { +} = {}): UseMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return useMutation({ + return useMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/user/${username}`, ...clientOptions, diff --git a/examples/solid-query/src/gen/hooks/deleteOrderQuery.ts b/examples/solid-query/src/gen/hooks/deleteOrderQuery.ts index 24c7e7359..550b26514 100644 --- a/examples/solid-query/src/gen/hooks/deleteOrderQuery.ts +++ b/examples/solid-query/src/gen/hooks/deleteOrderQuery.ts @@ -24,14 +24,14 @@ type DeleteOrder = { export function deleteOrderQuery( orderId: DeleteOrderPathParams['orderId'], options: { - mutation?: CreateMutationOptions + mutation?: CreateMutationOptions client?: DeleteOrder['client']['parameters'] } = {}, -): CreateMutationResult { +): CreateMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return createMutation({ + return createMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/store/order/${orderId}`, ...clientOptions, diff --git a/examples/solid-query/src/gen/hooks/deletePetQuery.ts b/examples/solid-query/src/gen/hooks/deletePetQuery.ts index 20a5276fe..bc3ffa309 100644 --- a/examples/solid-query/src/gen/hooks/deletePetQuery.ts +++ b/examples/solid-query/src/gen/hooks/deletePetQuery.ts @@ -25,14 +25,14 @@ export function deletePetQuery( petId: DeletePetPathParams['petId'], headers?: DeletePet['headerParams'], options: { - mutation?: CreateMutationOptions + mutation?: CreateMutationOptions client?: DeletePet['client']['parameters'] } = {}, -): CreateMutationResult { +): CreateMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return createMutation({ + return createMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/pet/${petId}`, headers: { ...headers, ...clientOptions.headers }, diff --git a/examples/solid-query/src/gen/hooks/deleteUserQuery.ts b/examples/solid-query/src/gen/hooks/deleteUserQuery.ts index 5f32d842a..5d4e35016 100644 --- a/examples/solid-query/src/gen/hooks/deleteUserQuery.ts +++ b/examples/solid-query/src/gen/hooks/deleteUserQuery.ts @@ -24,14 +24,14 @@ type DeleteUser = { export function deleteUserQuery( username: DeleteUserPathParams['username'], options: { - mutation?: CreateMutationOptions + mutation?: CreateMutationOptions client?: DeleteUser['client']['parameters'] } = {}, -): CreateMutationResult { +): CreateMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return createMutation({ + return createMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/user/${username}`, ...clientOptions, diff --git a/examples/solid-query/src/gen/hooks/updatePetWithFormQuery.ts b/examples/solid-query/src/gen/hooks/updatePetWithFormQuery.ts index 1194f0459..cae67bc21 100644 --- a/examples/solid-query/src/gen/hooks/updatePetWithFormQuery.ts +++ b/examples/solid-query/src/gen/hooks/updatePetWithFormQuery.ts @@ -29,14 +29,14 @@ export function updatePetWithFormQuery( petId: UpdatePetWithFormPathParams['petId'], params?: UpdatePetWithForm['queryParams'], options: { - mutation?: CreateMutationOptions + mutation?: CreateMutationOptions client?: UpdatePetWithForm['client']['parameters'] } = {}, -): CreateMutationResult { +): CreateMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return createMutation({ + return createMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'post', url: `/pet/${petId}`, params, diff --git a/examples/svelte-query/src/gen/hooks/deleteOrderQuery.ts b/examples/svelte-query/src/gen/hooks/deleteOrderQuery.ts index 81c13aa4c..3afcb1d85 100644 --- a/examples/svelte-query/src/gen/hooks/deleteOrderQuery.ts +++ b/examples/svelte-query/src/gen/hooks/deleteOrderQuery.ts @@ -24,14 +24,14 @@ type DeleteOrder = { export function deleteOrderQuery( orderId: DeleteOrderPathParams['orderId'], options: { - mutation?: CreateMutationOptions + mutation?: CreateMutationOptions client?: DeleteOrder['client']['parameters'] } = {}, -): CreateMutationResult { +): CreateMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return createMutation({ + return createMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/store/order/${orderId}`, ...clientOptions, diff --git a/examples/svelte-query/src/gen/hooks/deletePetQuery.ts b/examples/svelte-query/src/gen/hooks/deletePetQuery.ts index 135bacb2b..a146b3a46 100644 --- a/examples/svelte-query/src/gen/hooks/deletePetQuery.ts +++ b/examples/svelte-query/src/gen/hooks/deletePetQuery.ts @@ -25,14 +25,14 @@ export function deletePetQuery( petId: DeletePetPathParams['petId'], headers?: DeletePet['headerParams'], options: { - mutation?: CreateMutationOptions + mutation?: CreateMutationOptions client?: DeletePet['client']['parameters'] } = {}, -): CreateMutationResult { +): CreateMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return createMutation({ + return createMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/pet/${petId}`, headers: { ...headers, ...clientOptions.headers }, diff --git a/examples/svelte-query/src/gen/hooks/deleteUserQuery.ts b/examples/svelte-query/src/gen/hooks/deleteUserQuery.ts index 41d3f33c6..8ce3e7c90 100644 --- a/examples/svelte-query/src/gen/hooks/deleteUserQuery.ts +++ b/examples/svelte-query/src/gen/hooks/deleteUserQuery.ts @@ -24,14 +24,14 @@ type DeleteUser = { export function deleteUserQuery( username: DeleteUserPathParams['username'], options: { - mutation?: CreateMutationOptions + mutation?: CreateMutationOptions client?: DeleteUser['client']['parameters'] } = {}, -): CreateMutationResult { +): CreateMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return createMutation({ + return createMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'delete', url: `/user/${username}`, ...clientOptions, diff --git a/examples/svelte-query/src/gen/hooks/updatePetWithFormQuery.ts b/examples/svelte-query/src/gen/hooks/updatePetWithFormQuery.ts index dcbdf680b..70b6bf858 100644 --- a/examples/svelte-query/src/gen/hooks/updatePetWithFormQuery.ts +++ b/examples/svelte-query/src/gen/hooks/updatePetWithFormQuery.ts @@ -29,14 +29,14 @@ export function updatePetWithFormQuery( petId: UpdatePetWithFormPathParams['petId'], params?: UpdatePetWithForm['queryParams'], options: { - mutation?: CreateMutationOptions + mutation?: CreateMutationOptions client?: UpdatePetWithForm['client']['parameters'] } = {}, -): CreateMutationResult { +): CreateMutationResult { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} - return createMutation({ + return createMutation({ mutationFn: async () => { - const res = await client({ + const res = await client({ method: 'post', url: `/pet/${petId}`, params, diff --git a/examples/vue-query-v5/src/gen/hooks/useDeleteOrder.ts b/examples/vue-query-v5/src/gen/hooks/useDeleteOrder.ts index a189da8b0..40e78b4c4 100644 --- a/examples/vue-query-v5/src/gen/hooks/useDeleteOrder.ts +++ b/examples/vue-query-v5/src/gen/hooks/useDeleteOrder.ts @@ -32,9 +32,9 @@ export function useDeleteOrder( ) { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} return useMutation({ - mutationFn: async () => { + mutationFn: async (data) => { const orderId = unref(refOrderId) - const res = await client({ + const res = await client({ method: 'delete', url: `/store/order/${orderId}`, ...clientOptions, diff --git a/examples/vue-query-v5/src/gen/hooks/useDeletePet.ts b/examples/vue-query-v5/src/gen/hooks/useDeletePet.ts index 6289681e9..860cc71d6 100644 --- a/examples/vue-query-v5/src/gen/hooks/useDeletePet.ts +++ b/examples/vue-query-v5/src/gen/hooks/useDeletePet.ts @@ -33,10 +33,10 @@ export function useDeletePet( ) { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} return useMutation({ - mutationFn: async () => { + mutationFn: async (data) => { const petId = unref(refPetId) const headers = unref(refHeaders) - const res = await client({ + const res = await client({ method: 'delete', url: `/pet/${petId}`, headers: { ...headers, ...clientOptions.headers }, diff --git a/examples/vue-query-v5/src/gen/hooks/useDeleteUser.ts b/examples/vue-query-v5/src/gen/hooks/useDeleteUser.ts index 58ae86f46..05f7b99ee 100644 --- a/examples/vue-query-v5/src/gen/hooks/useDeleteUser.ts +++ b/examples/vue-query-v5/src/gen/hooks/useDeleteUser.ts @@ -32,9 +32,9 @@ export function useDeleteUser( ) { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} return useMutation({ - mutationFn: async () => { + mutationFn: async (data) => { const username = unref(refUsername) - const res = await client({ + const res = await client({ method: 'delete', url: `/user/${username}`, ...clientOptions, diff --git a/examples/vue-query-v5/src/gen/hooks/useUpdatePetWithForm.ts b/examples/vue-query-v5/src/gen/hooks/useUpdatePetWithForm.ts index bbf0868a1..4634d5fe1 100644 --- a/examples/vue-query-v5/src/gen/hooks/useUpdatePetWithForm.ts +++ b/examples/vue-query-v5/src/gen/hooks/useUpdatePetWithForm.ts @@ -37,10 +37,10 @@ export function useUpdatePetWithForm( ) { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} return useMutation({ - mutationFn: async () => { + mutationFn: async (data) => { const petId = unref(refPetId) const params = unref(refParams) - const res = await client({ + const res = await client({ method: 'post', url: `/pet/${petId}`, params, diff --git a/examples/vue-query/src/gen/hooks/useDeleteOrder.ts b/examples/vue-query/src/gen/hooks/useDeleteOrder.ts index 0d266c344..28df04808 100644 --- a/examples/vue-query/src/gen/hooks/useDeleteOrder.ts +++ b/examples/vue-query/src/gen/hooks/useDeleteOrder.ts @@ -33,9 +33,9 @@ export function useDeleteOrder( ): UseMutationReturnType { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} return useMutation({ - mutationFn: async () => { + mutationFn: async (data) => { const orderId = unref(refOrderId) - const res = await client({ + const res = await client({ method: 'delete', url: `/store/order/${orderId}`, ...clientOptions, diff --git a/examples/vue-query/src/gen/hooks/useDeletePet.ts b/examples/vue-query/src/gen/hooks/useDeletePet.ts index c25c1400b..1184890c7 100644 --- a/examples/vue-query/src/gen/hooks/useDeletePet.ts +++ b/examples/vue-query/src/gen/hooks/useDeletePet.ts @@ -34,10 +34,10 @@ export function useDeletePet( ): UseMutationReturnType { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} return useMutation({ - mutationFn: async () => { + mutationFn: async (data) => { const petId = unref(refPetId) const headers = unref(refHeaders) - const res = await client({ + const res = await client({ method: 'delete', url: `/pet/${petId}`, headers: { ...headers, ...clientOptions.headers }, diff --git a/examples/vue-query/src/gen/hooks/useDeleteUser.ts b/examples/vue-query/src/gen/hooks/useDeleteUser.ts index 40a31cc09..ee966810a 100644 --- a/examples/vue-query/src/gen/hooks/useDeleteUser.ts +++ b/examples/vue-query/src/gen/hooks/useDeleteUser.ts @@ -33,9 +33,9 @@ export function useDeleteUser( ): UseMutationReturnType { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} return useMutation({ - mutationFn: async () => { + mutationFn: async (data) => { const username = unref(refUsername) - const res = await client({ + const res = await client({ method: 'delete', url: `/user/${username}`, ...clientOptions, diff --git a/examples/vue-query/src/gen/hooks/useUpdatePetWithForm.ts b/examples/vue-query/src/gen/hooks/useUpdatePetWithForm.ts index 63f11c3dd..a9c6b2ae0 100644 --- a/examples/vue-query/src/gen/hooks/useUpdatePetWithForm.ts +++ b/examples/vue-query/src/gen/hooks/useUpdatePetWithForm.ts @@ -38,10 +38,10 @@ export function useUpdatePetWithForm( ): UseMutationReturnType { const { mutation: mutationOptions, client: clientOptions = {} } = options ?? {} return useMutation({ - mutationFn: async () => { + mutationFn: async (data) => { const petId = unref(refPetId) const params = unref(refParams) - const res = await client({ + const res = await client({ method: 'post', url: `/pet/${petId}`, params, diff --git a/packages/core/src/utils/FunctionParams.test.ts b/packages/core/src/utils/FunctionParams.test.ts index 9be1c9d84..5ba988c64 100644 --- a/packages/core/src/utils/FunctionParams.test.ts +++ b/packages/core/src/utils/FunctionParams.test.ts @@ -66,4 +66,31 @@ describe('objectToParameters', () => { .toString(), ).toEqual('lastName?: User["lastName"], firstName: User["firstName"] = {}') }) + + test('if object is resolved to a string with array typed parameters', () => { + expect( + new FunctionParams().add([ + [{ name: 'id' }], + { name: 'params' }, + ]).toString(), + ).toEqual('{ id }, params') + expect( + new FunctionParams() + .add([ + [{ name: 'id' }, { name: 'data' }], + { name: 'params' }, + ]) + .toString(), + ).toEqual('{ id, data }, params') + expect( + new FunctionParams() + .add([ + [{ name: 'id', type: 'Id' }, { name: 'data', type: 'Data' }], + { name: 'params', type: 'Params' }, + ]) + .toString(), + ).toEqual('{ id, data }?: { id: Id, data: Data }, params: Params') + }) + + test.todo('if static functionality works') }) diff --git a/packages/core/src/utils/FunctionParams.ts b/packages/core/src/utils/FunctionParams.ts index a012e9990..d743f2e29 100644 --- a/packages/core/src/utils/FunctionParams.ts +++ b/packages/core/src/utils/FunctionParams.ts @@ -32,55 +32,128 @@ type FunctionParamsASTWithType = { export type FunctionParamsAST = FunctionParamsASTWithoutType | FunctionParamsASTWithType export class FunctionParams { - public type?: 'generics' | 'typed' - public items: FunctionParamsAST[] = [] + type?: 'generics' | 'typed' + #items: Array = [] constructor(type?: 'generics' | 'typed') { this.type = type return this } - add(item: FunctionParamsAST | Array | undefined): FunctionParams { + get items(): FunctionParamsAST[] { + return this.#items.flat() + } + + add(item: FunctionParamsAST | Array | undefined): FunctionParams { if (!item) { return this } if (Array.isArray(item)) { - item.filter(Boolean).forEach((it) => this.items.push(it)) + item.filter(Boolean).forEach((it) => this.#items.push(it)) return this } - this.items.push(item) + this.#items.push(item) return this } + static #orderItems(items: Array) { + return orderBy(items.filter(Boolean), [ + (v) => { + if (Array.isArray(v)) { + return undefined + } + return !v.default + }, + (v) => { + if (Array.isArray(v)) { + return undefined + } + return v.required ?? true + }, + ], [ + 'desc', + 'desc', + ]) + } - toString(): string { - const sortedData = orderBy(this.items.filter(Boolean), [(v) => !v.default, (v) => v.required ?? true], ['desc', 'desc']) + static #addParams(acc: string[], item: FunctionParamsAST) { + const { enabled = true, name, type, required = true, ...rest } = item + + if (!enabled) { + return acc + } + + if (!name) { + // when name is not se we will use TypeScript generics + acc.push(`${type}${rest.default ? ` = ${rest.default}` : ''}`) + + return acc + } + // TODO check whey we still need the camelcase here + const parameterName = name.startsWith('{') ? name : camelCase(name) + + if (type) { + if (required) { + acc.push(`${parameterName}: ${type}${rest.default ? ` = ${rest.default}` : ''}`) + } else { + acc.push(`${parameterName}?: ${type}`) + } + } else { + acc.push(`${parameterName}`) + } + + return acc + } + + static toObject(items: FunctionParamsAST[]): FunctionParamsAST { + let type: string[] = [] + let name: string[] = [] + + const enabled = items.every(item => item.enabled) ? items.at(0)?.enabled : true + const required = items.every(item => item.required) ?? true + + items.forEach(item => { + name = FunctionParams.#addParams(name, { ...item, type: undefined }) + if (items.some(item => item.type)) { + type = FunctionParams.#addParams(type, item) + } + }) + + return { + name: `{ ${name.join(', ')} }`, + type: type.length ? `{ ${type.join(', ')} }` : undefined, + enabled, + required, + } + } + + static toString(items: (FunctionParamsAST | FunctionParamsAST[])[]): string { + const sortedData = this.#orderItems(items) return sortedData - .filter(({ enabled = true }) => enabled) - .reduce((acc, { name, type, required = true, ...rest }) => { - if (!name) { - // when name is not se we will use TypeScript generics - acc.push(`${type}${rest.default ? ` = ${rest.default}` : ''}`) + .reduce((acc, item) => { + if (Array.isArray(item)) { + const subItems = this.#orderItems(item) as FunctionParamsAST[] + const objectItem = FunctionParams.toObject(subItems) - return acc - } - // TODO check whey we still need the camelcase here - const parameterName = name.startsWith('{') ? name : camelCase(name) - - if (type) { - if (required) { - acc.push(`${parameterName}: ${type}${rest.default ? ` = ${rest.default}` : ''}`) - } else { - acc.push(`${parameterName}?: ${type}`) - } - } else { - acc.push(`${parameterName}`) + return FunctionParams.#addParams(acc, objectItem) } - return acc + return FunctionParams.#addParams(acc, item) }, [] as string[]) .join(', ') } + + toObject(): FunctionParamsAST { + const items = FunctionParams.#orderItems(this.#items).flat() + + return FunctionParams.toObject(items) + } + + toString(): string { + const items = FunctionParams.#orderItems(this.#items) + + return FunctionParams.toString(items) + } } diff --git a/packages/react/src/hooks/useFile.ts b/packages/react/src/hooks/useFile.ts index 50b07dead..e2e2e67d9 100644 --- a/packages/react/src/hooks/useFile.ts +++ b/packages/react/src/hooks/useFile.ts @@ -10,6 +10,9 @@ type Props = { options?: TOptions } +/** + * With `useFile` you can get all props needed to create a file(path, baseName, source). + */ export function useFile({ name, mode, extName, pluginKey, options }: Props): KubbFile.File<{ pluginKey: Plugin['key'] }> { const pluginManager = usePluginManager() diff --git a/packages/react/src/hooks/useFileManager.ts b/packages/react/src/hooks/useFileManager.ts index ddd0073f0..856dbbda1 100644 --- a/packages/react/src/hooks/useFileManager.ts +++ b/packages/react/src/hooks/useFileManager.ts @@ -2,6 +2,9 @@ import { useApp } from './useApp.ts' import type { FileManager, PluginManager } from '@kubb/core' +/** + * `useFileManager` will return the current FileManager instance. + */ export function useFileManager(): FileManager { const app = useApp<{ pluginManager: PluginManager }>() diff --git a/packages/react/src/hooks/useLanguage.ts b/packages/react/src/hooks/useLanguage.ts index ae4c59c0b..b50939ff0 100644 --- a/packages/react/src/hooks/useLanguage.ts +++ b/packages/react/src/hooks/useLanguage.ts @@ -4,6 +4,9 @@ import { Editor } from '../components/index.ts' import type { EditorContextProps } from '../components/Editor.tsx' +/** + * `useLanguage` will return the current language set by the parent `Editor` component. + */ export function useLanguage(): EditorContextProps { return useContext(Editor.Context) } diff --git a/packages/react/src/hooks/useMeta.ts b/packages/react/src/hooks/useMeta.ts index 3cf0f64d8..a5c97025f 100644 --- a/packages/react/src/hooks/useMeta.ts +++ b/packages/react/src/hooks/useMeta.ts @@ -2,6 +2,9 @@ import { useApp } from './useApp.ts' import type { AppContextProps } from '../components/App.tsx' +/** + * `useMeta` will return an object containing the meta that has been provided with the `root.render` functionality. + */ export function useMeta = Record>(): AppContextProps['meta'] { const app = useApp() diff --git a/packages/react/src/hooks/usePackageVersion.ts b/packages/react/src/hooks/usePackageVersion.ts index 83e146dda..005f6800b 100644 --- a/packages/react/src/hooks/usePackageVersion.ts +++ b/packages/react/src/hooks/usePackageVersion.ts @@ -4,7 +4,9 @@ type Props = { dependency: string version: string } - +/** + * With `usePackageVersion` you can validate of a specific package is set in the `package.json`. + */ export function usePackageVersion({ dependency, version }: Props): boolean { const manager = new PackageManager() diff --git a/packages/react/src/hooks/usePlugin.ts b/packages/react/src/hooks/usePlugin.ts index 89f846066..c18168080 100644 --- a/packages/react/src/hooks/usePlugin.ts +++ b/packages/react/src/hooks/usePlugin.ts @@ -2,6 +2,9 @@ import { useApp } from './useApp.ts' import type { Plugin, PluginFactoryOptions } from '@kubb/core' +/** + * `usePlugin` will return the current plugin. + */ export function usePlugin(): Plugin { const app = useApp<{ plugin: Plugin }>() diff --git a/packages/react/src/hooks/usePluginManager.ts b/packages/react/src/hooks/usePluginManager.ts index cbdbb1b55..cbe8b8346 100644 --- a/packages/react/src/hooks/usePluginManager.ts +++ b/packages/react/src/hooks/usePluginManager.ts @@ -2,6 +2,9 @@ import { useApp } from './useApp.ts' import type { PluginManager } from '@kubb/core' +/** + * `usePluginManager` will return the PluginManager instance. + */ export function usePluginManager(): PluginManager { const app = useApp<{ pluginManager: PluginManager }>() diff --git a/packages/react/src/hooks/useResolveName.ts b/packages/react/src/hooks/useResolveName.ts index a75640e43..7215259d9 100644 --- a/packages/react/src/hooks/useResolveName.ts +++ b/packages/react/src/hooks/useResolveName.ts @@ -4,6 +4,10 @@ import type { ResolveNameParams } from '@kubb/core' type Props = ResolveNameParams +/** + * Resolve a name based on what has been set inside the `resolveName` of a specific plugin. + * Use `pluginKey` to retreive the name of that specific plugin. + */ export function useResolveName(props: Props): string { const pluginManager = usePluginManager() diff --git a/packages/react/src/hooks/useResolvePath.ts b/packages/react/src/hooks/useResolvePath.ts index 73ff6a70c..4162f376e 100644 --- a/packages/react/src/hooks/useResolvePath.ts +++ b/packages/react/src/hooks/useResolvePath.ts @@ -4,6 +4,10 @@ import type { KubbFile, ResolvePathParams } from '@kubb/core' type Props = ResolvePathParams +/** + * Resolve a path based on what has been set inside the `resolvePath` of a specific plugin. + * Use `pluginKey` to retreive the path of that specific plugin. + */ export function useResolvePath(props: Props): KubbFile.OptionalPath { const pluginManager = usePluginManager() diff --git a/packages/react/src/shared/ReactTemplate.tsx b/packages/react/src/shared/ReactTemplate.tsx index 63b69c750..e0b97c08d 100644 --- a/packages/react/src/shared/ReactTemplate.tsx +++ b/packages/react/src/shared/ReactTemplate.tsx @@ -106,10 +106,9 @@ export class ReactTemplate { this.#lastFiles = files } onError(error: Error): void { - if (process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'development') { + if (process.env.NODE_ENV === 'test') { console.error(error) } - if (!this.logger) { console.error(error) } diff --git a/packages/swagger-client/src/OperationGenerator.test.tsx b/packages/swagger-client/src/OperationGenerator.test.tsx index 60542b09a..8496e4924 100644 --- a/packages/swagger-client/src/OperationGenerator.test.tsx +++ b/packages/swagger-client/src/OperationGenerator.test.tsx @@ -93,7 +93,7 @@ describe('OperationGenerator', async () => { operations: Operations.templates, client: { default: CustomClientTemplate, - editor: Client.templates.editor, + root: Client.templates.root, }, }, client: { diff --git a/packages/swagger-client/src/components/Client.tsx b/packages/swagger-client/src/components/Client.tsx index bf4997a1a..66c406064 100644 --- a/packages/swagger-client/src/components/Client.tsx +++ b/packages/swagger-client/src/components/Client.tsx @@ -76,11 +76,11 @@ return ${client.dataReturnType === 'data' ? 'res.data' : 'res'} ) } -type EditorTemplateProps = { +type RootTemplateProps = { children?: React.ReactNode } -function EditorTemplate({ children }: EditorTemplateProps) { +function RootTemplate({ children }: RootTemplateProps) { const { options: { client: { importPath } } } = usePlugin() const schemas = useSchemas() @@ -112,7 +112,7 @@ function EditorTemplate({ children }: EditorTemplateProps) { ) } -const defaultTemplates = { default: Template, editor: EditorTemplate } as const +const defaultTemplates = { default: Template, root: RootTemplate } as const type Templates = Partial @@ -195,12 +195,12 @@ Client.File = function(props: FileProps): KubbNode { const templates = { ...defaultTemplates, ...props.templates } const Template = templates.default - const EditorTemplate = templates.editor + const RootTemplate = templates.root return ( - + - + ) } diff --git a/packages/swagger-client/src/components/Operations.tsx b/packages/swagger-client/src/components/Operations.tsx index c5e45b0d9..a98441d47 100644 --- a/packages/swagger-client/src/components/Operations.tsx +++ b/packages/swagger-client/src/components/Operations.tsx @@ -36,11 +36,11 @@ function Template({ ) } -type EditorTemplateProps = { +type RootTemplateProps = { children?: React.ReactNode } -function EditorTemplate({ children }: EditorTemplateProps) { +function RootTemplate({ children }: RootTemplateProps) { const { key: pluginKey } = usePlugin() const file = useFile({ name: 'operations', extName: '.ts', pluginKey }) @@ -59,7 +59,7 @@ function EditorTemplate({ children }: EditorTemplateProps) { ) } -const defaultTemplates = { default: Template, editor: EditorTemplate } as const +const defaultTemplates = { default: Template, root: RootTemplate } as const type Templates = Partial @@ -94,12 +94,12 @@ Operations.File = function(props: FileProps): KubbNode { const templates = { ...defaultTemplates, ...props.templates } const Template = templates.default - const EditorTemplate = templates.editor + const RootTemplate = templates.root return ( - + - + ) } diff --git a/packages/swagger-faker/src/components/Mutation.tsx b/packages/swagger-faker/src/components/Mutation.tsx index a83580921..16e68c573 100644 --- a/packages/swagger-faker/src/components/Mutation.tsx +++ b/packages/swagger-faker/src/components/Mutation.tsx @@ -30,7 +30,7 @@ Mutation.File = function({}: FileProps): ReactNode { const schemas = useSchemas() const pluginManager = usePluginManager() - const { oas } = useOas() + const oas = useOas() const file = useOperationFile() const builder = new FakerBuilder(options, { oas, pluginManager }) diff --git a/packages/swagger-faker/src/components/Query.tsx b/packages/swagger-faker/src/components/Query.tsx index f55f64cc6..d5d56eb54 100644 --- a/packages/swagger-faker/src/components/Query.tsx +++ b/packages/swagger-faker/src/components/Query.tsx @@ -30,7 +30,7 @@ Query.File = function({}: FileProps): ReactNode { const schemas = useSchemas() const pluginManager = usePluginManager() - const { oas } = useOas() + const oas = useOas() const file = useOperationFile() const builder = new FakerBuilder(options, { oas, pluginManager }) diff --git a/packages/swagger-msw/src/components/Operations.tsx b/packages/swagger-msw/src/components/Operations.tsx index fbc6caadd..61eddf558 100644 --- a/packages/swagger-msw/src/components/Operations.tsx +++ b/packages/swagger-msw/src/components/Operations.tsx @@ -29,17 +29,17 @@ type EditorTemplateProps = { children?: React.ReactNode } -function EditorTemplate({ children }: EditorTemplateProps) { +function RootTemplate({ children }: EditorTemplateProps) { const { key: pluginKey } = usePlugin() const file = useFile({ name: 'handlers', extName: '.ts', pluginKey }) const operations = useOperations() - const { getOperationName, getOperationFile } = useOperationHelpers() + const { getName, getFile } = useOperationHelpers() const imports = operations.map(operation => { - const operationFile = getOperationFile(operation, { pluginKey }) - const operationName = getOperationName(operation, { pluginKey, type: 'function' }) + const operationFile = getFile(operation, { pluginKey }) + const operationName = getName(operation, { pluginKey, type: 'function' }) return }).filter(Boolean) @@ -60,7 +60,7 @@ function EditorTemplate({ children }: EditorTemplateProps) { ) } -const defaultTemplates = { default: Template, editor: EditorTemplate } as const +const defaultTemplates = { default: Template, root: RootTemplate } as const type Templates = Partial @@ -77,12 +77,12 @@ export function Operations({ const { key: pluginKey } = usePlugin() const operations = useOperations() - const { getOperationName } = useOperationHelpers() + const { getName } = useOperationHelpers() return (