Skip to content

Commit 8b417da

Browse files
authored
Merge pull request #4305 from sebws/feat/openapi-codegen-override-endpoints-filter-params
2 parents cd42073 + 3585e82 commit 8b417da

File tree

5 files changed

+1567
-21
lines changed

5 files changed

+1567
-21
lines changed

docs/rtk-query/usage/code-generation.mdx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ npx @rtk-query/codegen-openapi openapi-config.ts
6464

6565
#### Generating tags
6666

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

7070
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.
@@ -148,6 +148,34 @@ const withOverride: ConfigFile = {
148148
}
149149
```
150150

151+
You can also filter the parameters that are included for an endpoint, as long as they aren't a path parameter. This filter is of type `ParameterMatcher`. For example, to only include parameters that begin with "x-" for the 'loginUser' endpoint, see the below example.
152+
153+
```ts no-transpile title="openapi-config.ts"
154+
const withOverride: ConfigFile = {
155+
// ...
156+
endpointOverrides: [
157+
{
158+
pattern: 'loginUser',
159+
parameterFilter: /^x-/,
160+
},
161+
],
162+
}
163+
```
164+
165+
For more complex requirements, consider the other possible matchers, such as a `ParameterMatcherFunction`. The below example filters out any parameters that are in the header of the request.
166+
167+
```ts no-transpile title="openapi-config.ts"
168+
const withOverride: ConfigFile = {
169+
// ...
170+
endpointOverrides: [
171+
{
172+
pattern: /.*/,
173+
parameterFilter: (_name, parameter) => parameter.in !== "header",
174+
},
175+
],
176+
}
177+
```
178+
151179
#### Generating hooks
152180

153181
Setting `hooks: true` will generate `useQuery` and `useMutation` hook exports. If you also want `useLazyQuery` hooks generated or more granular control, you can also pass an object in the shape of: `{ queries: boolean; lazyQueries: boolean; mutations: boolean }`.

packages/rtk-query-codegen-openapi/src/generate.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,15 @@ import ts from 'typescript';
1515
import type { ObjectPropertyDefinitions } from './codegen';
1616
import { generateCreateApiCall, generateEndpointDefinition, generateImportNode, generateTagTypes } from './codegen';
1717
import { generateReactHooks } from './generators/react-hooks';
18-
import type { EndpointMatcher, EndpointOverrides, GenerationOptions, OperationDefinition, TextMatcher } from './types';
18+
import type {
19+
EndpointMatcher,
20+
EndpointOverrides,
21+
GenerationOptions,
22+
OperationDefinition,
23+
ParameterDefinition,
24+
ParameterMatcher,
25+
TextMatcher,
26+
} from './types';
1927
import { capitalize, getOperationDefinitions, getV3Doc, removeUndefined, isQuery as testIsQuery } from './utils';
2028
import { factory } from './utils/factory';
2129

@@ -57,6 +65,15 @@ function operationMatches(pattern?: EndpointMatcher) {
5765
};
5866
}
5967

68+
function argumentMatches(pattern?: ParameterMatcher) {
69+
const checkMatch = typeof pattern === 'function' ? pattern : patternMatches(pattern);
70+
return function matcher(argumentDefinition: ParameterDefinition) {
71+
if (!pattern || argumentDefinition.in === 'path') return true;
72+
const argumentName = argumentDefinition.name;
73+
return checkMatch(argumentName, argumentDefinition);
74+
};
75+
}
76+
6077
function withQueryComment<T extends ts.Node>(node: T, def: QueryArgDefinition, hasTrailingNewLine: boolean): T {
6178
const comment = def.origin === 'param' ? def.param.description : def.body.description;
6279
if (comment) {
@@ -264,7 +281,7 @@ export async function generateApi(
264281
const parameters = supportDeepObjects([
265282
...apiGen.resolveArray(pathItem.parameters),
266283
...apiGen.resolveArray(operation.parameters),
267-
]);
284+
]).filter(argumentMatches(overrides?.parameterFilter));
268285

269286
const allNames = parameters.map((p) => p.name);
270287
const queryArg: QueryArgDefinitions = {};

packages/rtk-query-codegen-openapi/src/types.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@ export type OperationDefinition = {
88
operation: OpenAPIV3.OperationObject;
99
};
1010

11+
export type ParameterDefinition = OpenAPIV3.ParameterObject;
12+
1113
type Require<T, K extends keyof T> = { [k in K]-?: NonNullable<T[k]> } & Omit<T, K>;
1214
type Optional<T, K extends keyof T> = { [k in K]?: NonNullable<T[k]> } & Omit<T, K>;
1315
type Id<T> = { [K in keyof T]: T[K] } & {};
16+
type AtLeastOneKey<T> = {
17+
[K in keyof T]-?: Pick<T, K> & Partial<T>;
18+
}[keyof T];
1419

1520
export const operationKeys = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'] as const;
1621

@@ -98,6 +103,10 @@ export type EndpointMatcherFunction = (operationName: string, operationDefinitio
98103

99104
export type EndpointMatcher = TextMatcher | EndpointMatcherFunction;
100105

106+
export type ParameterMatcherFunction = (parameterName: string, parameterDefinition: ParameterDefinition) => boolean;
107+
108+
export type ParameterMatcher = TextMatcher | ParameterMatcherFunction;
109+
101110
export interface OutputFileOptions extends Partial<CommonOptions> {
102111
outputFile: string;
103112
filterEndpoints?: EndpointMatcher;
@@ -109,10 +118,12 @@ export interface OutputFileOptions extends Partial<CommonOptions> {
109118
useEnumType?: boolean;
110119
}
111120

112-
export interface EndpointOverrides {
121+
export type EndpointOverrides = {
113122
pattern: EndpointMatcher;
123+
} & AtLeastOneKey<{
114124
type: 'mutation' | 'query';
115-
}
125+
parameterFilter: ParameterMatcher;
126+
}>;
116127

117128
export type ConfigFile =
118129
| Id<Require<CommonOptions & OutputFileOptions, 'outputFile'>>

0 commit comments

Comments
 (0)