tangled
alpha
login
or
join now
mokkenstorm.dev
/
openapi-ts
0
fork
atom
fork of hey-api/openapi-ts because I need some additional things
0
fork
atom
overview
issues
pulls
pipelines
refactor: clean up class name logic
Lubos
3 months ago
0c58b498
72d36102
+29
-92
11 changed files
expand all
collapse all
unified
split
dev
openapi-ts.config.ts
packages
openapi-ts
src
plugins
@angular
common
httpRequests.ts
httpResources.ts
@hey-api
sdk
shared
class.ts
operation.ts
@pinia
colada
v0
plugin.ts
@tanstack
query-core
v5
plugin.ts
swr
v2
plugin.ts
utils
__tests__
stringCase.test.ts
stringCase.ts
transform.ts
+4
-4
dev/openapi-ts.config.ts
···
38
38
// },
39
39
path: path.resolve(
40
40
getSpecsPath(),
41
41
-
// '3.0.x',
42
42
-
'3.1.x',
41
41
+
'3.0.x',
42
42
+
// '3.1.x',
43
43
// 'circular.yaml',
44
44
// 'dutchie.json',
45
45
// 'enum-names-values.yaml',
···
52
52
// 'pagination-ref.yaml',
53
53
// 'schema-const.yaml',
54
54
// 'sdk-instance.yaml',
55
55
-
// 'sdk-method-class-conflict.yaml',
55
55
+
'sdk-method-class-conflict.yaml',
56
56
// 'sdk-nested-classes.yaml',
57
57
-
'sdk-nested-conflict.yaml',
57
57
+
// 'sdk-nested-conflict.yaml',
58
58
// 'string-with-format.yaml',
59
59
// 'transformers.json',
60
60
// 'transformers-recursive.json',
+1
-5
packages/openapi-ts/src/plugins/@angular/common/httpRequests.ts
···
38
38
operation,
39
39
});
40
40
41
41
-
const classes = operationClasses({
42
42
-
context: plugin.context,
43
43
-
operation,
44
44
-
plugin: sdkPlugin,
45
45
-
});
41
41
+
const classes = operationClasses({ operation, plugin: sdkPlugin });
46
42
47
43
for (const entry of classes.values()) {
48
44
entry.path.forEach((currentClassName, index) => {
+2
-10
packages/openapi-ts/src/plugins/@angular/common/httpResources.ts
···
38
38
operation,
39
39
});
40
40
41
41
-
const classes = operationClasses({
42
42
-
context: plugin.context,
43
43
-
operation,
44
44
-
plugin: sdkPlugin,
45
45
-
});
41
41
+
const classes = operationClasses({ operation, plugin: sdkPlugin });
46
42
47
43
for (const entry of classes.values()) {
48
44
entry.path.forEach((currentClassName, index) => {
···
216
212
217
213
if (plugin.config.httpRequests.asClass) {
218
214
// For class-based request methods, use inject and class hierarchy
219
219
-
const classes = operationClasses({
220
220
-
context: plugin.context,
221
221
-
operation,
222
222
-
plugin: sdkPlugin,
223
223
-
});
215
215
+
const classes = operationClasses({ operation, plugin: sdkPlugin });
224
216
225
217
const firstEntry = Array.from(classes.values())[0];
226
218
if (firstEntry) {
+1
-5
packages/openapi-ts/src/plugins/@hey-api/sdk/shared/class.ts
···
181
181
})
182
182
: undefined;
183
183
184
184
-
const classes = operationClasses({
185
185
-
context: plugin.context,
186
186
-
operation,
187
187
-
plugin,
188
188
-
});
184
184
+
const classes = operationClasses({ operation, plugin });
189
185
190
186
for (const entry of classes.values()) {
191
187
entry.path.forEach((currentClassName, index) => {
+16
-27
packages/openapi-ts/src/plugins/@hey-api/sdk/shared/operation.ts
···
1
1
import type { SymbolMeta } from '@hey-api/codegen-core';
2
2
import { refs } from '@hey-api/codegen-core';
3
3
4
4
-
import type { Context } from '~/ir/context';
5
4
import { statusCodeToGroup } from '~/ir/operation';
6
5
import type { IR } from '~/ir/types';
7
6
import { sanitizeNamespaceIdentifier } from '~/openApi/common/parser/sanitize';
8
7
import { getClientPlugin } from '~/plugins/@hey-api/client-core/utils';
9
8
import { $ } from '~/ts-dsl';
10
9
import { stringCase } from '~/utils/stringCase';
11
11
-
import { transformClassName } from '~/utils/transform';
12
10
13
11
import type { Field, Fields } from '../../client-core/bundle/params';
14
12
import type { HeyApiSdkPlugin } from '../types';
···
18
16
import { getSignatureParameters } from './signature';
19
17
import { createRequestValidator, createResponseValidator } from './validator';
20
18
19
19
+
type Plugin = {
20
20
+
config: Pick<
21
21
+
HeyApiSdkPlugin['Instance']['config'],
22
22
+
'asClass' | 'classNameBuilder' | 'classStructure' | 'instance'
23
23
+
>;
24
24
+
};
25
25
+
21
26
interface ClassNameEntry {
22
27
/**
23
28
* Name of the class where this function appears.
···
34
39
}
35
40
36
41
const operationClassName = ({
37
37
-
context,
42
42
+
plugin,
38
43
value,
39
44
}: {
40
40
-
context: Context;
45
45
+
plugin: Plugin;
41
46
value: string;
42
47
}) => {
43
43
-
const name = stringCase({
44
44
-
case: 'PascalCase',
45
45
-
value: sanitizeNamespaceIdentifier(value),
46
46
-
});
47
47
-
return transformClassName({
48
48
-
config: context.config,
49
49
-
name,
50
50
-
});
48
48
+
const name = stringCase({ case: 'PascalCase', value });
49
49
+
return typeof plugin.config.classNameBuilder === 'string'
50
50
+
? plugin.config.classNameBuilder.replace('{{name}}', name)
51
51
+
: plugin.config.classNameBuilder(name);
51
52
};
52
53
53
54
const getOperationMethodName = ({
···
78
79
* Returns a list of classes where this operation appears in the generated SDK.
79
80
*/
80
81
export const operationClasses = ({
81
81
-
context,
82
82
operation,
83
83
plugin,
84
84
}: {
85
85
-
context: Context;
86
85
operation: IR.OperationObject;
87
87
-
plugin: {
88
88
-
config: Pick<
89
89
-
HeyApiSdkPlugin['Instance']['config'],
90
90
-
'asClass' | 'classStructure' | 'instance'
91
91
-
>;
92
92
-
};
86
86
+
plugin: Plugin;
93
87
}): Map<string, ClassNameEntry> => {
94
88
const classNames = new Map<string, ClassNameEntry>();
95
89
···
115
109
116
110
for (const rootClass of rootClasses) {
117
111
const finalClassName = operationClassName({
118
118
-
context,
112
112
+
plugin,
119
113
value: className || rootClass,
120
114
});
121
115
···
134
128
classNames.set(rootClass, {
135
129
className: finalClassName,
136
130
methodName: methodName || getOperationMethodName({ operation, plugin }),
137
137
-
path: path.map((value) =>
138
138
-
operationClassName({
139
139
-
context,
140
140
-
value,
141
141
-
}),
142
142
-
),
131
131
+
path: path.map((value) => operationClassName({ plugin, value })),
143
132
});
144
133
}
145
134
+1
-5
packages/openapi-ts/src/plugins/@pinia/colada/v0/plugin.ts
···
59
59
'operation',
60
60
({ operation }) => {
61
61
const classes = sdkPlugin.config.asClass
62
62
-
? operationClasses({
63
63
-
context: plugin.context,
64
64
-
operation,
65
65
-
plugin: sdkPlugin,
66
66
-
})
62
62
+
? operationClasses({ operation, plugin: sdkPlugin })
67
63
: undefined;
68
64
const entry = classes ? classes.values().next().value : undefined;
69
65
// TODO: this should use class graph to determine correct path string
+1
-5
packages/openapi-ts/src/plugins/@tanstack/query-core/v5/plugin.ts
···
83
83
'operation',
84
84
({ operation }) => {
85
85
const classes = sdkPlugin.config.asClass
86
86
-
? operationClasses({
87
87
-
context: plugin.context,
88
88
-
operation,
89
89
-
plugin: sdkPlugin,
90
90
-
})
86
86
+
? operationClasses({ operation, plugin: sdkPlugin })
91
87
: undefined;
92
88
const entry = classes ? classes.values().next().value : undefined;
93
89
// TODO: this should use class graph to determine correct path string
+1
-5
packages/openapi-ts/src/plugins/swr/v2/plugin.ts
···
24
24
'operation',
25
25
({ operation }) => {
26
26
const classes = sdkPlugin.config.asClass
27
27
-
? operationClasses({
28
28
-
context: plugin.context,
29
29
-
operation,
30
30
-
plugin: sdkPlugin,
31
31
-
})
27
27
+
? operationClasses({ operation, plugin: sdkPlugin })
32
28
: undefined;
33
29
const entry = classes ? classes.values().next().value : undefined;
34
30
// TODO: this should use class graph to determine correct path string
+1
-1
packages/openapi-ts/src/utils/__tests__/stringCase.test.ts
···
136
136
SCREAMING_SNAKE_CASE: 'IO_K8S_APIMACHINERY_PKG_APIS_META_V1_DELETE_OPTIONS',
137
137
camelCase: 'ioK8sApimachineryPkgApisMetaV1DeleteOptions',
138
138
snake_case: 'io_k8s_apimachinery_pkg_apis_meta_v1_delete_options',
139
139
-
value: 'io.k8sApimachinery.pkg.apis.meta.v1.DeleteOptions',
139
139
+
value: 'io.k8sApimachinery.pkg.apis.meta:v1.DeleteOptions',
140
140
},
141
141
{
142
142
PascalCase: 'GenericSchemaDuplicateIssue1SystemBoolean',
+1
-1
packages/openapi-ts/src/utils/stringCase.ts
···
3
3
const uppercaseRegExp = /[\p{Lu}]/u;
4
4
const lowercaseRegExp = /[\p{Ll}]/u;
5
5
const identifierRegExp = /([\p{Alpha}\p{N}_]|$)/u;
6
6
-
const separatorsRegExp = /[_.\- `\\[\]{}\\/]+/;
6
6
+
const separatorsRegExp = /[_.:\- `\\[\]{}\\/]+/;
7
7
8
8
const leadingSeparatorsRegExp = new RegExp(`^${separatorsRegExp.source}`);
9
9
const separatorsAndIdentifierRegExp = new RegExp(
-24
packages/openapi-ts/src/utils/transform.ts
···
1
1
-
import type { Config } from '~/types/config';
2
2
-
3
3
-
export const transformClassName = ({
4
4
-
config,
5
5
-
name,
6
6
-
}: {
7
7
-
config: Config;
8
8
-
name: string;
9
9
-
}) => {
10
10
-
const plugin = config.plugins['@hey-api/sdk'];
11
11
-
if (plugin?.config.classNameBuilder) {
12
12
-
let customName = '';
13
13
-
14
14
-
if (typeof plugin.config.classNameBuilder === 'function') {
15
15
-
customName = plugin.config.classNameBuilder(name);
16
16
-
} else {
17
17
-
customName = plugin.config.classNameBuilder.replace('{{name}}', name);
18
18
-
}
19
19
-
20
20
-
return customName;
21
21
-
}
22
22
-
23
23
-
return name;
24
24
-
};