@goast/typescript 0.6.1 → 0.6.3-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/assets/client/k6/request-builder.js +4 -0
- package/assets/client/k6/request-builder.ts +4 -0
- package/assets/stubs/easy-network-stub/easy-network-stub.utils.ts +2 -6
- package/package.json +2 -2
- package/src/mod.ts +0 -7
- package/src/src/assets.ts +0 -9
- package/src/src/ast/_index.ts +0 -54
- package/src/src/ast/common.ts +0 -1
- package/src/src/ast/index.ts +0 -1
- package/src/src/ast/node.ts +0 -10
- package/src/src/ast/nodes/argument.ts +0 -40
- package/src/src/ast/nodes/array-type.ts +0 -49
- package/src/src/ast/nodes/arrow-function.ts +0 -91
- package/src/src/ast/nodes/call.ts +0 -55
- package/src/src/ast/nodes/class.ts +0 -133
- package/src/src/ast/nodes/constructor-parameter.ts +0 -70
- package/src/src/ast/nodes/constructor.ts +0 -77
- package/src/src/ast/nodes/decorator.ts +0 -76
- package/src/src/ast/nodes/doc-tag.ts +0 -291
- package/src/src/ast/nodes/doc.ts +0 -102
- package/src/src/ast/nodes/enum-value.ts +0 -72
- package/src/src/ast/nodes/enum.ts +0 -77
- package/src/src/ast/nodes/export.ts +0 -54
- package/src/src/ast/nodes/function-type.ts +0 -60
- package/src/src/ast/nodes/function.ts +0 -107
- package/src/src/ast/nodes/generic-parameter.ts +0 -71
- package/src/src/ast/nodes/indexer.ts +0 -60
- package/src/src/ast/nodes/interface.ts +0 -117
- package/src/src/ast/nodes/intersection-type.ts +0 -67
- package/src/src/ast/nodes/lookup-type.ts +0 -53
- package/src/src/ast/nodes/method.ts +0 -138
- package/src/src/ast/nodes/object-type.ts +0 -52
- package/src/src/ast/nodes/object.ts +0 -48
- package/src/src/ast/nodes/parameter.ts +0 -85
- package/src/src/ast/nodes/property-accessor.ts +0 -173
- package/src/src/ast/nodes/property.ts +0 -192
- package/src/src/ast/nodes/reference.ts +0 -194
- package/src/src/ast/nodes/string.ts +0 -49
- package/src/src/ast/nodes/tuple.ts +0 -53
- package/src/src/ast/nodes/type-alias.ts +0 -75
- package/src/src/ast/nodes/typeof.ts +0 -42
- package/src/src/ast/nodes/types.ts +0 -40
- package/src/src/ast/nodes/union-type.ts +0 -62
- package/src/src/ast/nodes/variable.ts +0 -73
- package/src/src/ast/references/angular.ts +0 -24
- package/src/src/ast/references/easy-network-stub.ts +0 -21
- package/src/src/ast/references/index.ts +0 -5
- package/src/src/ast/references/k6.ts +0 -8
- package/src/src/ast/references/rxjs.ts +0 -7
- package/src/src/ast/references/typescript.ts +0 -35
- package/src/src/ast/utils/get-type-script-builder-options.ts +0 -19
- package/src/src/ast/utils/to-ts-node.ts +0 -27
- package/src/src/ast/utils/write-ts-generic-parameters.ts +0 -25
- package/src/src/ast/utils/write-ts-members.ts +0 -28
- package/src/src/ast/utils/write-ts-nodes.ts +0 -35
- package/src/src/ast/utils/write-ts-parameters.ts +0 -25
- package/src/src/common-results.ts +0 -26
- package/src/src/config.ts +0 -89
- package/src/src/file-builder.ts +0 -137
- package/src/src/generators/file-generator.ts +0 -15
- package/src/src/generators/index.ts +0 -6
- package/src/src/generators/models/index.ts +0 -3
- package/src/src/generators/models/model-generator.ts +0 -481
- package/src/src/generators/models/models-generator.ts +0 -108
- package/src/src/generators/models/models.ts +0 -121
- package/src/src/generators/services/angular-services/angular-service-generator.ts +0 -414
- package/src/src/generators/services/angular-services/angular-services-generator.ts +0 -295
- package/src/src/generators/services/angular-services/index.ts +0 -3
- package/src/src/generators/services/angular-services/models.ts +0 -277
- package/src/src/generators/services/angular-services/refs.ts +0 -54
- package/src/src/generators/services/easy-network-stub/easy-network-stub-generator.ts +0 -250
- package/src/src/generators/services/easy-network-stub/easy-network-stubs-generator.ts +0 -211
- package/src/src/generators/services/easy-network-stub/index.ts +0 -3
- package/src/src/generators/services/easy-network-stub/models.ts +0 -124
- package/src/src/generators/services/easy-network-stub/refs.ts +0 -45
- package/src/src/generators/services/fetch-clients/fetch-client-generator.ts +0 -285
- package/src/src/generators/services/fetch-clients/fetch-clients-generator.ts +0 -163
- package/src/src/generators/services/fetch-clients/index.ts +0 -3
- package/src/src/generators/services/fetch-clients/models.ts +0 -130
- package/src/src/generators/services/fetch-clients/refs.ts +0 -21
- package/src/src/generators/services/k6-clients/index.ts +0 -3
- package/src/src/generators/services/k6-clients/k6-client-generator.ts +0 -474
- package/src/src/generators/services/k6-clients/k6-clients-generator.ts +0 -171
- package/src/src/generators/services/k6-clients/models.ts +0 -247
- package/src/src/generators/services/k6-clients/refs.ts +0 -16
- package/src/src/import-collection.ts +0 -236
- package/src/src/utils.ts +0 -72
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
type ApiEndpoint,
|
|
5
|
-
type ApiSchema,
|
|
6
|
-
type AppendValueGroup,
|
|
7
|
-
appendValueGroup,
|
|
8
|
-
builderTemplate as s,
|
|
9
|
-
getSourceDisplayName,
|
|
10
|
-
type MaybePromise,
|
|
11
|
-
toCasing,
|
|
12
|
-
} from '@goast/core';
|
|
13
|
-
|
|
14
|
-
import { ts } from '../../../ast/index.js';
|
|
15
|
-
import { TypeScriptFileBuilder } from '../../../file-builder.js';
|
|
16
|
-
import { TypeScriptFileGenerator } from '../../file-generator.js';
|
|
17
|
-
import type { TypeScriptFetchClientGeneratorContext, TypeScriptFetchClientGeneratorOutput } from './models.js';
|
|
18
|
-
|
|
19
|
-
type Context = TypeScriptFetchClientGeneratorContext;
|
|
20
|
-
type Output = TypeScriptFetchClientGeneratorOutput;
|
|
21
|
-
type Builder = TypeScriptFileBuilder;
|
|
22
|
-
|
|
23
|
-
export interface TypeScriptFetchClientGenerator<TOutput extends Output = Output> {
|
|
24
|
-
generate(ctx: Context): MaybePromise<TOutput>;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export class DefaultTypeScriptFetchClientGenerator extends TypeScriptFileGenerator<Context, Output>
|
|
28
|
-
implements TypeScriptFetchClientGenerator {
|
|
29
|
-
public generate(ctx: Context): MaybePromise<Output> {
|
|
30
|
-
const result: Output = {};
|
|
31
|
-
|
|
32
|
-
if (this.shouldGenerateInterface(ctx)) {
|
|
33
|
-
const filePath = this.getInterfaceFilePath(ctx);
|
|
34
|
-
const name = this.getInterfaceName(ctx);
|
|
35
|
-
|
|
36
|
-
TypeScriptFileBuilder.generate({
|
|
37
|
-
logName: `interface ${name}`,
|
|
38
|
-
filePath,
|
|
39
|
-
options: ctx.config,
|
|
40
|
-
generator: (b) => {
|
|
41
|
-
ctx.service.endpoints.forEach((endpoint) => {
|
|
42
|
-
console.log(
|
|
43
|
-
` ${getSourceDisplayName(ctx.data, endpoint)} [${
|
|
44
|
-
toCasing(endpoint.name, ctx.config.functionNameCasing)
|
|
45
|
-
}]`,
|
|
46
|
-
);
|
|
47
|
-
});
|
|
48
|
-
b.append(this.getInterfaceFileContent(ctx));
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
result.clientInterface = { filePath, component: name };
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (this.shouldGenerateClass(ctx)) {
|
|
56
|
-
const filePath = this.getClassFilePath(ctx);
|
|
57
|
-
const name = this.getClassName(ctx);
|
|
58
|
-
|
|
59
|
-
TypeScriptFileBuilder.generate({
|
|
60
|
-
logName: `class ${name}`,
|
|
61
|
-
filePath,
|
|
62
|
-
options: ctx.config,
|
|
63
|
-
generator: (b) => b.append(this.getClassFileContent(ctx)),
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
result.client = { filePath, component: name };
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return result;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// #region Interface
|
|
73
|
-
protected getInterfaceFileContent(ctx: Context): AppendValueGroup<Builder> {
|
|
74
|
-
return appendValueGroup([this.getInterface(ctx)], '\n');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
protected getInterface(ctx: Context): ts.Interface<Builder> {
|
|
78
|
-
return ts.interface(this.getInterfaceName(ctx), {
|
|
79
|
-
doc: ts.doc({
|
|
80
|
-
description: ctx.service.description,
|
|
81
|
-
tags: [
|
|
82
|
-
ctx.service.endpoints.length === 0 || ctx.service.endpoints.some((x) => !x.deprecated)
|
|
83
|
-
? null
|
|
84
|
-
: ts.docTag('deprecated'),
|
|
85
|
-
],
|
|
86
|
-
}),
|
|
87
|
-
export: true,
|
|
88
|
-
members: ctx.service.endpoints.map((endpoint) => this.getInterfaceEndpointMethod(ctx, endpoint)),
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
protected getInterfaceEndpointMethod(ctx: Context, endpoint: ApiEndpoint): ts.Method<Builder> {
|
|
93
|
-
const params = endpoint.parameters.filter((x) =>
|
|
94
|
-
x.target === 'path' || x.target === 'query' || x.target === 'header'
|
|
95
|
-
);
|
|
96
|
-
const bodySchema = endpoint.requestBody?.content[0]?.schema;
|
|
97
|
-
const responseSchema = this.getResponseSchema(ctx, endpoint);
|
|
98
|
-
return ts.method(toCasing(endpoint.name, ctx.config.functionNameCasing), {
|
|
99
|
-
doc: ts.doc({ description: endpoint.description, tags: [endpoint.deprecated ? ts.docTag('deprecated') : null] }),
|
|
100
|
-
parameters: [
|
|
101
|
-
params.length > 0
|
|
102
|
-
? ts.parameter('params', {
|
|
103
|
-
description: 'Parameters for the endpoint.',
|
|
104
|
-
type: ts.objectType({
|
|
105
|
-
members: params.map((x) =>
|
|
106
|
-
ts.property(toCasing(x.name, ctx.config.propertyNameCasing), {
|
|
107
|
-
doc: ts.doc({ tags: [x.deprecated ? ts.docTag('deprecated') : null] }),
|
|
108
|
-
type: this.getSchemaType(ctx, x.schema),
|
|
109
|
-
optional: !x.required,
|
|
110
|
-
})
|
|
111
|
-
),
|
|
112
|
-
}),
|
|
113
|
-
})
|
|
114
|
-
: null,
|
|
115
|
-
bodySchema &&
|
|
116
|
-
ts.parameter('body', {
|
|
117
|
-
description: 'Body for the endpoint.',
|
|
118
|
-
type: this.getSchemaType(ctx, bodySchema),
|
|
119
|
-
}),
|
|
120
|
-
],
|
|
121
|
-
returnType: ts.refs.promise([ctx.refs.typedResponse([this.getSchemaType(ctx, responseSchema, ts.refs.void_())])]),
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
// #endregion
|
|
125
|
-
|
|
126
|
-
// #region Class
|
|
127
|
-
protected getClassFileContent(ctx: Context): AppendValueGroup<Builder> {
|
|
128
|
-
return appendValueGroup([this.getDefaultOptionsConstant(ctx), this.getClass(ctx)], '\n');
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
protected getDefaultOptionsConstant(ctx: Context): ts.Variable<Builder> {
|
|
132
|
-
const baseUrl = ctx.service.endpoints.map((x) => x.$src?.document.servers?.find((x) => x.url)?.url).find((x) =>
|
|
133
|
-
!!x
|
|
134
|
-
);
|
|
135
|
-
return ts.variable(this.getDefaultOptionsConstantName(ctx), {
|
|
136
|
-
export: true,
|
|
137
|
-
readonly: true,
|
|
138
|
-
type: ctx.refs.fetchClientOptions(),
|
|
139
|
-
value: ts.object({
|
|
140
|
-
members: [baseUrl && ts.property('baseUrl', { value: ts.string(baseUrl) })],
|
|
141
|
-
}),
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
protected getClass(ctx: Context): ts.Class<Builder> {
|
|
146
|
-
return ts.class(this.getClassName(ctx), {
|
|
147
|
-
doc: ts.doc({
|
|
148
|
-
description: ctx.service.description,
|
|
149
|
-
tags: [
|
|
150
|
-
ctx.service.endpoints.length === 0 || ctx.service.endpoints.some((x) => !x.deprecated)
|
|
151
|
-
? null
|
|
152
|
-
: ts.docTag('deprecated'),
|
|
153
|
-
],
|
|
154
|
-
}),
|
|
155
|
-
export: true,
|
|
156
|
-
implements: this.shouldGenerateInterface(ctx)
|
|
157
|
-
? [ts.reference(this.getInterfaceName(ctx), this.getInterfaceFilePath(ctx))]
|
|
158
|
-
: undefined,
|
|
159
|
-
members: [
|
|
160
|
-
ts.property('options', {
|
|
161
|
-
doc: ts.doc({ description: 'Options for the fetch client.' }),
|
|
162
|
-
accessModifier: 'public',
|
|
163
|
-
type: ctx.refs.fetchClientOptions(),
|
|
164
|
-
}),
|
|
165
|
-
ts.constructor({
|
|
166
|
-
parameters: [
|
|
167
|
-
ts.constructorParameter('options', {
|
|
168
|
-
type: ts.refs.partial([ctx.refs.fetchClientOptions()]),
|
|
169
|
-
optional: true,
|
|
170
|
-
}),
|
|
171
|
-
],
|
|
172
|
-
body: appendValueGroup(
|
|
173
|
-
[s`this.options = { ...${this.getDefaultOptionsConstantName(ctx)}, ...options };`],
|
|
174
|
-
'\n',
|
|
175
|
-
),
|
|
176
|
-
}),
|
|
177
|
-
...ctx.service.endpoints.map((endpoint) => this.getServiceMethod(ctx, endpoint)),
|
|
178
|
-
],
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
protected getServiceMethod(ctx: Context, endpoint: ApiEndpoint): ts.Method<Builder> {
|
|
183
|
-
const method = this.getInterfaceEndpointMethod(ctx, endpoint);
|
|
184
|
-
method.accessModifier = 'public';
|
|
185
|
-
method.body = appendValueGroup(
|
|
186
|
-
[
|
|
187
|
-
s`const url = new ${ctx.refs.urlBuilder()}(this.options.baseUrl)${s.indent`
|
|
188
|
-
.withPath(${ts.string(endpoint.path)})${(b) =>
|
|
189
|
-
b.forEach(endpoint.parameters, (b, p) => {
|
|
190
|
-
switch (p.target) {
|
|
191
|
-
case 'path':
|
|
192
|
-
b.append(
|
|
193
|
-
s<Builder>`\n.withPathParam(${ts.string(p.name)}, params.${
|
|
194
|
-
toCasing(p.name, ctx.config.paramNameCasing)
|
|
195
|
-
})`,
|
|
196
|
-
);
|
|
197
|
-
break;
|
|
198
|
-
case 'query':
|
|
199
|
-
b.append(
|
|
200
|
-
s<Builder>`\n.withQueryParam(${ts.string(p.name)}, params.${
|
|
201
|
-
toCasing(p.name, ctx.config.paramNameCasing)
|
|
202
|
-
})`,
|
|
203
|
-
);
|
|
204
|
-
break;
|
|
205
|
-
}
|
|
206
|
-
})}
|
|
207
|
-
.build();`}`,
|
|
208
|
-
'const headers = { ...this.options.headers };',
|
|
209
|
-
...endpoint.parameters.filter((x) => x.target === 'header').map((p) =>
|
|
210
|
-
s<Builder>`if (params && params.${toCasing(p.name, ctx.config.paramNameCasing)} !== undefined) {${s.indent`
|
|
211
|
-
headers[${ts.string(p.name)}] = String(params.${toCasing(p.name, ctx.config.paramNameCasing)});`}
|
|
212
|
-
}`
|
|
213
|
-
),
|
|
214
|
-
s`const response = (this.options.fetch ?? fetch)(url, ${
|
|
215
|
-
ts.object({
|
|
216
|
-
members: [
|
|
217
|
-
ts.property('method', { value: ts.string(toCasing(endpoint.method, 'all-upper')) }),
|
|
218
|
-
ts.property('headers', { value: 'headers' }),
|
|
219
|
-
endpoint.requestBody?.content[0]?.schema ? ts.property('body', { value: 'JSON.stringify(body)' }) : null,
|
|
220
|
-
],
|
|
221
|
-
})
|
|
222
|
-
});`,
|
|
223
|
-
s`Object.defineProperty(response, 'isVoidResponse', { value: ${
|
|
224
|
-
this.getResponseSchema(ctx, endpoint) ? 'false' : 'true'
|
|
225
|
-
} });`,
|
|
226
|
-
s`return response as unknown as ${method.returnType ?? 'unknown'};`,
|
|
227
|
-
],
|
|
228
|
-
'\n',
|
|
229
|
-
);
|
|
230
|
-
return method;
|
|
231
|
-
}
|
|
232
|
-
// #endregion
|
|
233
|
-
|
|
234
|
-
protected getSchemaType(ctx: Context, schema: ApiSchema | undefined, fallback?: ts.Type<Builder>): ts.Type<Builder> {
|
|
235
|
-
const output = schema && ctx.input.typescript.models[schema.id];
|
|
236
|
-
if (!output) return fallback ?? this.getAnyType(ctx);
|
|
237
|
-
return (b) => b.appendModelUsage(output);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
protected shouldGenerateInterface(ctx: Context): boolean {
|
|
241
|
-
return ctx.config.clientFileKind === 'interface' || ctx.config.clientFileKind === 'class-and-interface';
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
protected shouldGenerateClass(ctx: Context): boolean {
|
|
245
|
-
return ctx.config.clientFileKind === 'class' || ctx.config.clientFileKind === 'class-and-interface';
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
protected getInterfaceName(ctx: Context): string {
|
|
249
|
-
return toCasing(ctx.service.name, ctx.config.clientInterfaceNameCasing ?? ctx.config.typeNameCasing);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
protected getClassName(ctx: Context): string {
|
|
253
|
-
return toCasing(ctx.service.name, ctx.config.clientNameCasing ?? ctx.config.typeNameCasing);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
protected getDefaultOptionsConstantName(ctx: Context): string {
|
|
257
|
-
return toCasing(this.getClassName(ctx) + '-default-options', ctx.config.constantNameCasing);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
protected getInterfaceFilePath(ctx: Context): string {
|
|
261
|
-
return resolve(
|
|
262
|
-
ctx.config.outputDir,
|
|
263
|
-
ctx.config.clientInterfaceDir ?? ctx.config.clientDir,
|
|
264
|
-
`${toCasing(ctx.service.name, ctx.config.clientInterfaceFileNameCasing ?? ctx.config.fileNameCasing)}.ts`,
|
|
265
|
-
);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
protected getClassFilePath(ctx: Context): string {
|
|
269
|
-
return resolve(
|
|
270
|
-
ctx.config.outputDir,
|
|
271
|
-
ctx.config.clientDir,
|
|
272
|
-
`${toCasing(ctx.service.name, ctx.config.clientFileNameCasing ?? ctx.config.fileNameCasing)}.ts`,
|
|
273
|
-
);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
protected getUtilPath(ctx: Context, fileName: string): string {
|
|
277
|
-
return resolve(ctx.config.outputDir, ctx.config.utilsDir, fileName);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
private getResponseSchema(_ctx: Context, endpoint: ApiEndpoint) {
|
|
281
|
-
const successResponse = endpoint.responses.find((x) => x.statusCode === 200) ??
|
|
282
|
-
endpoint.responses.find((x) => x.statusCode && x.statusCode > 200 && x.statusCode < 300);
|
|
283
|
-
return successResponse?.contentOptions?.find((x) => x.schema !== undefined)?.schema;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import fs from 'fs-extra';
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
type ApiService,
|
|
8
|
-
type AppendValueGroup,
|
|
9
|
-
appendValueGroup,
|
|
10
|
-
Factory,
|
|
11
|
-
type MaybePromise,
|
|
12
|
-
notNullish,
|
|
13
|
-
type OpenApiGeneratorContext,
|
|
14
|
-
OpenApiServicesGenerationProviderBase,
|
|
15
|
-
} from '@goast/core';
|
|
16
|
-
|
|
17
|
-
import { copyAssetFile } from '../../../assets.js';
|
|
18
|
-
import { ts } from '../../../ast/index.js';
|
|
19
|
-
import { TypeScriptFileBuilder } from '../../../file-builder.js';
|
|
20
|
-
import {
|
|
21
|
-
DefaultTypeScriptFetchClientGenerator,
|
|
22
|
-
type TypeScriptFetchClientGenerator,
|
|
23
|
-
} from './fetch-client-generator.js';
|
|
24
|
-
import {
|
|
25
|
-
defaultTypeScriptFetchClientsGeneratorConfig,
|
|
26
|
-
type TypeScriptFetchClientGeneratorOutput,
|
|
27
|
-
type TypeScriptFetchClientsGeneratorConfig,
|
|
28
|
-
type TypeScriptFetchClientsGeneratorContext,
|
|
29
|
-
type TypeScriptFetchClientsGeneratorInput,
|
|
30
|
-
type TypeScriptFetchClientsGeneratorOutput,
|
|
31
|
-
} from './models.js';
|
|
32
|
-
import { getReferenceFactories } from './refs.js';
|
|
33
|
-
|
|
34
|
-
type Input = TypeScriptFetchClientsGeneratorInput;
|
|
35
|
-
type Output = TypeScriptFetchClientsGeneratorOutput;
|
|
36
|
-
type Config = TypeScriptFetchClientsGeneratorConfig;
|
|
37
|
-
type ServiceOutput = TypeScriptFetchClientGeneratorOutput;
|
|
38
|
-
type Context = TypeScriptFetchClientsGeneratorContext;
|
|
39
|
-
|
|
40
|
-
export class TypeScriptFetchClientsGenerator extends OpenApiServicesGenerationProviderBase<
|
|
41
|
-
Input,
|
|
42
|
-
Output,
|
|
43
|
-
Config,
|
|
44
|
-
ServiceOutput,
|
|
45
|
-
Context
|
|
46
|
-
> {
|
|
47
|
-
private readonly _clientGeneratorFactory: Factory<TypeScriptFetchClientGenerator, []>;
|
|
48
|
-
|
|
49
|
-
constructor(clientGeneratorFactory?: Factory<TypeScriptFetchClientGenerator, []>) {
|
|
50
|
-
super();
|
|
51
|
-
this._clientGeneratorFactory = clientGeneratorFactory ??
|
|
52
|
-
Factory.fromValue(new DefaultTypeScriptFetchClientGenerator());
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
protected override initResult(): Output {
|
|
56
|
-
return {
|
|
57
|
-
typescript: {
|
|
58
|
-
clients: {},
|
|
59
|
-
indexFiles: {
|
|
60
|
-
clients: undefined,
|
|
61
|
-
clientInterfaces: undefined,
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
protected override buildContext(
|
|
68
|
-
context: OpenApiGeneratorContext<Input>,
|
|
69
|
-
config?: Partial<Config> | undefined,
|
|
70
|
-
): Context {
|
|
71
|
-
const providerContext = this.getProviderContext(context, config, defaultTypeScriptFetchClientsGeneratorConfig);
|
|
72
|
-
return Object.assign(providerContext, {
|
|
73
|
-
refs: getReferenceFactories(providerContext.config),
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
protected override async generateAdditionalFiles(ctx: TypeScriptFetchClientsGeneratorContext): Promise<void> {
|
|
78
|
-
await this.copyUtilsFiles(ctx);
|
|
79
|
-
ctx.output.typescript.indexFiles.clients = this.generateIndexFile(ctx);
|
|
80
|
-
ctx.output.typescript.indexFiles.clientInterfaces = this.generateInterfaceIndexFile(ctx);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
protected override generateService(ctx: Context, service: ApiService): MaybePromise<ServiceOutput> {
|
|
84
|
-
const clientGenerator = this._clientGeneratorFactory.create();
|
|
85
|
-
return clientGenerator.generate({
|
|
86
|
-
...ctx,
|
|
87
|
-
service,
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
protected override addServiceResult(ctx: Context, service: ApiService, result: ServiceOutput): void {
|
|
92
|
-
ctx.output.typescript.clients[service.id] = result;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
protected generateIndexFile(ctx: Context): string | null {
|
|
96
|
-
const filePath = this.getIndexFilePath(ctx);
|
|
97
|
-
|
|
98
|
-
TypeScriptFileBuilder.tryGenerate({
|
|
99
|
-
logName: 'clients index file',
|
|
100
|
-
filePath,
|
|
101
|
-
options: ctx.config,
|
|
102
|
-
generator: (b) => b.append(this.getIndexFileContent(ctx)),
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
return filePath;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
protected generateInterfaceIndexFile(ctx: Context): string | null {
|
|
109
|
-
const filePath = this.getInterfaceIndexFilePath(ctx);
|
|
110
|
-
const clientsFilePath = this.getIndexFilePath(ctx);
|
|
111
|
-
|
|
112
|
-
if (filePath && filePath === clientsFilePath) {
|
|
113
|
-
return clientsFilePath;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
TypeScriptFileBuilder.tryGenerate({
|
|
117
|
-
logName: 'client interfaces index file',
|
|
118
|
-
filePath,
|
|
119
|
-
options: ctx.config,
|
|
120
|
-
generator: (b) => b.append(this.getInterfaceIndexFileContent(ctx)),
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
return filePath;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
protected getIndexFilePath(ctx: Context): string | null {
|
|
127
|
-
return ctx.config.clientsIndexFile ? resolve(ctx.config.outputDir, ctx.config.clientsIndexFile) : null;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
protected getInterfaceIndexFilePath(ctx: Context): string | null {
|
|
131
|
-
return ctx.config.clientInterfacesIndexFile
|
|
132
|
-
? resolve(ctx.config.outputDir, ctx.config.clientInterfacesIndexFile)
|
|
133
|
-
: null;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
protected getIndexFileContent(ctx: Context): AppendValueGroup<TypeScriptFileBuilder> {
|
|
137
|
-
const cIndexPath = this.getIndexFilePath(ctx);
|
|
138
|
-
const iIndexPath = this.getInterfaceIndexFilePath(ctx);
|
|
139
|
-
return appendValueGroup(
|
|
140
|
-
(iIndexPath && iIndexPath === cIndexPath
|
|
141
|
-
? Object.values(ctx.output.typescript.clients).flatMap((c) => [c.client, c.clientInterface])
|
|
142
|
-
: Object.values(ctx.output.typescript.clients).map((c) => c.client))
|
|
143
|
-
.filter(notNullish)
|
|
144
|
-
.map((x) => ts.export(x.component, x.filePath)),
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
protected getInterfaceIndexFileContent(ctx: Context): AppendValueGroup<TypeScriptFileBuilder> {
|
|
149
|
-
return appendValueGroup(
|
|
150
|
-
Object.values(ctx.output.typescript.clients)
|
|
151
|
-
.map((c) => c.clientInterface)
|
|
152
|
-
.filter(notNullish)
|
|
153
|
-
.map((x) => ts.export(x.component, x.filePath)),
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
private async copyUtilsFiles(ctx: Context): Promise<void> {
|
|
158
|
-
const targetDir = resolve(ctx.config.outputDir, ctx.config.utilsDir);
|
|
159
|
-
await fs.ensureDir(targetDir);
|
|
160
|
-
|
|
161
|
-
await copyAssetFile('client/fetch/fetch-client.utils.ts', targetDir);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ApiService,
|
|
3
|
-
DefaultGenerationProviderConfig,
|
|
4
|
-
ExtendedStringCasing,
|
|
5
|
-
Nullable,
|
|
6
|
-
OpenApiServicesGenerationProviderContext,
|
|
7
|
-
} from '@goast/core';
|
|
8
|
-
|
|
9
|
-
import type { TypeScriptExportOutput } from '../../../common-results.js';
|
|
10
|
-
import { defaultTypeScriptGeneratorConfig, type TypeScriptGeneratorConfig } from '../../../config.js';
|
|
11
|
-
import type { TypeScriptModelsGeneratorOutput } from '../../models/models.js';
|
|
12
|
-
import type { getReferenceFactories } from './refs.js';
|
|
13
|
-
|
|
14
|
-
export type TypeScriptFetchClientsGeneratorConfig = TypeScriptGeneratorConfig & {
|
|
15
|
-
/**
|
|
16
|
-
* The casing of the client file names. If nullish, the `fileNameCasing` is used.
|
|
17
|
-
* @default { casing: 'kebab', suffix: '-client' }
|
|
18
|
-
*/
|
|
19
|
-
clientFileNameCasing: Nullable<ExtendedStringCasing>;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* The casing of the client interface file names. If nullish, the `fileNameCasing` is used.
|
|
23
|
-
* @default { casing: 'kebab', suffix: '-client' }
|
|
24
|
-
*/
|
|
25
|
-
clientInterfaceFileNameCasing: Nullable<ExtendedStringCasing>;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* The casing of the client names. If nullish, the `typeNameCasing` is used.
|
|
29
|
-
* @default { casing: 'pascal', suffix: 'Client' }
|
|
30
|
-
*/
|
|
31
|
-
clientNameCasing: Nullable<ExtendedStringCasing>;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The casing of the client interface names. If nullish, the `typeNameCasing` is used.
|
|
35
|
-
* @default { prefix: 'I', casing: 'pascal', suffix: 'Client' }
|
|
36
|
-
*/
|
|
37
|
-
clientInterfaceNameCasing: Nullable<ExtendedStringCasing>;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Determines how the client files should be generated.
|
|
41
|
-
* - `interface` - generates only the interface
|
|
42
|
-
* - `class` - generates only the class
|
|
43
|
-
* - `class-and-interface` - generates both the class and the interface
|
|
44
|
-
* @default 'class'
|
|
45
|
-
*/
|
|
46
|
-
clientFileKind: 'interface' | 'class' | 'class-and-interface';
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* The directory where the client files should be saved. The path is relative to the output directory.
|
|
50
|
-
* @default 'clients'
|
|
51
|
-
*/
|
|
52
|
-
clientDir: string;
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* The directory where the client interface files should be saved. The path is relative to the output directory.
|
|
56
|
-
* @default 'clients/interfaces'
|
|
57
|
-
*/
|
|
58
|
-
clientInterfaceDir: Nullable<string>;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* The index file where all clients should be exported. The path is relative to the output directory. If nullish, no index file will be generated.
|
|
62
|
-
* @default 'clients.ts'
|
|
63
|
-
*/
|
|
64
|
-
clientsIndexFile: Nullable<string>;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* The index file where all client interfaces should be exported. The path is relative to the output directory. If nullish, no index file will be generated.
|
|
68
|
-
* @default 'clients.ts'
|
|
69
|
-
*/
|
|
70
|
-
clientInterfacesIndexFile: Nullable<string>;
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* The directory where the utilies should be saved. The path is relative to the output directory.
|
|
74
|
-
* @default 'utils'
|
|
75
|
-
*/
|
|
76
|
-
utilsDir: string;
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
export const defaultTypeScriptFetchClientsGeneratorConfig: DefaultGenerationProviderConfig<
|
|
80
|
-
TypeScriptFetchClientsGeneratorConfig
|
|
81
|
-
> = {
|
|
82
|
-
...defaultTypeScriptGeneratorConfig,
|
|
83
|
-
|
|
84
|
-
clientFileNameCasing: { casing: 'kebab', suffix: '-client' },
|
|
85
|
-
clientInterfaceFileNameCasing: undefined,
|
|
86
|
-
|
|
87
|
-
clientNameCasing: { casing: 'pascal', suffix: 'Client' },
|
|
88
|
-
clientInterfaceNameCasing: { prefix: 'I', casing: 'pascal', suffix: 'Client' },
|
|
89
|
-
|
|
90
|
-
clientFileKind: 'class',
|
|
91
|
-
clientDir: 'clients',
|
|
92
|
-
clientInterfaceDir: 'clients/interfaces',
|
|
93
|
-
clientsIndexFile: 'clients.ts',
|
|
94
|
-
clientInterfacesIndexFile: 'clients.ts',
|
|
95
|
-
utilsDir: 'utils',
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
export type TypeScriptFetchClientsGeneratorInput = TypeScriptModelsGeneratorOutput;
|
|
99
|
-
|
|
100
|
-
export type TypeScriptFetchClientsGeneratorOutput = {
|
|
101
|
-
typescript: {
|
|
102
|
-
clients: {
|
|
103
|
-
[serviceId: string]: TypeScriptFetchClientGeneratorOutput;
|
|
104
|
-
};
|
|
105
|
-
indexFiles: {
|
|
106
|
-
clients: Nullable<string>;
|
|
107
|
-
clientInterfaces: Nullable<string>;
|
|
108
|
-
};
|
|
109
|
-
};
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
export type TypeScriptFetchClientGeneratorOutput = {
|
|
113
|
-
client?: TypeScriptExportOutput;
|
|
114
|
-
clientInterface?: TypeScriptExportOutput;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
export type TypeScriptFetchClientsGeneratorContext =
|
|
118
|
-
& OpenApiServicesGenerationProviderContext<
|
|
119
|
-
TypeScriptFetchClientsGeneratorInput,
|
|
120
|
-
TypeScriptFetchClientsGeneratorOutput,
|
|
121
|
-
TypeScriptFetchClientsGeneratorConfig,
|
|
122
|
-
TypeScriptFetchClientGeneratorOutput
|
|
123
|
-
>
|
|
124
|
-
& {
|
|
125
|
-
refs: ReturnType<typeof getReferenceFactories>;
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
export type TypeScriptFetchClientGeneratorContext = TypeScriptFetchClientsGeneratorContext & {
|
|
129
|
-
readonly service: ApiService;
|
|
130
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
2
|
-
|
|
3
|
-
import { ts } from '../../../ast/index.js';
|
|
4
|
-
import type { TypeScriptFetchClientsGeneratorConfig } from './models.js';
|
|
5
|
-
|
|
6
|
-
// See packages/typescript/assets/client/fetch for reference
|
|
7
|
-
export function getReferenceFactories(options: TypeScriptFetchClientsGeneratorConfig): {
|
|
8
|
-
typedResponse: ts.GenericModuleReferenceFactory<1>;
|
|
9
|
-
fetchClientOptions: ts.ModuleReferenceFactory;
|
|
10
|
-
urlBuilder: ts.ModuleReferenceFactory;
|
|
11
|
-
} {
|
|
12
|
-
const utilsDirPath = resolve(options.outputDir, options.utilsDir);
|
|
13
|
-
const fetchClientUtilsPath = resolve(utilsDirPath, 'fetch-client.utils.ts');
|
|
14
|
-
|
|
15
|
-
return {
|
|
16
|
-
// fetch-client.utils.ts
|
|
17
|
-
typedResponse: ts.reference.genericFactory<1>('TypedResponse', fetchClientUtilsPath, { importType: 'type-import' }),
|
|
18
|
-
fetchClientOptions: ts.reference.factory('FetchClientOptions', fetchClientUtilsPath, { importType: 'type-import' }),
|
|
19
|
-
urlBuilder: ts.reference.factory('UrlBuilder', fetchClientUtilsPath),
|
|
20
|
-
};
|
|
21
|
-
}
|