@goast/typescript 0.0.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.
Files changed (70) hide show
  1. package/README.md +11 -0
  2. package/assets/client/fetch/types.ts +9 -0
  3. package/assets/client/fetch/url-builder.ts +36 -0
  4. package/assets/service/angular/api-configuration.ts +18 -0
  5. package/assets/service/angular/base-service.ts +29 -0
  6. package/assets/service/angular/request-builder.ts +368 -0
  7. package/assets/service/angular/response-handlers.ts +127 -0
  8. package/assets/service/angular/strict-http-response.ts +8 -0
  9. package/cjs/index.js +9 -0
  10. package/cjs/lib/common-results.js +2 -0
  11. package/cjs/lib/config.js +15 -0
  12. package/cjs/lib/file-builder.js +244 -0
  13. package/cjs/lib/generators/file-generator.js +26 -0
  14. package/cjs/lib/generators/index.js +7 -0
  15. package/cjs/lib/generators/models/index.js +6 -0
  16. package/cjs/lib/generators/models/model-generator.js +317 -0
  17. package/cjs/lib/generators/models/models-generator.js +67 -0
  18. package/cjs/lib/generators/models/models.js +6 -0
  19. package/cjs/lib/generators/services/angular-services/angular-service-generator.js +360 -0
  20. package/cjs/lib/generators/services/angular-services/angular-services-generator.js +122 -0
  21. package/cjs/lib/generators/services/angular-services/index.js +6 -0
  22. package/cjs/lib/generators/services/angular-services/models.js +5 -0
  23. package/cjs/lib/generators/services/fetch-clients/fetch-client-generator.js +240 -0
  24. package/cjs/lib/generators/services/fetch-clients/fetch-clients-generator.js +83 -0
  25. package/cjs/lib/generators/services/fetch-clients/index.js +6 -0
  26. package/cjs/lib/generators/services/fetch-clients/models.js +5 -0
  27. package/cjs/lib/import-collection.js +116 -0
  28. package/cjs/lib/utils.js +56 -0
  29. package/cjs/package.json +1 -0
  30. package/esm/index.js +6 -0
  31. package/esm/lib/common-results.js +1 -0
  32. package/esm/lib/config.js +12 -0
  33. package/esm/lib/file-builder.js +240 -0
  34. package/esm/lib/generators/file-generator.js +22 -0
  35. package/esm/lib/generators/index.js +4 -0
  36. package/esm/lib/generators/models/index.js +3 -0
  37. package/esm/lib/generators/models/model-generator.js +313 -0
  38. package/esm/lib/generators/models/models-generator.js +63 -0
  39. package/esm/lib/generators/models/models.js +3 -0
  40. package/esm/lib/generators/services/angular-services/angular-service-generator.js +356 -0
  41. package/esm/lib/generators/services/angular-services/angular-services-generator.js +118 -0
  42. package/esm/lib/generators/services/angular-services/index.js +3 -0
  43. package/esm/lib/generators/services/angular-services/models.js +2 -0
  44. package/esm/lib/generators/services/fetch-clients/fetch-client-generator.js +236 -0
  45. package/esm/lib/generators/services/fetch-clients/fetch-clients-generator.js +79 -0
  46. package/esm/lib/generators/services/fetch-clients/index.js +3 -0
  47. package/esm/lib/generators/services/fetch-clients/models.js +2 -0
  48. package/esm/lib/import-collection.js +112 -0
  49. package/esm/lib/utils.js +48 -0
  50. package/package.json +29 -0
  51. package/types/index.d.ts +6 -0
  52. package/types/lib/common-results.d.ts +11 -0
  53. package/types/lib/config.d.ts +13 -0
  54. package/types/lib/file-builder.d.ts +110 -0
  55. package/types/lib/generators/file-generator.d.ts +11 -0
  56. package/types/lib/generators/index.d.ts +4 -0
  57. package/types/lib/generators/models/index.d.ts +3 -0
  58. package/types/lib/generators/models/model-generator.d.ts +40 -0
  59. package/types/lib/generators/models/models-generator.d.ts +23 -0
  60. package/types/lib/generators/models/models.d.ts +29 -0
  61. package/types/lib/generators/services/angular-services/angular-service-generator.d.ts +53 -0
  62. package/types/lib/generators/services/angular-services/angular-services-generator.d.ts +29 -0
  63. package/types/lib/generators/services/angular-services/index.d.ts +3 -0
  64. package/types/lib/generators/services/angular-services/models.d.ts +41 -0
  65. package/types/lib/generators/services/fetch-clients/fetch-client-generator.d.ts +43 -0
  66. package/types/lib/generators/services/fetch-clients/fetch-clients-generator.d.ts +24 -0
  67. package/types/lib/generators/services/fetch-clients/index.d.ts +3 -0
  68. package/types/lib/generators/services/fetch-clients/models.d.ts +34 -0
  69. package/types/lib/import-collection.d.ts +21 -0
  70. package/types/lib/utils.d.ts +6 -0
@@ -0,0 +1,356 @@
1
+ import { writeFileSync } from 'fs';
2
+ import { dirname, resolve } from 'path';
3
+ import { ensureDirSync } from 'fs-extra';
4
+ import { toCasing } from '@goast/core';
5
+ import { TypeScriptFileBuilder, } from '../../../file-builder';
6
+ import { TypeScriptFileGenerator } from '../../file-generator';
7
+ export class DefaultTypeScriptAngularServiceGenerator extends TypeScriptFileGenerator {
8
+ constructor() {
9
+ super(...arguments);
10
+ this.httpClientType = {
11
+ name: 'HttpClient',
12
+ module: '@angular/common/http',
13
+ };
14
+ this.httpContextType = {
15
+ name: 'HttpContext',
16
+ module: '@angular/common/http',
17
+ };
18
+ this.httpResponseType = {
19
+ name: 'HttpResponse',
20
+ module: '@angular/common/http',
21
+ };
22
+ this.observableType = {
23
+ name: 'Observable',
24
+ module: 'rxjs',
25
+ };
26
+ this.rxjsFilterType = {
27
+ name: 'filter',
28
+ module: 'rxjs',
29
+ };
30
+ this.rxjsMapType = {
31
+ name: 'map',
32
+ module: 'rxjs',
33
+ };
34
+ }
35
+ getApiConfigurationType(ctx) {
36
+ return { name: 'ApiConfiguration', module: resolve(this.getUtilsDirPath(ctx), 'api-configuration.ts') };
37
+ }
38
+ getBaseServiceType(ctx) {
39
+ return { name: 'BaseService', module: resolve(this.getUtilsDirPath(ctx), 'base-service.ts') };
40
+ }
41
+ getStrictHttpResponseType(ctx) {
42
+ return { name: 'StrictHttpResponse', module: resolve(this.getUtilsDirPath(ctx), 'strict-http-response.ts') };
43
+ }
44
+ getRequestBuilderType(ctx) {
45
+ return { name: 'RequestBuilder', module: resolve(this.getUtilsDirPath(ctx), 'request-builder.ts') };
46
+ }
47
+ generate(ctx) {
48
+ const filePath = this.getServiceFilePath(ctx);
49
+ const name = this.getServiceClassName(ctx);
50
+ console.log(`Generating service ${name} in ${filePath}...`);
51
+ ensureDirSync(dirname(filePath));
52
+ const serviceBuilder = new TypeScriptFileBuilder(filePath, ctx.config);
53
+ this.generateServiceFileContent(ctx, serviceBuilder);
54
+ writeFileSync(filePath, serviceBuilder.toString());
55
+ return {
56
+ filePath,
57
+ component: name,
58
+ responseModels: {},
59
+ imports: [{ kind: 'file', name, modulePath: filePath }],
60
+ };
61
+ }
62
+ generateServiceFileContent(ctx, builder) {
63
+ builder
64
+ .append((builder) => builder.forEach(ctx.service.endpoints, (builder, endpoint) => this.generateEndpointParamsType(ctx, builder, endpoint), { separator: '\n' }))
65
+ .ensurePreviousLineEmpty()
66
+ .append((builder) => this.generateClass(ctx, builder));
67
+ }
68
+ // protected generateResponseModels(ctx: Context): Output['responseModels'] {
69
+ // const filePath = this.get;
70
+ // const builder = new TypeScriptFileBuilder();
71
+ // }
72
+ //protected generateResponseModelsFileContent(ctx: Context, builder: Builder) {}
73
+ generateEndpointParamsType(ctx, builder, endpoint) {
74
+ if (!this.hasEndpointParams(ctx, endpoint)) {
75
+ return;
76
+ }
77
+ const params = [];
78
+ for (const parameter of endpoint.parameters) {
79
+ const schema = parameter.schema;
80
+ params.push((builder) => builder.appendProperty({
81
+ name: this.toPropertyName(ctx, parameter.name),
82
+ documentation: parameter.description,
83
+ type: schema ? (builder) => builder.appendModelUsage(ctx.input.models[schema.id]) : this.getAnyType(ctx),
84
+ isOptional: !parameter.required,
85
+ }));
86
+ }
87
+ if (endpoint.requestBody !== undefined) {
88
+ const body = endpoint.requestBody;
89
+ const schema = body.content[0].schema;
90
+ params.push((builder) => builder.appendProperty({
91
+ name: 'body',
92
+ documentation: body.description,
93
+ type: schema ? (builder) => builder.appendModelUsage(ctx.input.models[schema.id]) : this.getAnyType(ctx),
94
+ isOptional: !body.required,
95
+ }));
96
+ }
97
+ builder.appendTypeDeclaration({
98
+ name: this.getEndpointParamsTypeName(ctx, endpoint),
99
+ documentation: `Parameters for operation ${this.getEndpointMethodName(ctx, endpoint)}`,
100
+ type: (builder) => builder.appendCodeBlock(...params),
101
+ });
102
+ }
103
+ generateClass(ctx, builder) {
104
+ builder.appendClass(this.getClassOptions(ctx));
105
+ }
106
+ generateClassContent(ctx, builder) {
107
+ builder
108
+ .append((builder) => this.generateConstructor(ctx, builder))
109
+ .forEach(ctx.service.endpoints, (builder, endpoint) => builder.ensurePreviousLineEmpty().append((builder) => this.generateEndpoint(ctx, builder, endpoint)));
110
+ }
111
+ generateConstructor(ctx, builder) {
112
+ builder.appendConstructor(this.getConstructorOptions(ctx));
113
+ }
114
+ generateConstructorContent(ctx, builder) {
115
+ builder.appendLine('super(config, http);');
116
+ }
117
+ generateEndpoint(ctx, builder, endpoint) {
118
+ builder
119
+ .append((builder) => this.generateEndpointPathProperty(ctx, builder, endpoint))
120
+ .ensurePreviousLineEmpty()
121
+ .append((builder) => this.generateEndpointResponseMethod(ctx, builder, endpoint))
122
+ .ensurePreviousLineEmpty()
123
+ .append((builder) => this.generateEndpointMethod(ctx, builder, endpoint));
124
+ }
125
+ generateEndpointPathProperty(ctx, builder, endpoint) {
126
+ builder.appendProperty(this.getEndpointPathPropertyOptions(ctx, endpoint));
127
+ }
128
+ generateEndpointResponseMethod(ctx, builder, endpoint) {
129
+ builder.appendMethod(this.getEndpointResponseMethodOptions(ctx, endpoint));
130
+ }
131
+ generateEndpointResponseMethodContent(ctx, builder, endpoint) {
132
+ var _a, _b;
133
+ builder
134
+ .append('const rb = new ')
135
+ .appendExternalTypeUsage(this.getRequestBuilderType(ctx))
136
+ .appendParameters('this.rootUrl', `${this.getServiceClassName(ctx)}.${this.getEndpointPathPropertyName(ctx, endpoint)}`, this.toStringLiteral(ctx, endpoint.method))
137
+ .appendLine(';');
138
+ if (this.hasEndpointParams(ctx, endpoint)) {
139
+ builder.append('if (params) ').appendCodeBlock((builder) => builder
140
+ .forEach(endpoint.parameters.filter((x) => x.target === 'path' || x.target === 'query' || x.target === 'header'), (builder, parameter) => builder
141
+ .append('rb.', parameter.target)
142
+ .appendParameters(this.toStringLiteral(ctx, parameter.name), `params.${toCasing(parameter.name, 'camel')}`, (builder) => builder.appendObjectLiteral(parameter.style !== undefined
143
+ ? `style: ${this.toStringLiteral(ctx, parameter.style)}`
144
+ : undefined, parameter.explode !== undefined ? `explode: ${parameter.explode ? 'true' : 'false'}` : undefined))
145
+ .appendLine(';'))
146
+ .if(endpoint.requestBody !== undefined, (builder) => {
147
+ var _a, _b, _c;
148
+ return builder
149
+ .append('rb.body')
150
+ .appendParameters('params.body', this.toStringLiteral(ctx, (_c = (_b = (_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.content[0]) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : 'application/json'))
151
+ .appendLine(';');
152
+ }));
153
+ }
154
+ const response = this.getEndpointSuccessResponse(ctx, endpoint);
155
+ const accept = (_b = (_a = response === null || response === void 0 ? void 0 : response.contentOptions[0]) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : '*/*';
156
+ const responseType = accept.includes('json') ? 'json' : 'text';
157
+ builder
158
+ .ensurePreviousLineEmpty()
159
+ .append('this.http.request')
160
+ .appendParameters((builder) => builder
161
+ .append('rb.build')
162
+ .appendParameters((builder) => builder.appendObjectLiteral(`responseType: ${this.toStringLiteral(ctx, responseType)}`, `accept: ${this.toStringLiteral(ctx, accept)}`, 'context: context')))
163
+ .append('.pipe')
164
+ .appendParameters((builder) => builder.appendExternalTypeUsage(this.rxjsFilterType).appendParameters((builder) => builder.appendFunction({
165
+ parameters: ['r: any'],
166
+ body: (builder) => builder.append('r instanceof ').appendExternalTypeUsage(this.httpResponseType),
167
+ singleLine: true,
168
+ })), (builder) => builder.appendExternalTypeUsage(this.rxjsMapType).appendParameters((builder) => {
169
+ var _a;
170
+ return builder.appendFunction({
171
+ parameters: [{ name: 'r', type: this.httpResponseType, genericArguments: ['any'] }],
172
+ body: ((_a = response === null || response === void 0 ? void 0 : response.contentOptions) === null || _a === void 0 ? void 0 : _a[0])
173
+ ? (builder) => builder
174
+ .append('r as ')
175
+ .appendExternalTypeUsage(this.getStrictHttpResponseType(ctx))
176
+ .appendGenericArguments((builder) => this.generateEndpointSuccessResponseSchema(ctx, builder, endpoint))
177
+ : (builder) => builder
178
+ .parenthesize('()', (builder) => builder
179
+ .append('r as ')
180
+ .appendExternalTypeUsage(this.httpResponseType)
181
+ .appendGenericArguments('any'))
182
+ .append('.clone')
183
+ .appendParameters((builder) => builder.appendObjectLiteral('body: undefined'))
184
+ .append(' as ')
185
+ .appendExternalTypeUsage(this.getStrictHttpResponseType(ctx))
186
+ .appendGenericArguments('void'),
187
+ singleLine: true,
188
+ });
189
+ }))
190
+ .appendLine(';');
191
+ }
192
+ generateEndpointMethod(ctx, builder, endpoint) {
193
+ builder.appendMethod(this.getEndpointMethodOptions(ctx, endpoint));
194
+ }
195
+ generateEndpointMethodContent(ctx, builder, endpoint) {
196
+ builder
197
+ .append('return this.', this.getEndpointResponseMethodName(ctx, endpoint))
198
+ .appendParameters(this.hasEndpointParams(ctx, endpoint) ? 'params' : undefined, 'context')
199
+ .append('.pipe')
200
+ .appendParameters((builder) => builder
201
+ .appendExternalTypeUsage(this.rxjsMapType)
202
+ .append('((r: ')
203
+ .appendExternalTypeUsage(this.getStrictHttpResponseType(ctx))
204
+ .appendGenericArguments((builder) => this.generateEndpointSuccessResponseSchema(ctx, builder, endpoint))
205
+ .append(') => r.body as ')
206
+ .append((builder) => this.generateEndpointSuccessResponseSchema(ctx, builder, endpoint))
207
+ .append(')'))
208
+ .appendLine(';');
209
+ }
210
+ getClassOptions(ctx) {
211
+ return {
212
+ name: this.getServiceClassName(ctx),
213
+ documentation: ctx.service.description,
214
+ annotations: [
215
+ {
216
+ name: 'Injectable',
217
+ module: '@angular/core',
218
+ args: [(builder) => builder.appendObjectLiteral(`providedIn: ${this.toStringLiteral(ctx, 'root')}`)],
219
+ },
220
+ ],
221
+ extends: (builder) => builder.appendExternalTypeUsage(this.getBaseServiceType(ctx)),
222
+ body: (builder) => this.generateClassContent(ctx, builder),
223
+ };
224
+ }
225
+ getConstructorOptions(ctx) {
226
+ return {
227
+ parameters: [
228
+ { name: 'config', type: (builder) => builder.appendExternalTypeUsage(this.getApiConfigurationType(ctx)) },
229
+ { name: 'http', type: (builder) => builder.appendExternalTypeUsage(this.httpClientType) },
230
+ ],
231
+ body: (builder) => this.generateConstructorContent(ctx, builder),
232
+ };
233
+ }
234
+ getEndpointPathPropertyOptions(ctx, endpoint) {
235
+ return {
236
+ name: this.getEndpointPathPropertyName(ctx, endpoint),
237
+ documentation: ctx.config.exposePathProperties
238
+ ? `Path part for operation ${this.getEndpointMethodName(ctx, endpoint)}`
239
+ : undefined,
240
+ isStatic: true,
241
+ accessibility: ctx.config.exposePathProperties ? 'public' : 'protected',
242
+ isReadonly: true,
243
+ initializer: this.toStringLiteral(ctx, endpoint.path),
244
+ };
245
+ }
246
+ getEndpointMethodParams(ctx, endpoint) {
247
+ const params = [];
248
+ if (this.hasEndpointParams(ctx, endpoint)) {
249
+ params.push({
250
+ name: 'params',
251
+ type: this.getEndpointParamsTypeName(ctx, endpoint),
252
+ });
253
+ }
254
+ params.push({
255
+ name: 'context',
256
+ isOptional: true,
257
+ type: (builder) => builder.appendExternalTypeUsage(this.httpContextType),
258
+ });
259
+ return params;
260
+ }
261
+ generateEndpointSuccessResponseSchema(ctx, builder, endpoint) {
262
+ var _a;
263
+ const successResponse = this.getEndpointSuccessResponse(ctx, endpoint);
264
+ const schema = (_a = successResponse === null || successResponse === void 0 ? void 0 : successResponse.contentOptions[0]) === null || _a === void 0 ? void 0 : _a.schema;
265
+ if (schema) {
266
+ const model = ctx.input.models[schema.id];
267
+ if (model) {
268
+ builder.appendModelUsage(model);
269
+ }
270
+ else {
271
+ builder.append(this.getAnyType(ctx));
272
+ }
273
+ }
274
+ else {
275
+ builder.append('void');
276
+ }
277
+ }
278
+ getEndpointResponseMethodOptions(ctx, endpoint) {
279
+ return {
280
+ name: this.getEndpointResponseMethodName(ctx, endpoint),
281
+ accessibility: ctx.config.exposeResponseMethods ? 'public' : 'protected',
282
+ documentation: ctx.config.exposeResponseMethods
283
+ ? [
284
+ endpoint.summary,
285
+ endpoint.description,
286
+ 'This method provides access to the full `HttpResponse`, allowing access to response headers.\n' +
287
+ `To access only the response body, use \`${this.getEndpointMethodName(ctx, endpoint)}()\` instead.`,
288
+ ]
289
+ .filter((x) => x)
290
+ .join('\n\n')
291
+ : undefined,
292
+ parameters: this.getEndpointMethodParams(ctx, endpoint),
293
+ returnType: (builder) => builder
294
+ .appendExternalTypeUsage(this.observableType)
295
+ .appendGenericArguments((builder) => builder
296
+ .appendExternalTypeUsage(this.getStrictHttpResponseType(ctx))
297
+ .appendGenericArguments((builder) => this.generateEndpointSuccessResponseSchema(ctx, builder, endpoint))),
298
+ body: (builder) => this.generateEndpointResponseMethodContent(ctx, builder, endpoint),
299
+ };
300
+ }
301
+ getEndpointMethodOptions(ctx, endpoint) {
302
+ return {
303
+ name: this.getEndpointMethodName(ctx, endpoint),
304
+ accessibility: 'public',
305
+ documentation: [
306
+ endpoint.summary,
307
+ endpoint.description,
308
+ ctx.config.exposeResponseMethods
309
+ ? 'This method provides access only to the response body.\n' +
310
+ `To access the full response (for headers, for example), \`${this.getEndpointResponseMethodName(ctx, endpoint)}()\` instead.`
311
+ : undefined,
312
+ ]
313
+ .filter((x) => x)
314
+ .join('\n\n'),
315
+ parameters: this.getEndpointMethodParams(ctx, endpoint),
316
+ returnType: ctx.config.clientMethodFlavor === 'response-handler'
317
+ ? 'void'
318
+ : (builder) => builder
319
+ .appendExternalTypeUsage(this.observableType)
320
+ .appendGenericArguments((builder) => this.generateEndpointSuccessResponseSchema(ctx, builder, endpoint)),
321
+ body: (builder) => this.generateEndpointMethodContent(ctx, builder, endpoint),
322
+ };
323
+ }
324
+ getEndpointSuccessResponse(ctx, endpoint) {
325
+ var _a;
326
+ return ((_a = endpoint.responses.find((x) => x.statusCode && x.statusCode >= 200 && x.statusCode < 300)) !== null && _a !== void 0 ? _a : endpoint.responses.find((x) => x.statusCode === undefined));
327
+ }
328
+ getServiceClassName(ctx) {
329
+ return this.toTypeName(ctx, ctx.service.name);
330
+ }
331
+ hasEndpointParams(ctx, endpoint) {
332
+ return endpoint.parameters.length > 0 || endpoint.requestBody !== undefined;
333
+ }
334
+ getEndpointParamsTypeName(ctx, endpoint) {
335
+ return toCasing(this.getEndpointMethodName(ctx, endpoint), 'pascal') + 'Params';
336
+ }
337
+ getEndpointPathPropertyName(ctx, endpoint) {
338
+ return this.getEndpointMethodName(ctx, endpoint) + 'Path';
339
+ }
340
+ getEndpointMethodName(ctx, endpoint) {
341
+ return this.toMethodName(ctx, endpoint.name);
342
+ }
343
+ getEndpointResponseMethodName(ctx, endpoint) {
344
+ return this.getEndpointMethodName(ctx, endpoint) + '$Response';
345
+ }
346
+ getServiceFilePath(ctx) {
347
+ return resolve(ctx.config.outputDir, ctx.config.servicesDirPath, `${toCasing(ctx.service.name, ctx.config.fileNameCasing)}.ts`);
348
+ }
349
+ getResponseModelsFilePath(ctx) {
350
+ var _a;
351
+ return resolve(ctx.config.outputDir, (_a = ctx.config.responseModelsDirPath) !== null && _a !== void 0 ? _a : 'models/responses', `${toCasing(ctx.service.name, ctx.config.responseModelsFileNameCasing)}.ts`);
352
+ }
353
+ getUtilsDirPath(ctx) {
354
+ return resolve(ctx.config.outputDir, ctx.config.utilsDirPath);
355
+ }
356
+ }
@@ -0,0 +1,118 @@
1
+ import { readFileSync } from 'fs';
2
+ import { dirname, resolve } from 'path';
3
+ import { ensureDirSync, writeFileSync } from 'fs-extra';
4
+ import { Factory, OpenApiServicesGenerationProviderBase, notNullish, } from '@goast/core';
5
+ import { DefaultTypeScriptAngularServiceGenerator, } from './angular-service-generator';
6
+ import { defaultTypeScriptAngularServicesGeneratorConfig, } from './models';
7
+ import { TypeScriptFileBuilder } from '../../../file-builder';
8
+ import { ImportExportCollection } from '../../../import-collection';
9
+ import { modifyString } from '../../../utils';
10
+ export class TypeScriptAngularServicesGenerator extends OpenApiServicesGenerationProviderBase {
11
+ constructor(clientGeneratorFactory) {
12
+ super();
13
+ this._clientGeneratorFactory =
14
+ clientGeneratorFactory !== null && clientGeneratorFactory !== void 0 ? clientGeneratorFactory : Factory.fromValue(new DefaultTypeScriptAngularServiceGenerator());
15
+ }
16
+ initResult() {
17
+ return {
18
+ services: {},
19
+ servicesIndexFilePath: undefined,
20
+ responseModelsIndexFilePath: undefined,
21
+ };
22
+ }
23
+ buildContext(context, config) {
24
+ return this.getProviderContext(context, config, defaultTypeScriptAngularServicesGeneratorConfig);
25
+ }
26
+ onGenerate(ctx) {
27
+ const output = super.onGenerate(ctx);
28
+ this.copyUtilsFiles(ctx);
29
+ output.servicesIndexFilePath = this.generateServicesIndexFile(ctx);
30
+ return output;
31
+ }
32
+ generateService(ctx, service) {
33
+ const clientGenerator = this._clientGeneratorFactory.create();
34
+ return clientGenerator.generate(Object.assign(Object.assign({}, ctx), { service }));
35
+ }
36
+ addServiceResult(ctx, service, result) {
37
+ ctx.output.services[service.id] = result;
38
+ }
39
+ generateServicesIndexFile(ctx) {
40
+ if (!this.shouldGenerateServicesIndexFile(ctx)) {
41
+ return undefined;
42
+ }
43
+ const filePath = this.getServicesIndexFilePath(ctx);
44
+ console.log(`Generating index file to ${filePath}...`);
45
+ ensureDirSync(dirname(filePath));
46
+ const builder = new TypeScriptFileBuilder(filePath, ctx.config);
47
+ this.generateServicesIndexFileContent(ctx, builder);
48
+ writeFileSync(filePath, builder.toString());
49
+ return filePath;
50
+ }
51
+ getServicesIndexFilePath(ctx) {
52
+ var _a;
53
+ return resolve(ctx.config.outputDir, (_a = ctx.config.indexFilePath) !== null && _a !== void 0 ? _a : 'clients.ts');
54
+ }
55
+ shouldGenerateServicesIndexFile(ctx) {
56
+ return notNullish(ctx.config.indexFilePath);
57
+ }
58
+ generateServicesIndexFileContent(ctx, builder) {
59
+ const exports = new ImportExportCollection();
60
+ for (const serviceId in ctx.output.services) {
61
+ const service = ctx.output.services[serviceId];
62
+ exports.addExport(service.component, service.filePath);
63
+ }
64
+ exports.writeTo(builder);
65
+ }
66
+ generateResponseModelsIndexFile(ctx) {
67
+ if (!this.shouldGenerateResponseModelsIndexFile(ctx)) {
68
+ return undefined;
69
+ }
70
+ const filePath = this.getResponseModelsIndexFilePath(ctx);
71
+ console.log(`Generating response models index file to ${filePath}...`);
72
+ ensureDirSync(dirname(filePath));
73
+ const builder = new TypeScriptFileBuilder(filePath, ctx.config);
74
+ this.generateResponseModelsIndexFileContent(ctx, builder);
75
+ writeFileSync(filePath, builder.toString());
76
+ return filePath;
77
+ }
78
+ getResponseModelsIndexFilePath(ctx) {
79
+ var _a;
80
+ return resolve(ctx.config.outputDir, (_a = ctx.config.responseModelsIndexFilePath) !== null && _a !== void 0 ? _a : 'responses.ts');
81
+ }
82
+ shouldGenerateResponseModelsIndexFile(ctx) {
83
+ return notNullish(ctx.config.responseModelsDirPath) && notNullish(ctx.config.responseModelsIndexFilePath);
84
+ }
85
+ generateResponseModelsIndexFileContent(ctx, builder) {
86
+ const exports = new ImportExportCollection();
87
+ for (const serviceId in ctx.output.services) {
88
+ const service = ctx.output.services[serviceId];
89
+ for (const operationId in service.responseModels) {
90
+ const responseModel = service.responseModels[operationId];
91
+ if (responseModel.filePath) {
92
+ exports.addExport(responseModel.component, responseModel.filePath);
93
+ }
94
+ }
95
+ }
96
+ exports.writeTo(builder);
97
+ }
98
+ copyUtilsFiles(ctx) {
99
+ const sourceDir = resolve(dirname(require.resolve('@goast/typescript')), '../assets/service/angular');
100
+ const targetDir = resolve(ctx.config.outputDir, ctx.config.utilsDirPath);
101
+ ensureDirSync(targetDir);
102
+ const files = ['api-configuration.ts', 'base-service.ts', 'request-builder.ts', 'strict-http-response.ts'];
103
+ if (ctx.config.clientMethodFlavor === 'response-handler') {
104
+ files.push('response-handler.ts');
105
+ }
106
+ const rootUrl = this.getRootUrl(ctx);
107
+ for (const file of files) {
108
+ const fileContent = readFileSync(resolve(sourceDir, file))
109
+ .toString()
110
+ .replace(/@ROOT_URL@/g, rootUrl);
111
+ writeFileSync(resolve(targetDir, file), fileContent);
112
+ }
113
+ }
114
+ getRootUrl(ctx) {
115
+ var _a, _b, _c, _d, _e, _f;
116
+ return modifyString((_f = (_e = (_d = (_c = ((_a = ctx.data.services[0].$src) !== null && _a !== void 0 ? _a : (_b = ctx.data.services[0].endpoints[0]) === null || _b === void 0 ? void 0 : _b.$src)) === null || _c === void 0 ? void 0 : _c.document.servers) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.url) !== null && _f !== void 0 ? _f : '/', ctx.config.rootUrl);
117
+ }
118
+ }
@@ -0,0 +1,3 @@
1
+ export * from './angular-service-generator';
2
+ export * from './angular-services-generator';
3
+ export * from './models';
@@ -0,0 +1,2 @@
1
+ import { defaultTypeScriptGeneratorConfig } from '../../../config';
2
+ export const defaultTypeScriptAngularServicesGeneratorConfig = Object.assign(Object.assign({}, defaultTypeScriptGeneratorConfig), { fileNameCasing: { casing: 'kebab', suffix: '.service' }, responseModelsFileNameCasing: { casing: 'kebab', suffix: '-responses.model' }, exposeResponseMethods: false, exposePathProperties: false, clientMethodFlavor: 'default', servicesDirPath: 'services', responseModelsDirPath: 'models/responses', utilsDirPath: 'utils', indexFilePath: 'services.ts', responseModelsIndexFilePath: 'responses.ts' });