swagger-typescript-api 13.0.0-experimental-1 → 13.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 (81) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +26 -12
  3. package/cli/constants.js +3 -3
  4. package/cli/execute.js +52 -31
  5. package/cli/index.d.ts +1 -2
  6. package/cli/index.js +18 -17
  7. package/cli/operations/display-help.js +51 -29
  8. package/cli/parse-args.js +3 -3
  9. package/cli/process-option.js +28 -20
  10. package/index.d.ts +113 -8
  11. package/index.js +164 -135
  12. package/package.json +36 -30
  13. package/src/code-formatter.js +28 -13
  14. package/src/code-gen-process.js +367 -259
  15. package/src/commands/generate-templates/configuration.js +2 -2
  16. package/src/commands/generate-templates/index.js +1 -2
  17. package/src/commands/generate-templates/templates-gen-process.js +62 -35
  18. package/src/component-type-name-resolver.js +44 -0
  19. package/src/configuration.js +172 -96
  20. package/src/constants.js +28 -22
  21. package/src/index.js +3 -4
  22. package/src/schema-components-map.js +43 -25
  23. package/src/schema-parser/base-schema-parsers/array.js +43 -0
  24. package/src/schema-parser/base-schema-parsers/complex.js +51 -0
  25. package/src/schema-parser/base-schema-parsers/discriminator.js +304 -0
  26. package/src/schema-parser/base-schema-parsers/enum.js +158 -0
  27. package/src/schema-parser/base-schema-parsers/object.js +105 -0
  28. package/src/schema-parser/base-schema-parsers/primitive.js +63 -0
  29. package/src/schema-parser/complex-schema-parsers/all-of.js +26 -0
  30. package/src/schema-parser/complex-schema-parsers/any-of.js +27 -0
  31. package/src/schema-parser/complex-schema-parsers/not.js +9 -0
  32. package/src/schema-parser/complex-schema-parsers/one-of.js +27 -0
  33. package/src/schema-parser/mono-schema-parser.js +48 -0
  34. package/src/schema-parser/schema-formatters.js +69 -60
  35. package/src/schema-parser/schema-parser-fabric.js +131 -0
  36. package/src/schema-parser/schema-parser.js +234 -425
  37. package/src/schema-parser/schema-utils.js +165 -67
  38. package/src/schema-parser/util/enum-key-resolver.js +26 -0
  39. package/src/schema-routes/schema-routes.js +1222 -0
  40. package/src/schema-routes/util/specific-arg-name-resolver.js +26 -0
  41. package/src/schema-walker.js +93 -0
  42. package/src/swagger-schema-resolver.js +61 -28
  43. package/src/templates-worker.js +240 -0
  44. package/src/translators/javascript.js +83 -0
  45. package/src/translators/translator.js +35 -0
  46. package/src/type-name-formatter.js +43 -22
  47. package/src/util/file-system.js +30 -14
  48. package/src/util/id.js +2 -2
  49. package/src/util/internal-case.js +1 -1
  50. package/src/util/logger.js +46 -20
  51. package/src/util/name-resolver.js +52 -60
  52. package/src/util/object-assign.js +7 -3
  53. package/src/util/pascal-case.js +1 -1
  54. package/src/util/request.js +5 -5
  55. package/src/util/sort-by-property.js +17 -0
  56. package/templates/README.md +17 -17
  57. package/templates/base/README.md +7 -7
  58. package/templates/base/data-contract-jsdoc.ejs +37 -37
  59. package/templates/base/data-contracts.ejs +40 -27
  60. package/templates/base/enum-data-contract.ejs +12 -12
  61. package/templates/base/http-client.ejs +3 -3
  62. package/templates/base/http-clients/axios-http-client.ejs +139 -138
  63. package/templates/base/http-clients/fetch-http-client.ejs +224 -224
  64. package/templates/base/interface-data-contract.ejs +10 -10
  65. package/templates/base/object-field-jsdoc.ejs +28 -28
  66. package/templates/base/route-docs.ejs +30 -30
  67. package/templates/base/route-name.ejs +42 -42
  68. package/templates/base/route-type.ejs +22 -21
  69. package/templates/base/type-data-contract.ejs +15 -15
  70. package/templates/default/README.md +6 -6
  71. package/templates/default/api.ejs +69 -68
  72. package/templates/default/procedure-call.ejs +100 -100
  73. package/templates/default/route-types.ejs +32 -32
  74. package/templates/modular/README.md +6 -6
  75. package/templates/modular/api.ejs +28 -28
  76. package/templates/modular/procedure-call.ejs +100 -100
  77. package/templates/modular/route-types.ejs +18 -18
  78. package/src/schema-parser/schema-processor.js +0 -79
  79. package/src/schema-parser/schema-routes.js +0 -950
  80. package/src/templates.js +0 -182
  81. package/src/translators/JavaScript.js +0 -60
@@ -1,57 +1,59 @@
1
- const { SwaggerSchemaResolver } = require("./swagger-schema-resolver.js");
2
- const { SchemaComponentsMap } = require("./schema-components-map.js");
3
- const { NameResolver } = require("./util/name-resolver");
4
- const { Logger } = require("./util/logger.js");
5
- const { TypeNameFormatter } = require("./type-name-formatter.js");
6
- const _ = require("lodash");
7
- const { SchemaProcessor } = require("./schema-parser/schema-processor.js");
8
- const { SchemaRoutes } = require("./schema-parser/schema-routes.js");
9
- const { CodeGenConfig } = require("./configuration.js");
10
- const { FileSystem } = require("./util/file-system");
11
- const { Templates } = require("./templates");
12
- const { translate: translateToJS } = require("./translators/JavaScript");
13
- const ts = require("typescript");
14
- const { CodeFormatter } = require("./code-formatter");
15
- const { pascalCase } = require("./util/pascal-case");
16
- const { internalCase } = require("./util/internal-case");
1
+ const { SwaggerSchemaResolver } = require('./swagger-schema-resolver.js');
2
+ const { SchemaComponentsMap } = require('./schema-components-map.js');
3
+ const { NameResolver } = require('./util/name-resolver');
4
+ const { Logger } = require('./util/logger.js');
5
+ const { TypeNameFormatter } = require('./type-name-formatter.js');
6
+ const _ = require('lodash');
7
+ const { SchemaParserFabric } = require('./schema-parser/schema-parser-fabric');
8
+ const { SchemaRoutes } = require('./schema-routes/schema-routes.js');
9
+ const { CodeGenConfig } = require('./configuration.js');
10
+ const { SchemaWalker } = require('./schema-walker');
11
+ const { FileSystem } = require('./util/file-system');
12
+ const { TemplatesWorker } = require('./templates-worker');
13
+ const { JavascriptTranslator } = require('./translators/javascript');
14
+ const ts = require('typescript');
15
+ const { CodeFormatter } = require('./code-formatter');
16
+ const { pascalCase } = require('./util/pascal-case');
17
+ const { internalCase } = require('./util/internal-case');
18
+ const { sortByProperty } = require('./util/sort-by-property');
19
+
20
+ const PATCHABLE_INSTANCES = [
21
+ 'schemaWalker',
22
+ 'swaggerSchemaResolver',
23
+ 'schemaComponentsMap',
24
+ 'typeNameFormatter',
25
+ 'templatesWorker',
26
+ 'codeFormatter',
27
+ 'schemaParserFabric',
28
+ 'schemaRoutes',
29
+ 'javascriptTranslator',
30
+ ];
17
31
 
18
32
  class CodeGenProcess {
19
- /**
20
- * @type {CodeGenConfig}
21
- */
33
+ /** @type {CodeGenConfig} */
22
34
  config;
23
- /**
24
- * @type {SwaggerSchemaResolver}
25
- */
35
+ /** @type {SwaggerSchemaResolver} */
26
36
  swaggerSchemaResolver;
27
- /**
28
- * @type {SchemaComponentsMap}
29
- */
30
- schemaComponentMap;
31
- /**
32
- * @type {Logger}
33
- */
37
+ /** @type {SchemaComponentsMap} */
38
+ schemaComponentsMap;
39
+ /** @type {Logger} */
34
40
  logger;
35
- /**
36
- * @type {TypeNameFormatter}
37
- */
38
- typeName;
39
- /**
40
- * @type {SchemaProcessor}
41
- */
42
- schemaParser;
43
- /**
44
- * @type {SchemaRoutes}
45
- */
41
+ /** @type {TypeNameFormatter} */
42
+ typeNameFormatter;
43
+ /** @type {SchemaParserFabric} */
44
+ schemaParserFabric;
45
+ /** @type {SchemaRoutes} */
46
46
  schemaRoutes;
47
- /**
48
- * @type {FileSystem}
49
- */
47
+ /** @type {FileSystem} */
50
48
  fileSystem;
51
- /**
52
- * @type {CodeFormatter}
53
- */
49
+ /** @type {CodeFormatter} */
54
50
  codeFormatter;
51
+ /** type {TemplatesWorker} */
52
+ templatesWorker;
53
+ /** @type {SchemaWalker} */
54
+ schemaWalker;
55
+ /** @type {JavascriptTranslator} */
56
+ javascriptTranslator;
55
57
 
56
58
  /**
57
59
  *
@@ -59,35 +61,27 @@ class CodeGenProcess {
59
61
  */
60
62
  constructor(config) {
61
63
  this.config = new CodeGenConfig(config);
62
- this.logger = new Logger(this.config);
63
- this.fileSystem = new FileSystem();
64
- this.swaggerSchemaResolver = new SwaggerSchemaResolver(this.config, this.logger, this.fileSystem);
65
- this.schemaComponentMap = new SchemaComponentsMap(this.config);
66
- this.typeName = new TypeNameFormatter(this.config, this.logger);
67
- this.templates = new Templates(this.config, this.logger, this.fileSystem, this.getRenderTemplateData);
68
- this.codeFormatter = new CodeFormatter(this.config);
69
- this.schemaParser = new SchemaProcessor(
70
- this.config,
71
- this.logger,
72
- this.templates,
73
- this.schemaComponentMap,
74
- this.typeName,
75
- );
76
- this.schemaRoutes = new SchemaRoutes(
77
- this.config,
78
- this.schemaParser,
79
- this.schemaComponentMap,
80
- this.logger,
81
- this.templates,
82
- this.typeName,
83
- );
64
+ this.logger = new Logger(this);
65
+ this.fileSystem = new FileSystem(this);
66
+ this.schemaWalker = new SchemaWalker(this);
67
+ this.swaggerSchemaResolver = new SwaggerSchemaResolver(this);
68
+ this.schemaComponentsMap = new SchemaComponentsMap(this);
69
+ this.typeNameFormatter = new TypeNameFormatter(this);
70
+ this.templatesWorker = new TemplatesWorker(this);
71
+ this.codeFormatter = new CodeFormatter(this);
72
+ this.schemaParserFabric = new SchemaParserFabric(this);
73
+ this.schemaRoutes = new SchemaRoutes(this);
74
+ this.javascriptTranslator = new JavascriptTranslator(this);
84
75
  this.config.componentTypeNameResolver.logger = this.logger;
85
76
  }
86
77
 
87
78
  async start() {
88
- await this.schemaRoutes.init();
89
- this.config.update({ templatePaths: this.templates.getTemplatePaths(this.config) });
90
- this.config.update({ templatesToRender: this.templates.getTemplates(this.config) });
79
+ this.config.update({
80
+ templatePaths: this.templatesWorker.getTemplatePaths(this.config),
81
+ });
82
+ this.config.update({
83
+ templatesToRender: this.templatesWorker.getTemplates(this.config),
84
+ });
91
85
 
92
86
  const swagger = await this.swaggerSchemaResolver.create();
93
87
 
@@ -98,70 +92,55 @@ class CodeGenProcess {
98
92
  originalSchema: swagger.originalSchema,
99
93
  });
100
94
 
101
- this.logger.event("start generating your typescript api");
95
+ this.schemaWalker.addSchema('$usage', swagger.usageSchema);
96
+ this.schemaWalker.addSchema('$original', swagger.originalSchema);
102
97
 
103
- this.config.update(this.config.hooks.onInit(this.config) || this.config);
98
+ this.logger.event('start generating your typescript api');
104
99
 
105
- this.schemaComponentMap.processSchema(swagger.usageSchema);
106
-
107
- const componentSchemaNames = this.schemaComponentMap.filter("schemas").map((c) => c.typeName);
100
+ this.config.update(
101
+ this.config.hooks.onInit(this.config, this) || this.config,
102
+ );
108
103
 
109
- this.config.componentTypeNameResolver.reserve(componentSchemaNames);
104
+ this.schemaComponentsMap.clear();
105
+
106
+ _.each(swagger.usageSchema.components, (component, componentName) =>
107
+ _.each(component, (rawTypeData, typeName) => {
108
+ this.schemaComponentsMap.createComponent(
109
+ this.schemaComponentsMap.createRef([
110
+ 'components',
111
+ componentName,
112
+ typeName,
113
+ ]),
114
+ rawTypeData,
115
+ );
116
+ }),
117
+ );
110
118
 
111
- const parsedSchemas = await Promise.all(
112
- _.map(_.get(swagger.usageSchema.components, "schemas"), (schema, typeName) =>
113
- this.schemaParser.parseSchema(schema, typeName),
114
- ),
119
+ /**
120
+ * @type {SchemaComponent[]}
121
+ */
122
+ const componentsToParse = this.schemaComponentsMap.filter(
123
+ _.compact(['schemas', this.config.extractResponses && 'responses']),
115
124
  );
116
125
 
117
- await this.schemaRoutes.attachSchema({
126
+ const parsedSchemas = componentsToParse.map((schemaComponent) => {
127
+ const parsed = this.schemaParserFabric.parseSchema(
128
+ schemaComponent.rawTypeData,
129
+ schemaComponent.typeName,
130
+ );
131
+ schemaComponent.typeData = parsed;
132
+ return parsed;
133
+ });
134
+
135
+ this.schemaRoutes.attachSchema({
118
136
  usageSchema: swagger.usageSchema,
119
137
  parsedSchemas,
120
138
  });
121
139
 
122
- const usageComponentSchemas = this.schemaComponentMap.filter("schemas");
123
- const sortByProperty = (propertyName) => (o1, o2) => {
124
- if (o1[propertyName] > o2[propertyName]) {
125
- return 1;
126
- }
127
- if (o1[propertyName] < o2[propertyName]) {
128
- return -1;
129
- }
130
- return 0;
131
- };
132
-
133
- const sortSchemas = (schemas) => {
134
- if (this.config.sortTypes) {
135
- return schemas.sort(sortByProperty("typeName")).map((schema) => {
136
- if (schema.rawTypeData?.properties) {
137
- return {
138
- ...schema,
139
- rawTypeData: {
140
- ...schema.rawTypeData,
141
- $parsed: schema.rawTypeData["$parsed"] && {
142
- ...schema.rawTypeData["$parsed"],
143
- content: Array.isArray(schema.rawTypeData["$parsed"].content)
144
- ? schema.rawTypeData["$parsed"].content.sort(sortByProperty("name"))
145
- : schema.rawTypeData["$parsed"].content,
146
- },
147
- },
148
- };
149
- }
150
- return schema;
151
- });
152
- }
153
- return schemas;
154
- };
155
-
156
- const modelTypes = (await Promise.all(_.map(sortSchemas(usageComponentSchemas), this.prepareModelType))).filter(
157
- Boolean,
158
- );
159
-
160
140
  const rawConfiguration = {
161
141
  apiConfig: this.createApiConfig(swagger.usageSchema),
162
142
  config: this.config,
163
- modelTypes: modelTypes,
164
- rawModelTypes: usageComponentSchemas,
143
+ modelTypes: this.collectModelTypes(),
165
144
  hasSecurityRoutes: this.schemaRoutes.hasSecurityRoutes,
166
145
  hasQueryRoutes: this.schemaRoutes.hasQueryRoutes,
167
146
  hasFormDataRoutes: this.schemaRoutes.hasFormDataRoutes,
@@ -170,10 +149,14 @@ class CodeGenProcess {
170
149
  extraTemplates: this.config.extraTemplates,
171
150
  fileName: this.config.fileName,
172
151
  translateToJavaScript: this.config.toJS,
152
+ customTranslator: this.config.customTranslator
153
+ ? new this.config.customTranslator(this)
154
+ : null,
173
155
  utils: this.getRenderTemplateData().utils,
174
156
  };
175
157
 
176
- const configuration = this.config.hooks.onPrepareConfig(rawConfiguration) || rawConfiguration;
158
+ const configuration =
159
+ this.config.hooks.onPrepareConfig(rawConfiguration) || rawConfiguration;
177
160
 
178
161
  if (this.fileSystem.pathIsExist(this.config.output)) {
179
162
  if (this.config.cleanOutput) {
@@ -181,7 +164,9 @@ class CodeGenProcess {
181
164
  this.fileSystem.cleanDir(this.config.output);
182
165
  }
183
166
  } else {
184
- this.logger.debug(`path ${this.config.output} is not exist. creating dir by this path`);
167
+ this.logger.debug(
168
+ `path ${this.config.output} is not exist. creating dir by this path`,
169
+ );
185
170
  this.fileSystem.createDir(this.config.output);
186
171
  }
187
172
 
@@ -191,41 +176,28 @@ class CodeGenProcess {
191
176
 
192
177
  const isDirPath = this.fileSystem.pathIsDir(this.config.output);
193
178
 
194
- const generatedFiles = files.map((file) => {
195
- if (!isDirPath) return file;
196
-
197
- if (this.config.toJS) {
179
+ if (isDirPath) {
180
+ files.forEach((file) => {
198
181
  this.fileSystem.createFile({
199
182
  path: this.config.output,
200
- fileName: file.name,
201
- content: file.content,
183
+ fileName: `${file.fileName}${file.fileExtension}`,
184
+ content: file.fileContent,
202
185
  withPrefix: true,
203
186
  });
204
- this.fileSystem.createFile({
205
- path: this.config.output,
206
- fileName: file.declaration.name,
207
- content: file.declaration.content,
208
- withPrefix: true,
209
- });
210
- this.logger.success(`javascript api file`, file.name, `created in ${this.config.output}`);
211
- } else {
212
- this.fileSystem.createFile({
213
- path: this.config.output,
214
- fileName: file.name,
215
- content: file.content,
216
- withPrefix: true,
217
- });
218
- this.logger.success(`typescript api file`, file.name, `created in ${this.config.output}`);
219
- }
220
187
 
221
- return file;
222
- });
188
+ this.logger.success(
189
+ `api file`,
190
+ `"${file.fileName}${file.fileExtension}"`,
191
+ `created in ${this.config.output}`,
192
+ );
193
+ });
194
+ }
223
195
 
224
196
  return {
225
- files: generatedFiles,
197
+ files,
226
198
  configuration,
227
- getTemplate: this.templates.getTemplate,
228
- renderTemplate: await this.templates.renderTemplate,
199
+ getTemplate: this.templatesWorker.getTemplate,
200
+ renderTemplate: this.templatesWorker.renderTemplate,
229
201
  createFile: this.fileSystem.createFile,
230
202
  formatTSContent: this.codeFormatter.formatCode,
231
203
  };
@@ -235,57 +207,114 @@ class CodeGenProcess {
235
207
  return {
236
208
  utils: {
237
209
  Ts: this.config.Ts,
238
- formatDescription: this.schemaParser.schemaFormatters.formatDescription,
210
+ formatDescription:
211
+ this.schemaParserFabric.schemaFormatters.formatDescription,
239
212
  internalCase: internalCase,
240
213
  classNameCase: pascalCase,
241
214
  pascalCase: pascalCase,
242
- getInlineParseContent: this.schemaParser.getInlineParseContent,
243
- getParseContent: this.schemaParser.getParseContent,
244
- getComponentByRef: this.schemaComponentMap.get,
245
- parseSchema: this.schemaParser.parseSchema,
246
- checkAndAddNull: this.schemaParser.schemaUtils.safeAddNullToType,
247
- safeAddNullToType: this.schemaParser.schemaUtils.safeAddNullToType,
248
- isNeedToAddNull: this.schemaParser.schemaUtils.isNullMissingInType,
249
- inlineExtraFormatters: this.schemaParser.schemaFormatters.inline,
250
- formatters: this.schemaParser.schemaFormatters.base,
251
- formatModelName: this.typeName.format,
215
+ getInlineParseContent: this.schemaParserFabric.getInlineParseContent,
216
+ getParseContent: this.schemaParserFabric.getParseContent,
217
+ getComponentByRef: this.schemaComponentsMap.get,
218
+ parseSchema: this.schemaParserFabric.parseSchema,
219
+ checkAndAddNull: this.schemaParserFabric.schemaUtils.safeAddNullToType,
220
+ safeAddNullToType:
221
+ this.schemaParserFabric.schemaUtils.safeAddNullToType,
222
+ isNeedToAddNull:
223
+ this.schemaParserFabric.schemaUtils.isNullMissingInType,
224
+ inlineExtraFormatters: this.schemaParserFabric.schemaFormatters.inline,
225
+ formatters: this.schemaParserFabric.schemaFormatters.base,
226
+ formatModelName: this.typeNameFormatter.format,
252
227
  fmtToJSDocLine: function fmtToJSDocLine(line, { eol = true }) {
253
- return ` * ${line}${eol ? "\n" : ""}`;
228
+ return ` * ${line}${eol ? '\n' : ''}`;
254
229
  },
255
230
  NameResolver: NameResolver,
256
231
  _,
257
- require: this.templates.requireFnFromTemplate,
232
+ require: this.templatesWorker.requireFnFromTemplate,
258
233
  },
259
234
  config: this.config,
260
235
  };
261
236
  };
262
237
 
263
- prepareModelType = async (typeInfo) => {
264
- if (!typeInfo.typeData) {
265
- typeInfo.typeData = await this.schemaParser.parseSchema(typeInfo.rawTypeData, typeInfo.typeName);
238
+ collectModelTypes = () => {
239
+ const components = this.schemaComponentsMap.getComponents();
240
+ let modelTypes = [];
241
+
242
+ const modelTypeComponents = _.compact([
243
+ 'schemas',
244
+ this.config.extractResponses && 'responses',
245
+ ]);
246
+
247
+ const getSchemaComponentsCount = () =>
248
+ this.schemaComponentsMap.filter(...modelTypeComponents).length;
249
+
250
+ let schemaComponentsCount = getSchemaComponentsCount();
251
+ let processedCount = 0;
252
+
253
+ while (processedCount < schemaComponentsCount) {
254
+ modelTypes = [];
255
+ processedCount = 0;
256
+ for (const component of components) {
257
+ if (modelTypeComponents.includes(component.componentName)) {
258
+ const modelType = this.prepareModelType(component);
259
+ if (modelType) {
260
+ modelTypes.push(modelType);
261
+ }
262
+ processedCount++;
263
+ }
264
+ }
265
+ schemaComponentsCount = getSchemaComponentsCount();
266
266
  }
267
- const typeData = await this.schemaParser.schemaFormatters.formatSchema(typeInfo.typeData, {
268
- formatType: "base",
269
- schemaType: typeInfo.typeData.type,
270
- });
271
267
 
268
+ if (this.config.sortTypes) {
269
+ return modelTypes.sort(sortByProperty('name'));
270
+ }
271
+
272
+ return modelTypes;
273
+ };
274
+
275
+ prepareModelType = (typeInfo) => {
276
+ if (typeInfo.$prepared) return typeInfo.$prepared;
277
+
278
+ if (!typeInfo.typeData) {
279
+ typeInfo.typeData = this.schemaParserFabric.parseSchema(
280
+ typeInfo.rawTypeData,
281
+ typeInfo.typeName,
282
+ );
283
+ }
284
+ const rawTypeData = typeInfo.typeData;
285
+ const typeData = this.schemaParserFabric.schemaFormatters.base[
286
+ rawTypeData.type
287
+ ]
288
+ ? this.schemaParserFabric.schemaFormatters.base[rawTypeData.type](
289
+ rawTypeData,
290
+ )
291
+ : rawTypeData;
272
292
  let { typeIdentifier, name: originalName, content, description } = typeData;
273
- const name = this.typeName.format(originalName);
293
+ const name = this.typeNameFormatter.format(originalName);
274
294
 
275
295
  if (name === null) return null;
276
296
 
277
- return {
297
+ const preparedModelType = {
278
298
  ...typeData,
279
299
  typeIdentifier,
280
300
  name,
281
301
  description,
282
- $content: typeInfo.typeData.content,
283
- rawContent: typeInfo.typeData.content,
302
+ $content: rawTypeData.content,
303
+ rawContent: rawTypeData.content,
284
304
  content: content,
285
305
  typeData,
286
306
  };
307
+
308
+ typeInfo.$prepared = preparedModelType;
309
+
310
+ return preparedModelType;
287
311
  };
288
312
 
313
+ /**
314
+ *
315
+ * @param configuration
316
+ * @returns {Promise<TranslatorIO[]>}
317
+ */
289
318
  generateOutputFiles = async ({ configuration }) => {
290
319
  const { modular, templatesToRender } = this.config;
291
320
 
@@ -294,148 +323,218 @@ class CodeGenProcess {
294
323
  : await this.createSingleFileInfo(templatesToRender, configuration);
295
324
 
296
325
  if (!_.isEmpty(configuration.extraTemplates)) {
297
- output.push(
298
- ...(await Promise.all(
299
- _.map(configuration.extraTemplates, async (extraTemplate) => {
300
- return this.createOutputFileInfo(
301
- configuration,
302
- extraTemplate.name,
303
- await await this.templates.renderTemplate(
304
- this.fileSystem.getFileContent(extraTemplate.path),
305
- configuration,
306
- ),
307
- );
308
- }),
309
- )),
310
- );
326
+ for (const extraTemplate of configuration.extraTemplates) {
327
+ const content = this.templatesWorker.renderTemplate(
328
+ this.fileSystem.getFileContent(extraTemplate.path),
329
+ configuration,
330
+ );
331
+ output.push(
332
+ ...(await this.createOutputFileInfo(
333
+ configuration,
334
+ extraTemplate.name,
335
+ content,
336
+ )),
337
+ );
338
+ }
311
339
  }
312
340
 
313
- return output.filter((fileInfo) => !!fileInfo && !!fileInfo.content);
341
+ return output.filter((fileInfo) => !!fileInfo && !!fileInfo.fileContent);
314
342
  };
315
343
 
344
+ /**
345
+ * @param templatesToRender
346
+ * @param configuration
347
+ * @returns {Promise<TranslatorIO[]>}
348
+ */
316
349
  createMultipleFileInfos = async (templatesToRender, configuration) => {
317
350
  const { routes } = configuration;
318
- const { fileNames, generateRouteTypes, generateClient } = configuration.config;
351
+ const { fileNames, generateRouteTypes, generateClient } =
352
+ configuration.config;
353
+ /**
354
+ * @type {TranslatorIO[]}
355
+ */
319
356
  const modularApiFileInfos = [];
320
357
 
321
358
  if (routes.$outOfModule) {
322
359
  if (generateRouteTypes) {
323
- const outOfModuleRouteContent = await this.templates.renderTemplate(templatesToRender.routeTypes, {
324
- ...configuration,
325
- route: configuration.routes.$outOfModule,
326
- });
360
+ const outOfModuleRouteContent = this.templatesWorker.renderTemplate(
361
+ templatesToRender.routeTypes,
362
+ {
363
+ ...configuration,
364
+ route: configuration.routes.$outOfModule,
365
+ },
366
+ );
327
367
 
328
368
  modularApiFileInfos.push(
329
- this.createOutputFileInfo(configuration, fileNames.outOfModuleApi, outOfModuleRouteContent),
369
+ ...(await this.createOutputFileInfo(
370
+ configuration,
371
+ fileNames.outOfModuleApi,
372
+ outOfModuleRouteContent,
373
+ )),
330
374
  );
331
375
  }
332
376
  if (generateClient) {
333
- const outOfModuleApiContent = await this.templates.renderTemplate(templatesToRender.api, {
334
- ...configuration,
335
- route: configuration.routes.$outOfModule,
336
- });
377
+ const outOfModuleApiContent = this.templatesWorker.renderTemplate(
378
+ templatesToRender.api,
379
+ {
380
+ ...configuration,
381
+ route: configuration.routes.$outOfModule,
382
+ },
383
+ );
337
384
 
338
385
  modularApiFileInfos.push(
339
- this.createOutputFileInfo(configuration, fileNames.outOfModuleApi, outOfModuleApiContent),
386
+ ...(await this.createOutputFileInfo(
387
+ configuration,
388
+ fileNames.outOfModuleApi,
389
+ outOfModuleApiContent,
390
+ )),
340
391
  );
341
392
  }
342
393
  }
343
394
 
344
395
  if (routes.combined) {
345
- for await (const route of routes.combined) {
396
+ for (const route of routes.combined) {
346
397
  if (generateRouteTypes) {
347
- const routeModuleContent = await this.templates.renderTemplate(templatesToRender.routeTypes, {
348
- ...configuration,
349
- route,
350
- });
398
+ const routeModuleContent = this.templatesWorker.renderTemplate(
399
+ templatesToRender.routeTypes,
400
+ {
401
+ ...configuration,
402
+ route,
403
+ },
404
+ );
351
405
 
352
406
  modularApiFileInfos.push(
353
- this.createOutputFileInfo(configuration, pascalCase(`${route.moduleName}_Route`), routeModuleContent),
407
+ ...(await this.createOutputFileInfo(
408
+ configuration,
409
+ pascalCase(`${route.moduleName}_Route`),
410
+ routeModuleContent,
411
+ )),
354
412
  );
355
413
  }
356
414
 
357
415
  if (generateClient) {
358
- const apiModuleContent = await this.templates.renderTemplate(templatesToRender.api, {
359
- ...configuration,
360
- route,
361
- });
416
+ const apiModuleContent = this.templatesWorker.renderTemplate(
417
+ templatesToRender.api,
418
+ {
419
+ ...configuration,
420
+ route,
421
+ },
422
+ );
362
423
 
363
424
  modularApiFileInfos.push(
364
- this.createOutputFileInfo(configuration, pascalCase(route.moduleName), apiModuleContent),
425
+ ...(await this.createOutputFileInfo(
426
+ configuration,
427
+ pascalCase(route.moduleName),
428
+ apiModuleContent,
429
+ )),
365
430
  );
366
431
  }
367
432
  }
368
433
  }
369
434
 
370
435
  return [
371
- this.createOutputFileInfo(
436
+ ...(await this.createOutputFileInfo(
372
437
  configuration,
373
438
  fileNames.dataContracts,
374
- await this.templates.renderTemplate(templatesToRender.dataContracts, configuration),
375
- ),
376
- generateClient &&
377
- this.createOutputFileInfo(
439
+ this.templatesWorker.renderTemplate(
440
+ templatesToRender.dataContracts,
378
441
  configuration,
379
- fileNames.httpClient,
380
- await this.templates.renderTemplate(templatesToRender.httpClient, configuration),
381
442
  ),
443
+ )),
444
+ ...(generateClient
445
+ ? await this.createOutputFileInfo(
446
+ configuration,
447
+ fileNames.httpClient,
448
+ this.templatesWorker.renderTemplate(
449
+ templatesToRender.httpClient,
450
+ configuration,
451
+ ),
452
+ )
453
+ : []),
382
454
  ...modularApiFileInfos,
383
455
  ];
384
456
  };
385
457
 
458
+ /**
459
+ *
460
+ * @param templatesToRender
461
+ * @param configuration
462
+ * @returns {Promise<TranslatorIO[]>}
463
+ */
386
464
  createSingleFileInfo = async (templatesToRender, configuration) => {
387
465
  const { generateRouteTypes, generateClient } = configuration.config;
388
466
 
389
- return [
390
- this.createOutputFileInfo(
391
- configuration,
392
- configuration.fileName,
393
- _.compact([
394
- await this.templates.renderTemplate(templatesToRender.dataContracts, configuration),
395
- generateRouteTypes && (await this.templates.renderTemplate(templatesToRender.routeTypes, configuration)),
396
- generateClient && (await this.templates.renderTemplate(templatesToRender.httpClient, configuration)),
397
- generateClient && (await this.templates.renderTemplate(templatesToRender.api, configuration)),
398
- ]).join("\n"),
399
- ),
400
- ];
467
+ return await this.createOutputFileInfo(
468
+ configuration,
469
+ configuration.fileName,
470
+ _.compact([
471
+ this.templatesWorker.renderTemplate(
472
+ templatesToRender.dataContracts,
473
+ configuration,
474
+ ),
475
+ generateRouteTypes &&
476
+ this.templatesWorker.renderTemplate(
477
+ templatesToRender.routeTypes,
478
+ configuration,
479
+ ),
480
+ generateClient &&
481
+ this.templatesWorker.renderTemplate(
482
+ templatesToRender.httpClient,
483
+ configuration,
484
+ ),
485
+ generateClient &&
486
+ this.templatesWorker.renderTemplate(
487
+ templatesToRender.api,
488
+ configuration,
489
+ ),
490
+ ]).join('\n'),
491
+ );
401
492
  };
402
493
 
403
- createOutputFileInfo = (configuration, fileName, content) => {
404
- const fixedFileName = this.fileSystem.cropExtension(fileName);
494
+ /**
495
+ *
496
+ * @param configuration
497
+ * @param fileNameFull
498
+ * @param content
499
+ * @returns {Promise<TranslatorIO[]>}
500
+ */
501
+ createOutputFileInfo = async (configuration, fileNameFull, content) => {
502
+ const fileName = this.fileSystem.cropExtension(fileNameFull);
503
+ const fileExtension = ts.Extension.Ts;
405
504
 
406
505
  if (configuration.translateToJavaScript) {
407
- const { sourceContent, declarationContent } = translateToJS(`${fixedFileName}${ts.Extension.Ts}`, content);
408
-
409
- this.logger.debug("generating output for", `${fixedFileName}${ts.Extension.Js}`);
410
- this.logger.debug(sourceContent);
411
-
412
- this.logger.debug("generating output for", `${fixedFileName}${ts.Extension.Js}`);
413
- this.logger.debug(declarationContent);
506
+ this.logger.debug('using js translator for', fileName);
507
+ return await this.javascriptTranslator.translate({
508
+ fileName: fileName,
509
+ fileExtension: fileExtension,
510
+ fileContent: content,
511
+ });
512
+ }
414
513
 
415
- return {
416
- name: `${fixedFileName}${ts.Extension.Js}`,
417
- content: this.codeFormatter.formatCode(sourceContent),
418
- declaration: {
419
- name: `${fixedFileName}${ts.Extension.Dts}`,
420
- content: this.codeFormatter.formatCode(declarationContent),
421
- },
422
- };
514
+ if (configuration.customTranslator) {
515
+ this.logger.debug('using custom translator for', fileName);
516
+ return await configuration.customTranslator.translate({
517
+ fileName: fileName,
518
+ fileExtension: fileExtension,
519
+ fileContent: content,
520
+ });
423
521
  }
424
522
 
425
- this.logger.debug("generating output for", `${fixedFileName}${ts.Extension.Js}`);
426
- this.logger.debug(content);
523
+ this.logger.debug('generating output for', `${fileName}${fileExtension}`);
427
524
 
428
- return {
429
- name: `${fixedFileName}${ts.Extension.Ts}`,
430
- content: this.codeFormatter.formatCode(content),
431
- declaration: null,
432
- };
525
+ return [
526
+ {
527
+ fileName,
528
+ fileExtension: fileExtension,
529
+ fileContent: await this.codeFormatter.formatCode(content),
530
+ },
531
+ ];
433
532
  };
434
533
 
435
534
  createApiConfig = (swaggerSchema) => {
436
535
  const { info, servers, host, basePath, externalDocs, tags } = swaggerSchema;
437
- const server = (servers && servers[0]) || { url: "" };
438
- const { title = "No title", version, description: schemaDescription = "" } = info || {};
536
+ const server = (servers && servers[0]) || { url: '' };
537
+ const { title = 'No title', version } = info || {};
439
538
  const { url: serverUrl } = server;
440
539
 
441
540
  return {
@@ -445,8 +544,8 @@ class CodeGenProcess {
445
544
  host,
446
545
  externalDocs: _.merge(
447
546
  {
448
- url: "",
449
- description: "",
547
+ url: '',
548
+ description: '',
450
549
  },
451
550
  externalDocs,
452
551
  ),
@@ -456,6 +555,15 @@ class CodeGenProcess {
456
555
  version,
457
556
  };
458
557
  };
558
+
559
+ injectClassInstance = (key, value) => {
560
+ this[key] = value;
561
+ PATCHABLE_INSTANCES.forEach((instanceKey) => {
562
+ if (instanceKey !== key && key in this[instanceKey]) {
563
+ this[instanceKey][key] = value;
564
+ }
565
+ });
566
+ };
459
567
  }
460
568
 
461
569
  module.exports = {