@goast/typescript 0.5.3 → 0.6.0-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/esm/src/file-builder.d.ts.map +1 -1
- package/esm/src/file-builder.js +2 -5
- package/esm/src/generators/models/model-generator.d.ts.map +1 -1
- package/esm/src/generators/models/model-generator.js +6 -2
- package/esm/src/generators/services/k6-clients/k6-client-generator.d.ts.map +1 -1
- package/esm/src/generators/services/k6-clients/k6-client-generator.js +2 -1
- package/package.json +3 -3
- package/script/src/file-builder.d.ts.map +1 -1
- package/script/src/file-builder.js +1 -5
- package/script/src/generators/models/model-generator.d.ts.map +1 -1
- package/script/src/generators/models/model-generator.js +5 -1
- package/script/src/generators/services/k6-clients/k6-client-generator.d.ts.map +1 -1
- package/script/src/generators/services/k6-clients/k6-client-generator.js +2 -1
- 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 -136
- 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 -469
- 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 -406
- 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 -242
- 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 -275
- 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 -465
- 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,277 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ApiEndpoint,
|
|
3
|
-
ApiSchema,
|
|
4
|
-
ApiService,
|
|
5
|
-
DefaultGenerationProviderConfig,
|
|
6
|
-
ExtendedStringCasing,
|
|
7
|
-
Nullable,
|
|
8
|
-
OpenApiServicesGenerationProviderContext,
|
|
9
|
-
} from '@goast/core';
|
|
10
|
-
|
|
11
|
-
import type { ts } from '../../../ast/index.js';
|
|
12
|
-
import type { TypeScriptExportOutput } from '../../../common-results.js';
|
|
13
|
-
import { defaultTypeScriptGeneratorConfig, type TypeScriptGeneratorConfig } from '../../../config.js';
|
|
14
|
-
import type { TypeScriptFileBuilder } from '../../../file-builder.js';
|
|
15
|
-
import type { TypeScriptModelGeneratorOutput } from '../../models/index.js';
|
|
16
|
-
import type { getReferenceFactories } from './refs.js';
|
|
17
|
-
|
|
18
|
-
export type TypeScriptAngularServicesGeneratorConfig = TypeScriptGeneratorConfig & {
|
|
19
|
-
/**
|
|
20
|
-
* How the services should be provided in the Angular application.
|
|
21
|
-
* - `root` - provides all the services using `Injectable({ providedIn: 'root' })`
|
|
22
|
-
* - `provide-fn` - generates a function `provideApiClients` that provides the services
|
|
23
|
-
* @default 'root'
|
|
24
|
-
*/
|
|
25
|
-
provideKind: 'root' | 'provide-fn';
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* The domain name of the API. Used as a prefix for exported components (e.g. `ApiConfiguration`).
|
|
29
|
-
* @default undefined
|
|
30
|
-
*/
|
|
31
|
-
domainName: Nullable<string>;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Whether to use strict response types for the services.
|
|
35
|
-
* If enabled only the status codes are included that are defined in the OpenAPI specification or the `defaultStatusCodeResponseTypes` option.
|
|
36
|
-
* @default true
|
|
37
|
-
*/
|
|
38
|
-
strictResponseTypes: boolean;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* The default response types for status codes that are not defined in the OpenAPI specification.
|
|
42
|
-
* @example
|
|
43
|
-
* {
|
|
44
|
-
* 400: {
|
|
45
|
-
* parser: 'json',
|
|
46
|
-
* type: schemas =>
|
|
47
|
-
* schemas.find(s => s.name === 'BadRequestResponse')
|
|
48
|
-
* ?? throwExp('BadRequestResponse not found'),
|
|
49
|
-
* },
|
|
50
|
-
* 404: null,
|
|
51
|
-
* 500: {
|
|
52
|
-
* parser: 'json',
|
|
53
|
-
* type: ts.refs.any(),
|
|
54
|
-
* },
|
|
55
|
-
* }
|
|
56
|
-
* @default
|
|
57
|
-
* {
|
|
58
|
-
* 401: null,
|
|
59
|
-
* 403: null,
|
|
60
|
-
* 500: null,
|
|
61
|
-
* }
|
|
62
|
-
*/
|
|
63
|
-
defaultStatusCodeResponseTypes: Record<
|
|
64
|
-
number,
|
|
65
|
-
{
|
|
66
|
-
parser: 'text' | 'json';
|
|
67
|
-
// deno-lint-ignore ban-types
|
|
68
|
-
type: Exclude<ts.Type<TypeScriptFileBuilder>, Function> | ((schemas: readonly ApiSchema[]) => ApiSchema);
|
|
69
|
-
} | null
|
|
70
|
-
>;
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* The default content type which is used for the request. If not defined the first one defined in the OpenApi specification is used.
|
|
74
|
-
* @default undefined
|
|
75
|
-
*/
|
|
76
|
-
defaultRequestContentType: Nullable<string>;
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* The default content type which is used for the success response. If not defined the first one defined in the OpenApi specification is used.
|
|
80
|
-
* @default undefined
|
|
81
|
-
*/
|
|
82
|
-
defaultSuccessResponseContentType: Nullable<string>;
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* The possible status codes that any API endpoint can return.
|
|
86
|
-
* This is only used when `strictResponseTypes` is set to `false`.
|
|
87
|
-
* @default
|
|
88
|
-
* [100, 101, 102, 103, 200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 421, 422, 423, 424, 425, 426, 428, 429, 431, 451, 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511]
|
|
89
|
-
*/
|
|
90
|
-
possibleStatusCodes: number[];
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Explicitly set the root URL of the API. If `undefined`, the root URL is taken from the first `server` in the OpenAPI specification.
|
|
94
|
-
* @default undefined
|
|
95
|
-
*/
|
|
96
|
-
rootUrl: Nullable<string | RegExp | ((rootUrl: string) => string)>;
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Modifier that is applied to the path of each endpoint.
|
|
100
|
-
* @default undefined
|
|
101
|
-
*/
|
|
102
|
-
pathModifier: Nullable<RegExp | ((path: string, endpoint: ApiEndpoint) => string)>;
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* The directory where the services should be saved. The path is relative to the output directory.
|
|
106
|
-
* @default 'services'
|
|
107
|
-
*/
|
|
108
|
-
servicesDir: string;
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* The casing of the file names for the services. If nullish, the `fileNameCasing` is used.
|
|
112
|
-
* @default { casing: 'kebab', suffix: '.service' }
|
|
113
|
-
*/
|
|
114
|
-
serviceFileNameCasing: Nullable<ExtendedStringCasing>;
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* The path to the index file where all services should be exported. The path is relative to the output directory. If nullish, no index file will be generated.
|
|
118
|
-
* @default 'services.ts'
|
|
119
|
-
*/
|
|
120
|
-
servicesIndexFile: Nullable<string>;
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* The directory where the response models should be saved. The path is relative to the output directory.
|
|
124
|
-
* @default 'models/responses'
|
|
125
|
-
*/
|
|
126
|
-
responseModelsDir: string;
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* The casing of the file names for the response models. If nullish, the `fileNameCasing` is used.
|
|
130
|
-
* @default { casing: 'kebab', suffix: '-responses.model' }
|
|
131
|
-
*/
|
|
132
|
-
responseModelFileNameCasing: Nullable<ExtendedStringCasing>;
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* The path to the index file where all response models should be exported. The path is relative to the output directory. If nullish, no index file will be generated.
|
|
136
|
-
* @default 'responses.ts'
|
|
137
|
-
*/
|
|
138
|
-
responseModelsIndexFile: Nullable<string>;
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* The directory where the utilies should be saved. The path is relative to the output directory.
|
|
142
|
-
* @default 'utils'
|
|
143
|
-
*/
|
|
144
|
-
utilsDir: string;
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
export const defaultTypeScriptAngularServicesGeneratorConfig: DefaultGenerationProviderConfig<
|
|
148
|
-
TypeScriptAngularServicesGeneratorConfig
|
|
149
|
-
> = {
|
|
150
|
-
...defaultTypeScriptGeneratorConfig,
|
|
151
|
-
|
|
152
|
-
provideKind: 'provide-fn',
|
|
153
|
-
domainName: undefined,
|
|
154
|
-
strictResponseTypes: true,
|
|
155
|
-
defaultStatusCodeResponseTypes: {
|
|
156
|
-
401: null,
|
|
157
|
-
403: null,
|
|
158
|
-
500: null,
|
|
159
|
-
},
|
|
160
|
-
defaultRequestContentType: undefined,
|
|
161
|
-
defaultSuccessResponseContentType: undefined,
|
|
162
|
-
possibleStatusCodes: [
|
|
163
|
-
100,
|
|
164
|
-
101,
|
|
165
|
-
102,
|
|
166
|
-
103,
|
|
167
|
-
200,
|
|
168
|
-
201,
|
|
169
|
-
202,
|
|
170
|
-
203,
|
|
171
|
-
204,
|
|
172
|
-
205,
|
|
173
|
-
206,
|
|
174
|
-
207,
|
|
175
|
-
208,
|
|
176
|
-
226,
|
|
177
|
-
300,
|
|
178
|
-
301,
|
|
179
|
-
302,
|
|
180
|
-
303,
|
|
181
|
-
304,
|
|
182
|
-
305,
|
|
183
|
-
306,
|
|
184
|
-
307,
|
|
185
|
-
308,
|
|
186
|
-
400,
|
|
187
|
-
401,
|
|
188
|
-
402,
|
|
189
|
-
403,
|
|
190
|
-
404,
|
|
191
|
-
405,
|
|
192
|
-
406,
|
|
193
|
-
407,
|
|
194
|
-
408,
|
|
195
|
-
409,
|
|
196
|
-
410,
|
|
197
|
-
411,
|
|
198
|
-
412,
|
|
199
|
-
413,
|
|
200
|
-
414,
|
|
201
|
-
415,
|
|
202
|
-
416,
|
|
203
|
-
417,
|
|
204
|
-
421,
|
|
205
|
-
422,
|
|
206
|
-
423,
|
|
207
|
-
424,
|
|
208
|
-
425,
|
|
209
|
-
426,
|
|
210
|
-
428,
|
|
211
|
-
429,
|
|
212
|
-
431,
|
|
213
|
-
451,
|
|
214
|
-
500,
|
|
215
|
-
501,
|
|
216
|
-
502,
|
|
217
|
-
503,
|
|
218
|
-
504,
|
|
219
|
-
505,
|
|
220
|
-
506,
|
|
221
|
-
507,
|
|
222
|
-
508,
|
|
223
|
-
510,
|
|
224
|
-
511,
|
|
225
|
-
],
|
|
226
|
-
rootUrl: undefined,
|
|
227
|
-
pathModifier: undefined,
|
|
228
|
-
|
|
229
|
-
servicesDir: 'services',
|
|
230
|
-
serviceFileNameCasing: { casing: 'kebab', suffix: '.service' },
|
|
231
|
-
servicesIndexFile: 'services.ts',
|
|
232
|
-
responseModelsDir: 'models/responses',
|
|
233
|
-
responseModelFileNameCasing: { casing: 'kebab', suffix: '-responses.model' },
|
|
234
|
-
responseModelsIndexFile: 'responses.ts',
|
|
235
|
-
utilsDir: 'utils',
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
export type TypeScriptAngularServicesGeneratorInput = {
|
|
239
|
-
typescript: {
|
|
240
|
-
models: {
|
|
241
|
-
[schemaId: string]: TypeScriptModelGeneratorOutput;
|
|
242
|
-
};
|
|
243
|
-
};
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
export type TypeScriptAngularServicesGeneratorOutput = {
|
|
247
|
-
typescript: {
|
|
248
|
-
services: {
|
|
249
|
-
[serviceId: string]: TypeScriptAngularServiceGeneratorOutput;
|
|
250
|
-
};
|
|
251
|
-
indexFiles: {
|
|
252
|
-
services: Nullable<string>;
|
|
253
|
-
responseModels: Nullable<string>;
|
|
254
|
-
};
|
|
255
|
-
};
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
export type TypeScriptAngularServiceGeneratorOutput = TypeScriptExportOutput & {
|
|
259
|
-
responseModels: {
|
|
260
|
-
[operationId: string]: TypeScriptExportOutput;
|
|
261
|
-
};
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
export type TypeScriptAngularServicesGeneratorContext =
|
|
265
|
-
& OpenApiServicesGenerationProviderContext<
|
|
266
|
-
TypeScriptAngularServicesGeneratorInput,
|
|
267
|
-
TypeScriptAngularServicesGeneratorOutput,
|
|
268
|
-
TypeScriptAngularServicesGeneratorConfig,
|
|
269
|
-
TypeScriptAngularServiceGeneratorOutput
|
|
270
|
-
>
|
|
271
|
-
& {
|
|
272
|
-
refs: ReturnType<typeof getReferenceFactories>;
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
export type TypeScriptAngularServiceGeneratorContext = TypeScriptAngularServicesGeneratorContext & {
|
|
276
|
-
readonly service: ApiService;
|
|
277
|
-
};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { join, resolve } from 'node:path';
|
|
2
|
-
|
|
3
|
-
import { toCasing } from '@goast/core';
|
|
4
|
-
|
|
5
|
-
import { ts } from '../../../ast/index.js';
|
|
6
|
-
|
|
7
|
-
import type { TypeScriptAngularServicesGeneratorConfig } from './models.js';
|
|
8
|
-
|
|
9
|
-
// See packages/typescript/assets/client/angular for reference
|
|
10
|
-
export function getReferenceFactories(options: TypeScriptAngularServicesGeneratorConfig): {
|
|
11
|
-
abortablePromise: ts.GenericModuleReferenceFactory<1>;
|
|
12
|
-
waitForResponse: ts.GenericModuleReferenceFactory<1>;
|
|
13
|
-
requestBuilder: ts.ModuleReferenceFactory;
|
|
14
|
-
apiConfiguration: ts.ModuleReferenceFactory;
|
|
15
|
-
apiBaseService: ts.ModuleReferenceFactory;
|
|
16
|
-
httpStatusCode: ts.ModuleReferenceFactory;
|
|
17
|
-
provide: ts.ModuleReferenceFactory;
|
|
18
|
-
} {
|
|
19
|
-
const utilsDirPath = resolve(options.outputDir, options.utilsDir);
|
|
20
|
-
return {
|
|
21
|
-
// angular-service.utils.ts
|
|
22
|
-
abortablePromise: ts.reference.genericFactory<1>(
|
|
23
|
-
'AbortablePromise',
|
|
24
|
-
join(utilsDirPath, 'angular-service.utils.ts'),
|
|
25
|
-
{
|
|
26
|
-
importType: 'type-import',
|
|
27
|
-
},
|
|
28
|
-
),
|
|
29
|
-
waitForResponse: ts.reference.genericFactory<1>('waitForResponse', join(utilsDirPath, 'angular-service.utils.ts')),
|
|
30
|
-
|
|
31
|
-
// request-builder.ts
|
|
32
|
-
requestBuilder: ts.reference.factory('RequestBuilder', join(utilsDirPath, 'request-builder.ts')),
|
|
33
|
-
|
|
34
|
-
// api-configuration.ts - generated in angular-services-generator.ts
|
|
35
|
-
apiConfiguration: ts.reference.factory(
|
|
36
|
-
toCasing(`${options.domainName ?? ''}ApiConfiguration`, options.typeNameCasing),
|
|
37
|
-
join(utilsDirPath, 'api-configuration.ts'),
|
|
38
|
-
),
|
|
39
|
-
|
|
40
|
-
// api-base-service.ts - generated in angular-service-generator.ts
|
|
41
|
-
apiBaseService: ts.reference.factory('ApiBaseService', join(utilsDirPath, 'api-base-service.ts')),
|
|
42
|
-
|
|
43
|
-
// http-status-code.ts - generated in angular-services-generator.ts
|
|
44
|
-
httpStatusCode: ts.reference.factory('HttpStatusCode', join(utilsDirPath, 'http-status-code.ts'), {
|
|
45
|
-
importType: 'type-import',
|
|
46
|
-
}),
|
|
47
|
-
|
|
48
|
-
// provide.ts - generated in angular-services-generator.ts
|
|
49
|
-
provide: ts.reference.factory(
|
|
50
|
-
toCasing(`provide_${options.domainName ?? ''}_Api`, options.functionNameCasing),
|
|
51
|
-
join(utilsDirPath, 'provide.ts'),
|
|
52
|
-
),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
adjustCasing,
|
|
5
|
-
type ApiEndpoint,
|
|
6
|
-
type ApiSchema,
|
|
7
|
-
type AppendValueGroup,
|
|
8
|
-
appendValueGroup,
|
|
9
|
-
builderTemplate as s,
|
|
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 { TypeScriptEasyNetworkStubGeneratorContext, TypeScriptEasyNetworkStubGeneratorOutput } from './models.js';
|
|
18
|
-
|
|
19
|
-
type Context = TypeScriptEasyNetworkStubGeneratorContext;
|
|
20
|
-
type Output = TypeScriptEasyNetworkStubGeneratorOutput;
|
|
21
|
-
type Builder = TypeScriptFileBuilder;
|
|
22
|
-
|
|
23
|
-
export interface TypeScriptEasyNetworkStubGenerator<TOutput extends Output = Output> {
|
|
24
|
-
generate(ctx: Context): MaybePromise<TOutput>;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export class DefaultTypeScriptEasyNetworkStubGenerator extends TypeScriptFileGenerator<Context, Output>
|
|
28
|
-
implements TypeScriptEasyNetworkStubGenerator {
|
|
29
|
-
public generate(ctx: Context): MaybePromise<Output> {
|
|
30
|
-
const filePath = this.getStubFilePath(ctx);
|
|
31
|
-
const name = this.getStubClassName(ctx);
|
|
32
|
-
|
|
33
|
-
TypeScriptFileBuilder.generate({
|
|
34
|
-
logName: `stub ${name}`,
|
|
35
|
-
filePath,
|
|
36
|
-
options: ctx.config,
|
|
37
|
-
generator: (b) => b.append(this.getStubFileContent(ctx)),
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
filePath,
|
|
42
|
-
component: name,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
protected getStubFileContent(ctx: Context): AppendValueGroup<Builder> {
|
|
47
|
-
return appendValueGroup(
|
|
48
|
-
[...ctx.service.endpoints.map((endpoint) => this.getResponderVariable(ctx, endpoint)), this.getStubClass(ctx)],
|
|
49
|
-
'\n',
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
protected getResponderVariable(ctx: Context, endpoint: ApiEndpoint): ts.Variable<Builder> {
|
|
54
|
-
return ts.variable(this.getResponderVariableName(ctx, endpoint), {
|
|
55
|
-
readonly: true,
|
|
56
|
-
value: ts.call(
|
|
57
|
-
ctx.refs.getStubResponder([
|
|
58
|
-
ts.objectType({
|
|
59
|
-
members: Object.entries(this.getEndpointStatusCodes(ctx, endpoint)).map(([statusCode, type]) =>
|
|
60
|
-
ts.property<Builder>(statusCode, { type })
|
|
61
|
-
),
|
|
62
|
-
}),
|
|
63
|
-
]),
|
|
64
|
-
[],
|
|
65
|
-
),
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
protected getStubClass(ctx: Context): ts.Class<Builder> {
|
|
70
|
-
return ts.class(this.getStubClassName(ctx), {
|
|
71
|
-
export: true,
|
|
72
|
-
extends: ctx.refs.easyNetworkStubBase(),
|
|
73
|
-
members: [
|
|
74
|
-
...ctx.service.endpoints.map((endpoint) =>
|
|
75
|
-
ts.property<Builder>(this.getEndpointPathPropertyName(ctx, endpoint), {
|
|
76
|
-
static: true,
|
|
77
|
-
readonly: true,
|
|
78
|
-
accessModifier: 'private',
|
|
79
|
-
value: s`${ts.string(this.getStubRoute(ctx, endpoint))} as const`,
|
|
80
|
-
})
|
|
81
|
-
),
|
|
82
|
-
'\n',
|
|
83
|
-
...ctx.service.endpoints.map((endpoint) =>
|
|
84
|
-
ts.property<Builder>(this.getEndpointRequestsFieldName(ctx, endpoint), {
|
|
85
|
-
readonly: true,
|
|
86
|
-
accessModifier: 'private',
|
|
87
|
-
type: this.getEndpointRequestsType(ctx, endpoint),
|
|
88
|
-
value: ts.tuple([]),
|
|
89
|
-
})
|
|
90
|
-
),
|
|
91
|
-
'\n',
|
|
92
|
-
...ctx.service.endpoints.map((endpoint) =>
|
|
93
|
-
ts.property<Builder>(this.getEndpointRequestsPropertyName(ctx, endpoint), {
|
|
94
|
-
readonly: true,
|
|
95
|
-
accessModifier: 'public',
|
|
96
|
-
type: this.getEndpointRequestsType(ctx, endpoint, { readonly: true }),
|
|
97
|
-
get: ts.property.getter({
|
|
98
|
-
body: appendValueGroup([`return this.${this.getEndpointRequestsFieldName(ctx, endpoint)};`], '\n'),
|
|
99
|
-
}),
|
|
100
|
-
})
|
|
101
|
-
),
|
|
102
|
-
...ctx.service.endpoints.map((endpoint) => this.getEndpointStubMethod(ctx, endpoint)),
|
|
103
|
-
ts.method('reset', {
|
|
104
|
-
accessModifier: 'public',
|
|
105
|
-
override: true,
|
|
106
|
-
returnType: ts.refs.void_(),
|
|
107
|
-
body: appendValueGroup(
|
|
108
|
-
[
|
|
109
|
-
...ctx.service.endpoints.map((endpoint) =>
|
|
110
|
-
`this.${this.getEndpointRequestsFieldName(ctx, endpoint)}.length = 0;`
|
|
111
|
-
),
|
|
112
|
-
'super.reset();',
|
|
113
|
-
],
|
|
114
|
-
'\n',
|
|
115
|
-
),
|
|
116
|
-
}),
|
|
117
|
-
],
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
protected getEndpointRequestsType(
|
|
122
|
-
ctx: Context,
|
|
123
|
-
endpoint: ApiEndpoint,
|
|
124
|
-
options?: { readonly?: boolean },
|
|
125
|
-
): ts.Type<Builder> {
|
|
126
|
-
return ts.arrayType(
|
|
127
|
-
ctx.refs.stubRequestInfo([
|
|
128
|
-
ts.typeof(ts.call([this.getStubClassName(ctx), this.getEndpointPathPropertyName(ctx, endpoint)])),
|
|
129
|
-
this.getSchemaType(ctx, endpoint.requestBody?.content[0].schema),
|
|
130
|
-
]),
|
|
131
|
-
options,
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
protected getEndpointStubMethod(ctx: Context, endpoint: ApiEndpoint): ts.Method<Builder> {
|
|
136
|
-
const requestType = this.getSchemaType(ctx, endpoint.requestBody?.content[0].schema);
|
|
137
|
-
return ts.method(this.getEndpointStubMethodName(ctx, endpoint), {
|
|
138
|
-
accessModifier: 'public',
|
|
139
|
-
parameters: [
|
|
140
|
-
ts.parameter('response', {
|
|
141
|
-
type: ctx.refs.strictRouteResponseCallback([
|
|
142
|
-
requestType,
|
|
143
|
-
ts.typeof(ts.call([this.getStubClassName(ctx), this.getEndpointPathPropertyName(ctx, endpoint)])),
|
|
144
|
-
ts.typeof(this.getResponderVariableName(ctx, endpoint)),
|
|
145
|
-
]),
|
|
146
|
-
}),
|
|
147
|
-
],
|
|
148
|
-
returnType: 'this',
|
|
149
|
-
body: appendValueGroup(
|
|
150
|
-
[
|
|
151
|
-
s`this.stubWrapper.stub2<${requestType}>()(${s.indent`
|
|
152
|
-
${ts.string(endpoint.method.toUpperCase())},
|
|
153
|
-
${this.getStubClassName(ctx)}.${this.getEndpointPathPropertyName(ctx, endpoint)},
|
|
154
|
-
async (request) => {${s.indent`
|
|
155
|
-
if (this.stubWrapper.options.rememberRequests) {${s.indent`
|
|
156
|
-
this.${this.getEndpointRequestsFieldName(ctx, endpoint)}.push(request);`}
|
|
157
|
-
}
|
|
158
|
-
throw await response(${this.getResponderVariableName(ctx, endpoint)}, request);`}
|
|
159
|
-
}`}
|
|
160
|
-
);`,
|
|
161
|
-
'return this;',
|
|
162
|
-
],
|
|
163
|
-
'\n',
|
|
164
|
-
),
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
protected getStubFilePath(ctx: Context): string {
|
|
169
|
-
return resolve(
|
|
170
|
-
ctx.config.outputDir,
|
|
171
|
-
ctx.config.stubsDir,
|
|
172
|
-
`${toCasing(ctx.service.name, ctx.config.stubFileNameCasing ?? ctx.config.fileNameCasing)}.ts`,
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
protected getResponderVariableName(ctx: Context, endpoint: ApiEndpoint): string {
|
|
177
|
-
return toCasing(endpoint.name + '_Responder', ctx.config.propertyNameCasing);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
protected getStubClassName(ctx: Context): string {
|
|
181
|
-
return toCasing(ctx.service.name + '_Stubs', ctx.config.typeNameCasing);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
protected getEndpointPathPropertyName(ctx: Context, endpoint: ApiEndpoint): string {
|
|
185
|
-
return toCasing(endpoint.name + '_Path', ctx.config.constantNameCasing);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
protected getEndpointRequestsFieldName(ctx: Context, endpoint: ApiEndpoint): string {
|
|
189
|
-
return toCasing(endpoint.name + '_Requests', adjustCasing(ctx.config.propertyNameCasing, { prefix: '_' }));
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
protected getEndpointRequestsPropertyName(ctx: Context, endpoint: ApiEndpoint): string {
|
|
193
|
-
return toCasing(endpoint.name + '_Requests', ctx.config.propertyNameCasing);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
protected getEndpointStubMethodName(ctx: Context, endpoint: ApiEndpoint): string {
|
|
197
|
-
return toCasing('stub_' + endpoint.name, ctx.config.functionNameCasing);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
protected getStubRoute(ctx: Context, endpoint: ApiEndpoint): string {
|
|
201
|
-
let path = endpoint.path;
|
|
202
|
-
let isFirstQueryParam = true;
|
|
203
|
-
for (const param of endpoint.parameters) {
|
|
204
|
-
let type = ((param.schema && ctx.input.typescript.models[param.schema.id]?.component) ?? ts.refs.unknown.name)
|
|
205
|
-
.replace(
|
|
206
|
-
/^readonly /,
|
|
207
|
-
'',
|
|
208
|
-
);
|
|
209
|
-
|
|
210
|
-
const arrayMatch = /^\((.*)\)\[\]$/.exec(type);
|
|
211
|
-
if (arrayMatch !== null) {
|
|
212
|
-
type = `${arrayMatch[1]}[]`;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (param.target === 'path') {
|
|
216
|
-
path = path.replace(`{${param.name}}`, `{${param.name}${param.required ? '' : '?'}:${type}}`);
|
|
217
|
-
} else if (param.target === 'query') {
|
|
218
|
-
path = path + (isFirstQueryParam ? '?' : '&') + `{${param.name}${param.required ? '' : '?'}:${type}}`;
|
|
219
|
-
isFirstQueryParam = false;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return path.replace(/^\/+/, '');
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
protected getEndpointStatusCodes(ctx: Context, endpoint: ApiEndpoint): Record<number, ts.Type<Builder>> {
|
|
226
|
-
return Object.fromEntries([
|
|
227
|
-
...Object.entries(ctx.config.defaultStatusCodeResponseTypes).map(([key, value]) => [
|
|
228
|
-
key,
|
|
229
|
-
typeof value === 'function' ? this.getSchemaType(ctx, value(ctx.data.schemas)) : value,
|
|
230
|
-
]),
|
|
231
|
-
...endpoint.responses
|
|
232
|
-
.filter((x) => x.statusCode)
|
|
233
|
-
.map((x) => [x.statusCode, this.getSchemaType(ctx, x.contentOptions[0]?.schema, ts.refs.never())]),
|
|
234
|
-
]);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
protected getSchemaType(ctx: Context, schema: ApiSchema | undefined, fallback?: ts.Type<Builder>): ts.Type<Builder> {
|
|
238
|
-
const output = schema && ctx.input.typescript.models[schema.id];
|
|
239
|
-
if (!output) return fallback ?? this.getAnyType(ctx);
|
|
240
|
-
return (b) => b.appendModelUsage(output);
|
|
241
|
-
}
|
|
242
|
-
}
|