Skip to content

Commit 46a5e59

Browse files
authored
Merge pull request #2059 from hey-api/fix/enum-const-ignore-null
fix(typescript): add enumsConstantsIgnoreNull option to skip nulls from generated JavaScript objects
2 parents f64b4c5 + af2082f commit 46a5e59

File tree

11 files changed

+187
-5
lines changed

11 files changed

+187
-5
lines changed

.changeset/smooth-masks-buy.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hey-api/openapi-ts': patch
3+
---
4+
5+
fix(typescript): add enumsConstantsIgnoreNull option to skip nulls from generated JavaScript objects

packages/openapi-ts-tests/test/3.0.x.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,22 @@ describe(`OpenAPI ${version}`, () => {
324324
description:
325325
'handles various enum names and values (JavaScript, preserve)',
326326
},
327+
{
328+
config: createConfig({
329+
input: 'enum-names-values.json',
330+
output: 'enum-names-values-javascript-ignore-null',
331+
plugins: [
332+
{
333+
enums: 'javascript',
334+
enumsCase: 'preserve',
335+
enumsConstantsIgnoreNull: true,
336+
name: '@hey-api/typescript',
337+
},
338+
],
339+
}),
340+
description:
341+
'handles various enum names and values (JavaScript, preserve, ignore null)',
342+
},
327343
{
328344
config: createConfig({
329345
input: 'enum-names-values.json',

packages/openapi-ts-tests/test/3.1.x.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,22 @@ describe(`OpenAPI ${version}`, () => {
338338
description:
339339
'handles various enum names and values (JavaScript, preserve)',
340340
},
341+
{
342+
config: createConfig({
343+
input: 'enum-names-values.json',
344+
output: 'enum-names-values-javascript-ignore-null',
345+
plugins: [
346+
{
347+
enums: 'javascript',
348+
enumsCase: 'preserve',
349+
enumsConstantsIgnoreNull: true,
350+
name: '@hey-api/typescript',
351+
},
352+
],
353+
}),
354+
description:
355+
'handles various enum names and values (JavaScript, preserve, ignore null)',
356+
},
341357
{
342358
config: createConfig({
343359
input: 'enum-names-values.json',
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
export * from './types.gen';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
3+
export type _110 = '1-10' | '11-20';
4+
5+
export const _110 = {
6+
'1-10': '1-10',
7+
'11-20': '11-20'
8+
} as const;
9+
10+
export type MyFoo = 'myFoo' | 'myBar';
11+
12+
export const MyFoo = {
13+
myFoo: 'myFoo',
14+
myBar: 'myBar'
15+
} as const;
16+
17+
export type MyFoo2 = 'MyFoo' | 'MyBar';
18+
19+
export const MyFoo2 = {
20+
MyFoo: 'MyFoo',
21+
MyBar: 'MyBar'
22+
} as const;
23+
24+
export type Foo = 'foo' | 'bar' | null | '' | true | false;
25+
26+
export const Foo = {
27+
foo: 'foo',
28+
bar: 'bar',
29+
'': '',
30+
true: true,
31+
false: false
32+
} as const;
33+
34+
export type Numbers = 100 | 200 | 300 | -100 | -200 | -300;
35+
36+
export const Numbers = {
37+
100: 100,
38+
200: 200,
39+
300: 300,
40+
'-100': -100,
41+
'-200': -200,
42+
'-300': -300
43+
} as const;
44+
45+
export type Arrays = [
46+
'foo'
47+
] | [
48+
'bar'
49+
] | [
50+
'baz'
51+
];
52+
53+
export const Arrays = {
54+
0: ['foo'],
55+
1: ['bar'],
56+
2: ['baz']
57+
} as const;
58+
59+
export type ClientOptions = {
60+
baseUrl: `${string}://${string}` | (string & {});
61+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
export * from './types.gen';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
3+
export type _110 = '1-10' | '11-20';
4+
5+
export const _110 = {
6+
'1-10': '1-10',
7+
'11-20': '11-20'
8+
} as const;
9+
10+
export type MyFoo = 'myFoo' | 'myBar';
11+
12+
export const MyFoo = {
13+
myFoo: 'myFoo',
14+
myBar: 'myBar'
15+
} as const;
16+
17+
export type MyFoo2 = 'MyFoo' | 'MyBar';
18+
19+
export const MyFoo2 = {
20+
MyFoo: 'MyFoo',
21+
MyBar: 'MyBar'
22+
} as const;
23+
24+
export type Foo = 'foo' | 'bar' | null | '' | true | false;
25+
26+
export const Foo = {
27+
foo: 'foo',
28+
bar: 'bar',
29+
'': '',
30+
true: true,
31+
false: false
32+
} as const;
33+
34+
export type Numbers = 100 | 200 | 300 | -100 | -200 | -300;
35+
36+
export const Numbers = {
37+
100: 100,
38+
200: 200,
39+
300: 300,
40+
'-100': -100,
41+
'-200': -200,
42+
'-300': -300
43+
} as const;
44+
45+
export type Arrays = [
46+
'foo'
47+
] | [
48+
'bar'
49+
] | [
50+
'baz'
51+
];
52+
53+
export const Arrays = {
54+
0: ['foo'],
55+
1: ['bar'],
56+
2: ['baz']
57+
} as const;
58+
59+
export type ClientOptions = {
60+
baseUrl: `${string}://${string}` | (string & {});
61+
};

packages/openapi-ts-tests/test/openapi-ts.config.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default defineConfig(() => {
3636
// openapi: '3.1.0',
3737
// paths: {},
3838
// },
39-
path: path.resolve(__dirname, 'spec', '3.1.x', 'full.json'),
39+
path: path.resolve(__dirname, 'spec', '3.1.x', 'enum-null.json'),
4040
// path: 'http://localhost:4000/',
4141
// path: 'https://get.heyapi.dev/',
4242
// path: 'https://get.heyapi.dev/hey-api/backend?branch=main&version=1.0.0',
@@ -84,7 +84,7 @@ export default defineConfig(() => {
8484
// auth: false,
8585
// client: false,
8686
// include...
87-
name: '@hey-api/sdk',
87+
// name: '@hey-api/sdk',
8888
// operationId: false,
8989
// serviceNameBuilder: '^Parameters',
9090
// throwOnError: true,
@@ -100,8 +100,9 @@ export default defineConfig(() => {
100100
{
101101
// enums: 'typescript+namespace',
102102
enums: 'javascript',
103-
enumsCase: 'camelCase',
104-
// exportInlineEnums: true,
103+
// enumsCase: 'camelCase',
104+
enumsConstantsIgnoreNull: true,
105+
exportInlineEnums: true,
105106
// identifierCase: 'preserve',
106107
name: '@hey-api/typescript',
107108
// readOnlyWriteOnlyBehavior: 'off',
@@ -114,7 +115,7 @@ export default defineConfig(() => {
114115
},
115116
{
116117
exportFromIndex: true,
117-
name: '@tanstack/react-query',
118+
// name: '@tanstack/react-query',
118119
},
119120
{
120121
// exportFromIndex: true,

packages/openapi-ts/src/plugins/@hey-api/typescript/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const defaultConfig: Plugin.Config<Config> = {
88
_handlerLegacy: handlerLegacy,
99
enums: false,
1010
enumsCase: 'SCREAMING_SNAKE_CASE',
11+
enumsConstantsIgnoreNull: false,
1112
exportFromIndex: true,
1213
exportInlineEnums: false,
1314
identifierCase: 'PascalCase',

packages/openapi-ts/src/plugins/@hey-api/typescript/plugin.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,14 @@ const addJavaScriptEnum = ({
125125

126126
const enumObject = schemaToEnumObject({ plugin, schema });
127127

128+
// JavaScript enums might want to ignore null values
129+
if (
130+
plugin.enumsConstantsIgnoreNull &&
131+
enumObject.typeofItems.includes('object')
132+
) {
133+
enumObject.obj = enumObject.obj.filter((item) => item.value !== null);
134+
}
135+
128136
const expression = compiler.objectExpression({
129137
multiLine: true,
130138
obj: enumObject.obj,

packages/openapi-ts/src/plugins/@hey-api/typescript/types.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ export interface Config extends Plugin.Name<'@hey-api/typescript'> {
1717
* @default 'SCREAMING_SNAKE_CASE'
1818
*/
1919
enumsCase?: StringCase;
20+
/**
21+
* When generating enums as JavaScript objects, they'll contain a null value
22+
* if they're nullable. This might be undesirable if you want to do
23+
* `Object.values(Foo)` and have all values be of the same type. This setting
24+
* is disabled by default to preserve the source schemas.
25+
*
26+
* @default false
27+
*/
28+
enumsConstantsIgnoreNull?: boolean;
2029
/**
2130
* Should the exports from the generated files be re-exported in the index
2231
* barrel file?

0 commit comments

Comments
 (0)