Skip to content

Commit 0c4e6d2

Browse files
authored
Merge pull request #2854 from labmorales/feat/add_ts_enums_rtk
2 parents 2fe9e73 + fe74bc6 commit 0c4e6d2

File tree

9 files changed

+117
-106
lines changed

9 files changed

+117
-106
lines changed

packages/rtk-query-codegen-openapi/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"prepare": "npm run build && chmod +x ./lib/bin/cli.js",
2222
"format": "prettier --write \"src/**/*.ts\"",
2323
"test:update": "lib/bin/cli.js test/fixtures/petstore.json --file test/fixtures/generated.ts -h",
24+
"test:update:enum": "lib/bin/cli.js test/config.example.enum.ts",
2425
"test": "jest --runInBand",
2526
"cli": "esr src/bin/cli.ts"
2627
},
@@ -56,12 +57,12 @@
5657
},
5758
"dependencies": {
5859
"@apidevtools/swagger-parser": "^10.0.2",
59-
"@rtk-query/oazapfts-patched": "^3.6.0-2",
6060
"commander": "^6.2.0",
61+
"oazapfts": "^4.2.0",
6162
"prettier": "^2.2.1",
6263
"semver": "^7.3.5",
6364
"swagger2openapi": "^7.0.4",
64-
"typescript": ">=4.1 <=4.5"
65+
"typescript": "^4.9.3"
6566
},
6667
"husky": {
6768
"hooks": {

packages/rtk-query-codegen-openapi/src/bin/cli.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
#!/usr/bin/env node
22

3-
import program from 'commander';
43
import { dirname, resolve } from 'path';
54
import { generateEndpoints, parseConfig } from '../';
6-
import semver from 'semver';
7-
import { version as tsVersion } from 'typescript';
85

9-
if (!semver.satisfies(tsVersion, '>=4.1 <=4.5')) {
10-
console.warn(
11-
'Please note that `@rtk-query/codegen-openapi` only has been tested with TS versions 4.1 to 4.5 - other versions might cause problems.'
12-
);
13-
}
6+
import program from 'commander';
147

158
let ts = false;
169
try {

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

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import ts from 'typescript';
21
import { factory } from './utils/factory';
2+
import ts from 'typescript';
33

44
const defaultEndpointBuilder = factory.createIdentifier('build');
55

@@ -12,7 +12,6 @@ export function generateObjectProperties(obj: ObjectPropertyDefinitions) {
1212

1313
export function generateImportNode(pkg: string, namedImports: Record<string, string>, defaultImportName?: string) {
1414
return factory.createImportDeclaration(
15-
undefined,
1615
undefined,
1716
factory.createImportClause(
1817
false,
@@ -44,17 +43,7 @@ export function generateCreateApiCall({
4443
endpoints: factory.createArrowFunction(
4544
undefined,
4645
undefined,
47-
[
48-
factory.createParameterDeclaration(
49-
undefined,
50-
undefined,
51-
undefined,
52-
endpointBuilder,
53-
undefined,
54-
undefined,
55-
undefined
56-
),
57-
],
46+
[factory.createParameterDeclaration(undefined, undefined, endpointBuilder, undefined, undefined, undefined)],
5847
undefined,
5948
factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
6049
factory.createParenthesizedExpression(endpointDefinitions)
@@ -67,30 +56,32 @@ export function generateCreateApiCall({
6756
const enhanceEndpointsObjectLiteralExpression = factory.createObjectLiteralExpression(
6857
[factory.createShorthandPropertyAssignment(factory.createIdentifier('addTagTypes'), undefined)],
6958
true
70-
)
59+
);
7160
return factory.createVariableStatement(
7261
undefined,
7362
factory.createVariableDeclarationList(
74-
[factory.createVariableDeclaration(
75-
factory.createIdentifier("injectedRtkApi"),
76-
undefined,
77-
undefined,
78-
factory.createCallExpression(
79-
factory.createPropertyAccessExpression(
80-
factory.createCallExpression(
81-
factory.createPropertyAccessExpression(
82-
factory.createIdentifier("api"),
83-
factory.createIdentifier("enhanceEndpoints")
63+
[
64+
factory.createVariableDeclaration(
65+
factory.createIdentifier('injectedRtkApi'),
66+
undefined,
67+
undefined,
68+
factory.createCallExpression(
69+
factory.createPropertyAccessExpression(
70+
factory.createCallExpression(
71+
factory.createPropertyAccessExpression(
72+
factory.createIdentifier('api'),
73+
factory.createIdentifier('enhanceEndpoints')
74+
),
75+
undefined,
76+
[enhanceEndpointsObjectLiteralExpression]
8477
),
85-
undefined,
86-
[enhanceEndpointsObjectLiteralExpression]
78+
factory.createIdentifier('injectEndpoints')
8779
),
88-
factory.createIdentifier("injectEndpoints")
89-
),
90-
undefined,
91-
[injectEndpointsObjectLiteralExpression]
92-
)
93-
)],
80+
undefined,
81+
[injectEndpointsObjectLiteralExpression]
82+
)
83+
),
84+
],
9485
ts.NodeFlags.Const
9586
)
9687
);
@@ -145,21 +136,16 @@ export function generateEndpointDefinition({
145136
factory.createIdentifier(type === 'query' ? 'providesTags' : 'invalidatesTags'),
146137
factory.createArrayLiteralExpression(tags.map((tag) => factory.createStringLiteral(tag), false))
147138
)
148-
)
139+
);
149140
}
150141
return factory.createPropertyAssignment(
151142
factory.createIdentifier(operationName),
152143

153144
factory.createCallExpression(
154145
factory.createPropertyAccessExpression(endpointBuilder, factory.createIdentifier(type)),
155146
[Response, QueryArg],
156-
[
157-
factory.createObjectLiteralExpression(
158-
objectProperties,
159-
true
160-
),
161-
]
162-
),
147+
[factory.createObjectLiteralExpression(objectProperties, true)]
148+
)
163149
);
164150
}
165151

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

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
1-
import ts from 'typescript';
21
import * as path from 'path';
3-
import { camelCase } from 'lodash';
2+
43
import ApiGenerator, {
54
getOperationName as _getOperationName,
65
getReferenceName,
76
isReference,
87
supportDeepObjects,
9-
} from '@rtk-query/oazapfts-patched/lib/codegen/generate';
8+
} from 'oazapfts/lib/codegen/generate';
9+
import type { EndpointMatcher, EndpointOverrides, GenerationOptions, OperationDefinition, TextMatcher } from './types';
10+
import { capitalize, getOperationDefinitions, getV3Doc, removeUndefined, isQuery as testIsQuery } from './utils';
1011
import {
11-
createQuestionToken,
12-
keywordType,
1312
createPropertyAssignment,
13+
createQuestionToken,
1414
isValidIdentifier,
15-
} from '@rtk-query/oazapfts-patched/lib/codegen/tscodegen';
16-
import type { OpenAPIV3 } from 'openapi-types';
17-
import { generateReactHooks } from './generators/react-hooks';
18-
import type { EndpointMatcher, EndpointOverrides, GenerationOptions, OperationDefinition, TextMatcher } from './types';
19-
import { capitalize, getOperationDefinitions, getV3Doc, isQuery as testIsQuery, removeUndefined } from './utils';
20-
import { generateTagTypes } from './codegen';
15+
keywordType,
16+
} from 'oazapfts/lib/codegen/tscodegen';
17+
import { generateCreateApiCall, generateEndpointDefinition, generateImportNode, generateTagTypes } from './codegen';
18+
2119
import type { ObjectPropertyDefinitions } from './codegen';
22-
import { generateCreateApiCall, generateEndpointDefinition, generateImportNode } from './codegen';
20+
import type { OpenAPIV3 } from 'openapi-types';
21+
import { camelCase } from 'lodash';
2322
import { factory } from './utils/factory';
23+
import { generateReactHooks } from './generators/react-hooks';
24+
import ts from 'typescript';
2425

2526
const generatedApiName = 'injectedRtkApi';
2627

@@ -92,12 +93,14 @@ export async function generateApi(
9293
endpointOverrides,
9394
unionUndefined,
9495
flattenArg = false,
96+
useEnumType = false,
9597
}: GenerationOptions
9698
) {
9799
const v3Doc = await getV3Doc(spec);
98100

99101
const apiGen = new ApiGenerator(v3Doc, {
100102
unionUndefined,
103+
useEnumType,
101104
});
102105

103106
const operationDefinitions = getOperationDefinitions(v3Doc).filter(operationMatches(filterEndpoints));
@@ -131,7 +134,7 @@ export async function generateApi(
131134
}
132135
apiFile = apiFile.replace(/\.[jt]sx?$/, '');
133136

134-
const sourceCode = printer.printNode(
137+
return printer.printNode(
135138
ts.EmitHint.Unspecified,
136139
factory.createSourceFile(
137140
[
@@ -150,7 +153,6 @@ export async function generateApi(
150153
),
151154
}),
152155
factory.createExportDeclaration(
153-
undefined,
154156
undefined,
155157
false,
156158
factory.createNamedExports([
@@ -162,7 +164,8 @@ export async function generateApi(
162164
undefined
163165
),
164166
...Object.values(interfaces),
165-
...apiGen['aliases'],
167+
...apiGen.aliases,
168+
...apiGen.enumAliases,
166169
...(hooks
167170
? [
168171
generateReactHooks({
@@ -180,8 +183,6 @@ export async function generateApi(
180183
resultFile
181184
);
182185

183-
return sourceCode;
184-
185186
function extractAllTagTypes({ operationDefinitions }: { operationDefinitions: OperationDefinition[] }) {
186187
let allTagTypes = new Set<string>();
187188

@@ -242,7 +243,6 @@ export async function generateApi(
242243
const ResponseTypeName = factory.createTypeReferenceNode(
243244
registerInterface(
244245
factory.createTypeAliasDeclaration(
245-
undefined,
246246
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
247247
capitalize(operationName + responseSuffix),
248248
undefined,
@@ -259,7 +259,7 @@ export async function generateApi(
259259
const allNames = parameters.map((p) => p.name);
260260
const queryArg: QueryArgDefinitions = {};
261261
for (const param of parameters) {
262-
const isPureSnakeCase = /^[a-zA-Z][a-zA-Z0-9_]*$/.test(param.name);
262+
const isPureSnakeCase = /^[a-zA-Z][\\w]*$/.test(param.name);
263263
const camelCaseName = camelCase(param.name);
264264

265265
const name = isPureSnakeCase && !allNames.includes(camelCaseName) ? camelCaseName : param.name;
@@ -309,7 +309,6 @@ export async function generateApi(
309309
const QueryArg = factory.createTypeReferenceNode(
310310
registerInterface(
311311
factory.createTypeAliasDeclaration(
312-
undefined,
313312
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
314313
capitalize(operationName + argSuffix),
315314
undefined,
@@ -391,17 +390,7 @@ export async function generateApi(
391390
undefined,
392391
undefined,
393392
Object.keys(queryArg).length
394-
? [
395-
factory.createParameterDeclaration(
396-
undefined,
397-
undefined,
398-
undefined,
399-
rootObject,
400-
undefined,
401-
undefined,
402-
undefined
403-
),
404-
]
393+
? [factory.createParameterDeclaration(undefined, undefined, rootObject, undefined, undefined, undefined)]
405394
: [],
406395
undefined,
407396
factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
@@ -461,7 +450,7 @@ function generatePathExpression(
461450
) {
462451
const expressions: Array<[string, string]> = [];
463452

464-
const head = path.replace(/\{(.*?)\}(.*?)(?=\{|$)/g, (_, expression, literal) => {
453+
const head = path.replace(/\{(.*?)}(.*?)(?=\{|$)/g, (_, expression, literal) => {
465454
const param = pathParameters.find((p) => p.originalName === expression);
466455
if (!param) {
467456
throw new Error(`path parameter ${expression} does not seem to be defined in '${path}'!`);

packages/rtk-query-codegen-openapi/src/generators/react-hooks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import ts from 'typescript';
2-
import { getOperationName } from '@rtk-query/oazapfts-patched/lib/codegen/generate';
2+
import { getOperationName } from 'oazapfts/lib/codegen/generate';
33
import { capitalize, isQuery } from '../utils';
44
import type { OperationDefinition, EndpointOverrides, ConfigFile } from '../types';
55
import { getOverrides } from '../generate';

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ export function parseConfig(fullConfig: ConfigFile) {
4242
}
4343

4444
/**
45-
* Enforces `@rtk-query/oazapfts-patched` to use the same TypeScript version as this module itself uses.
45+
* Enforces `oazapfts` to use the same TypeScript version as this module itself uses.
4646
* That should prevent enums from running out of sync if both libraries use different TS versions.
4747
*/
4848
function enforceOazapftsTsVersion<T>(cb: () => T): T {
49-
const ozTsPath = require.resolve('typescript', { paths: [require.resolve('@rtk-query/oazapfts-patched')] });
49+
const ozTsPath = require.resolve('typescript', { paths: [require.resolve('oazapfts')] });
5050
const tsPath = require.resolve('typescript');
5151
const originalEntry = require.cache[ozTsPath];
5252
try {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ export interface OutputFileOptions extends Partial<CommonOptions> {
7979
outputFile: string;
8080
filterEndpoints?: EndpointMatcher;
8181
endpointOverrides?: EndpointOverrides[];
82+
/**
83+
* defaults to false
84+
* If passed as true it will generate TS enums instead of union of strings
85+
*/
86+
useEnumType?: boolean;
8287
}
8388

8489
export interface EndpointOverrides {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import type { ConfigFile } from '@rtk-query/codegen-openapi';
2+
3+
const config: ConfigFile = {
4+
schemaFile: './fixtures/petstore.yaml',
5+
apiFile: './fixtures/emptyApi.ts',
6+
outputFile: './tmp/example.ts',
7+
useEnumType: true,
8+
};
9+
10+
export default config;

0 commit comments

Comments
 (0)