diff --git a/packages/rtk-query-codegen-openapi/src/generate.ts b/packages/rtk-query-codegen-openapi/src/generate.ts index c43ed65946..44d8a31b58 100644 --- a/packages/rtk-query-codegen-openapi/src/generate.ts +++ b/packages/rtk-query-codegen-openapi/src/generate.ts @@ -204,6 +204,7 @@ export async function generateApi( operationDefinitions, endpointOverrides, config: hooks, + operationNameSuffix, }), ] : []), diff --git a/packages/rtk-query-codegen-openapi/src/generators/react-hooks.ts b/packages/rtk-query-codegen-openapi/src/generators/react-hooks.ts index 43232ed07d..91b5baef81 100644 --- a/packages/rtk-query-codegen-openapi/src/generators/react-hooks.ts +++ b/packages/rtk-query-codegen-openapi/src/generators/react-hooks.ts @@ -11,36 +11,40 @@ type GetReactHookNameParams = { operationDefinition: OperationDefinition; endpointOverrides: EndpointOverrides[] | undefined; config: HooksConfigOptions; + operationNameSuffix?: string; }; type CreateBindingParams = { operationDefinition: OperationDefinition; overrides?: EndpointOverrides; isLazy?: boolean; + operationNameSuffix?: string; }; const createBinding = ({ operationDefinition: { verb, path, operation }, overrides, isLazy = false, + operationNameSuffix, }: CreateBindingParams) => factory.createBindingElement( undefined, undefined, factory.createIdentifier( - `use${isLazy ? 'Lazy' : ''}${capitalize(getOperationName(verb, path, operation.operationId))}${ + `use${isLazy ? 'Lazy' : ''}${capitalize(getOperationName(verb, path, operation.operationId))}${operationNameSuffix ?? ''}${ isQuery(verb, overrides) ? 'Query' : 'Mutation' }` ), undefined ); -const getReactHookName = ({ operationDefinition, endpointOverrides, config }: GetReactHookNameParams) => { +const getReactHookName = ({ operationDefinition, endpointOverrides, config, operationNameSuffix }: GetReactHookNameParams) => { const overrides = getOverrides(operationDefinition, endpointOverrides); const baseParams = { operationDefinition, overrides, + operationNameSuffix, }; const _isQuery = isQuery(operationDefinition.verb, overrides); @@ -66,12 +70,14 @@ type GenerateReactHooksParams = { operationDefinitions: OperationDefinition[]; endpointOverrides: EndpointOverrides[] | undefined; config: HooksConfigOptions; + operationNameSuffix?: string; }; export const generateReactHooks = ({ exportName, operationDefinitions, endpointOverrides, config, + operationNameSuffix, }: GenerateReactHooksParams) => factory.createVariableStatement( [factory.createModifier(ts.SyntaxKind.ExportKeyword)], @@ -80,7 +86,7 @@ export const generateReactHooks = ({ factory.createVariableDeclaration( factory.createObjectBindingPattern( operationDefinitions - .map((operationDefinition) => getReactHookName({ operationDefinition, endpointOverrides, config })) + .map((operationDefinition) => getReactHookName({ operationDefinition, endpointOverrides, config, operationNameSuffix })) .flat() ), undefined, diff --git a/packages/rtk-query-codegen-openapi/test/__snapshots__/generateEndpoints.test.ts.snap b/packages/rtk-query-codegen-openapi/test/__snapshots__/generateEndpoints.test.ts.snap index 750d1180c0..b0bd029779 100644 --- a/packages/rtk-query-codegen-openapi/test/__snapshots__/generateEndpoints.test.ts.snap +++ b/packages/rtk-query-codegen-openapi/test/__snapshots__/generateEndpoints.test.ts.snap @@ -2448,6 +2448,64 @@ export const { useLoginUserMutation } = injectedRtkApi; " `; +exports[`hooks generation with operationNameSuffix > should generate an \`useGetPetByIdMySuffixQuery\` query hook and an \`useAddPetMySuffixMutation\` mutation hook 1`] = ` +"import { api } from "./fixtures/emptyApi"; +const injectedRtkApi = api.injectEndpoints({ + endpoints: (build) => ({ + AddPetMySuffix: build.mutation< + AddPetMySuffixApiResponse, + AddPetMySuffixApiArg + >({ + query: (queryArg) => ({ + url: \`/pet\`, + method: "POST", + body: queryArg.pet, + }), + }), + GetPetByIdMySuffix: build.query< + GetPetByIdMySuffixApiResponse, + GetPetByIdMySuffixApiArg + >({ + query: (queryArg) => ({ url: \`/pet/\${queryArg.petId}\` }), + }), + }), + overrideExisting: false, +}); +export { injectedRtkApi as enhancedApi }; +export type AddPetMySuffixApiResponse = + /** status 200 Successful operation */ Pet; +export type AddPetMySuffixApiArg = { + /** Create a new pet in the store */ + pet: Pet; +}; +export type GetPetByIdMySuffixApiResponse = + /** status 200 successful operation */ Pet; +export type GetPetByIdMySuffixApiArg = { + /** ID of pet to return */ + petId: number; +}; +export type Category = { + id?: number | undefined; + name?: string | undefined; +}; +export type Tag = { + id?: number | undefined; + name?: string | undefined; +}; +export type Pet = { + id?: number | undefined; + name: string; + category?: Category | undefined; + photoUrls: string[]; + tags?: Tag[] | undefined; + /** pet status in the store */ + status?: ("available" | "pending" | "sold") | undefined; +}; +export const { useAddPetMySuffixMutation, useGetPetByIdMySuffixQuery } = + injectedRtkApi; +" +`; + exports[`openapi spec > readOnly / writeOnly are merged 1`] = ` "import { api } from "./fixtures/emptyApi"; const injectedRtkApi = api.injectEndpoints({ diff --git a/packages/rtk-query-codegen-openapi/test/generateEndpoints.test.ts b/packages/rtk-query-codegen-openapi/test/generateEndpoints.test.ts index 50024e7210..e542f161f6 100644 --- a/packages/rtk-query-codegen-openapi/test/generateEndpoints.test.ts +++ b/packages/rtk-query-codegen-openapi/test/generateEndpoints.test.ts @@ -348,6 +348,22 @@ test('hooks generation', async () => { ); }); +test('hooks generation with operationNameSuffix', async () => { + const api = await generateEndpoints({ + unionUndefined: true, + apiFile: './fixtures/emptyApi.ts', + schemaFile: resolve(__dirname, 'fixtures/petstore.json'), + filterEndpoints: ['getPetById', 'addPet'], + hooks: true, + operationNameSuffix: 'MySuffix', + }); + expect(api).toContain('useGetPetByIdMySuffixQuery'); + expect(api).toContain('useAddPetMySuffixMutation'); + expect(api).toMatchSnapshot( + 'should generate an `useGetPetByIdMySuffixQuery` query hook and an `useAddPetMySuffixMutation` mutation hook' + ); +}); + it('supports granular hooks generation that includes all query types', async () => { const api = await generateEndpoints({ apiFile: './fixtures/emptyApi.ts',