Skip to content

Commit

Permalink
Codegen: add operation name suffix
Browse files Browse the repository at this point in the history
  • Loading branch information
Георгиев Антон Стоев (4084897) committed Oct 19, 2023
1 parent 568680d commit 15d14b0
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 55 deletions.
3 changes: 2 additions & 1 deletion docs/rtk-query/usage/code-generation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ npx @rtk-query/codegen-openapi openapi-config.ts

#### Generating tags

If your OpenAPI specification uses [tags](https://swagger.io/docs/specification/grouping-operations-with-tags/), you can specify the `tag` option to the codegen.
If your OpenAPI specification uses [tags](https://swagger.io/docs/specification/grouping-operations-with-tags/), you can specify the `tag` option to the codegen.
That will result in all generated endpoints having `providesTags`/`invalidatesTags` declarations for the `tags` of their respective operation definition.

Note that this will only result in string tags with no ids, so it might lead to scenarios where too much is invalidated and unneccessary requests are made on mutation.
Expand Down Expand Up @@ -95,6 +95,7 @@ interface SimpleUsage {
apiImport?: string
exportName?: string
argSuffix?: string
operationNameSuffix?: string
responseSuffix?: string
hooks?:
| boolean
Expand Down
111 changes: 57 additions & 54 deletions packages/rtk-query-codegen-openapi/src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export async function generateApi(
exportName = 'enhancedApi',
argSuffix = 'ApiArg',
responseSuffix = 'ApiResponse',
operationNameSuffix = '',
hooks = false,
tag = false,
outputFile,
Expand Down Expand Up @@ -173,13 +174,13 @@ export async function generateApi(
...apiGen.enumAliases,
...(hooks
? [
generateReactHooks({
exportName: generatedApiName,
operationDefinitions,
endpointOverrides,
config: hooks,
}),
]
generateReactHooks({
exportName: generatedApiName,
operationDefinitions,
endpointOverrides,
config: hooks,
}),
]
: []),
],
factory.createToken(ts.SyntaxKind.EndOfFileToken),
Expand Down Expand Up @@ -250,7 +251,7 @@ export async function generateApi(
registerInterface(
factory.createTypeAliasDeclaration(
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
capitalize(operationName + responseSuffix),
capitalize(operationName + operationNameSuffix + responseSuffix),
undefined,
ResponseType
)
Expand Down Expand Up @@ -299,7 +300,9 @@ export async function generateApi(
const body = apiGen.resolve(requestBody);
const schema = apiGen.getSchemaFromContent(body.content);
const type = apiGen.getTypeFromSchema(schema);
const schemaName = camelCase((type as any).name || getReferenceName(schema) || ("title" in schema && schema.title) || 'body');
const schemaName = camelCase(
(type as any).name || getReferenceName(schema) || ('title' in schema && schema.title) || 'body'
);
const name = generateName(schemaName in queryArg ? 'body' : schemaName, 'body');

queryArg[name] = {
Expand Down Expand Up @@ -327,32 +330,32 @@ export async function generateApi(
registerInterface(
factory.createTypeAliasDeclaration(
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
capitalize(operationName + argSuffix),
capitalize(operationName + operationNameSuffix + argSuffix),
undefined,
queryArgValues.length > 0
? isFlatArg
? withQueryComment({ ...queryArgValues[0].type }, queryArgValues[0], false)
: factory.createTypeLiteralNode(
queryArgValues.map((def) =>
withQueryComment(
factory.createPropertySignature(
undefined,
propertyName(def.name),
createQuestionToken(!def.required),
def.type
),
def,
true
queryArgValues.map((def) =>
withQueryComment(
factory.createPropertySignature(
undefined,
propertyName(def.name),
createQuestionToken(!def.required),
def.type
),
def,
true
)
)
)
)
: factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)
)
).name
);

return generateEndpointDefinition({
operationName,
operationName: operationNameSuffix ? capitalize(operationName + operationNameSuffix) : operationName,
type: isQuery ? 'query' : 'mutation',
Response: ResponseTypeName,
QueryArg,
Expand Down Expand Up @@ -389,18 +392,18 @@ export async function generateApi(
return parameters.length === 0
? undefined
: factory.createPropertyAssignment(
factory.createIdentifier(propertyName),
factory.createObjectLiteralExpression(
parameters.map(
(param) =>
createPropertyAssignment(
param.originalName,
isFlatArg ? rootObject : accessProperty(rootObject, param.name)
),
true
factory.createIdentifier(propertyName),
factory.createObjectLiteralExpression(
parameters.map(
(param) =>
createPropertyAssignment(
param.originalName,
isFlatArg ? rootObject : accessProperty(rootObject, param.name)
),
true
)
)
)
);
);
}

return factory.createArrowFunction(
Expand All @@ -421,17 +424,17 @@ export async function generateApi(
isQuery && verb.toUpperCase() === 'GET'
? undefined
: factory.createPropertyAssignment(
factory.createIdentifier('method'),
factory.createStringLiteral(verb.toUpperCase())
),
factory.createIdentifier('method'),
factory.createStringLiteral(verb.toUpperCase())
),
bodyParameter === undefined
? undefined
: factory.createPropertyAssignment(
factory.createIdentifier('body'),
isFlatArg
? rootObject
: factory.createPropertyAccessExpression(rootObject, factory.createIdentifier(bodyParameter.name))
),
factory.createIdentifier('body'),
isFlatArg
? rootObject
: factory.createPropertyAccessExpression(rootObject, factory.createIdentifier(bodyParameter.name))
),
createObjectLiteralProperty(pickParams('cookie'), 'cookies'),
createObjectLiteralProperty(pickParams('header'), 'headers'),
createObjectLiteralProperty(pickParams('query'), 'params'),
Expand All @@ -443,12 +446,12 @@ export async function generateApi(
}

// eslint-disable-next-line no-empty-pattern
function generateQueryEndpointProps({ }: { operationDefinition: OperationDefinition }): ObjectPropertyDefinitions {
function generateQueryEndpointProps({}: { operationDefinition: OperationDefinition }): ObjectPropertyDefinitions {
return {}; /* TODO needs implementation - skip for now */
}

// eslint-disable-next-line no-empty-pattern
function generateMutationEndpointProps({ }: { operationDefinition: OperationDefinition }): ObjectPropertyDefinitions {
function generateMutationEndpointProps({}: { operationDefinition: OperationDefinition }): ObjectPropertyDefinitions {
return {}; /* TODO needs implementation - skip for now */
}
}
Expand Down Expand Up @@ -478,16 +481,16 @@ function generatePathExpression(

return expressions.length
? factory.createTemplateExpression(
factory.createTemplateHead(head),
expressions.map(([prop, literal], index) =>
factory.createTemplateSpan(
isFlatArg ? rootObject : accessProperty(rootObject, prop),
index === expressions.length - 1
? factory.createTemplateTail(literal)
: factory.createTemplateMiddle(literal)
factory.createTemplateHead(head),
expressions.map(([prop, literal], index) =>
factory.createTemplateSpan(
isFlatArg ? rootObject : accessProperty(rootObject, prop),
index === expressions.length - 1
? factory.createTemplateTail(literal)
: factory.createTemplateMiddle(literal)
)
)
)
)
: factory.createNoSubstitutionTemplateLiteral(head);
}

Expand All @@ -498,13 +501,13 @@ type QueryArgDefinition = {
required?: boolean;
param?: OpenAPIV3.ParameterObject;
} & (
| {
| {
origin: 'param';
param: OpenAPIV3.ParameterObject;
}
| {
| {
origin: 'body';
body: OpenAPIV3.RequestBodyObject;
}
);
);
type QueryArgDefinitions = Record<string, QueryArgDefinition>;
4 changes: 4 additions & 0 deletions packages/rtk-query-codegen-openapi/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export interface CommonOptions {
* defaults to "ApiResponse"
*/
responseSuffix?: string;
/**
* defaults to empty
*/
operationNameSuffix?: string;
/**
* defaults to `false`
* `true` will generate hooks for queries and mutations, but no lazyQueries
Expand Down

0 comments on commit 15d14b0

Please sign in to comment.