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.
- package/LICENSE +21 -21
- package/README.md +26 -12
- package/cli/constants.js +3 -3
- package/cli/execute.js +52 -31
- package/cli/index.d.ts +1 -2
- package/cli/index.js +18 -17
- package/cli/operations/display-help.js +51 -29
- package/cli/parse-args.js +3 -3
- package/cli/process-option.js +28 -20
- package/index.d.ts +113 -8
- package/index.js +164 -135
- package/package.json +36 -30
- package/src/code-formatter.js +28 -13
- package/src/code-gen-process.js +367 -259
- package/src/commands/generate-templates/configuration.js +2 -2
- package/src/commands/generate-templates/index.js +1 -2
- package/src/commands/generate-templates/templates-gen-process.js +62 -35
- package/src/component-type-name-resolver.js +44 -0
- package/src/configuration.js +172 -96
- package/src/constants.js +28 -22
- package/src/index.js +3 -4
- package/src/schema-components-map.js +43 -25
- package/src/schema-parser/base-schema-parsers/array.js +43 -0
- package/src/schema-parser/base-schema-parsers/complex.js +51 -0
- package/src/schema-parser/base-schema-parsers/discriminator.js +304 -0
- package/src/schema-parser/base-schema-parsers/enum.js +158 -0
- package/src/schema-parser/base-schema-parsers/object.js +105 -0
- package/src/schema-parser/base-schema-parsers/primitive.js +63 -0
- package/src/schema-parser/complex-schema-parsers/all-of.js +26 -0
- package/src/schema-parser/complex-schema-parsers/any-of.js +27 -0
- package/src/schema-parser/complex-schema-parsers/not.js +9 -0
- package/src/schema-parser/complex-schema-parsers/one-of.js +27 -0
- package/src/schema-parser/mono-schema-parser.js +48 -0
- package/src/schema-parser/schema-formatters.js +69 -60
- package/src/schema-parser/schema-parser-fabric.js +131 -0
- package/src/schema-parser/schema-parser.js +234 -425
- package/src/schema-parser/schema-utils.js +165 -67
- package/src/schema-parser/util/enum-key-resolver.js +26 -0
- package/src/schema-routes/schema-routes.js +1222 -0
- package/src/schema-routes/util/specific-arg-name-resolver.js +26 -0
- package/src/schema-walker.js +93 -0
- package/src/swagger-schema-resolver.js +61 -28
- package/src/templates-worker.js +240 -0
- package/src/translators/javascript.js +83 -0
- package/src/translators/translator.js +35 -0
- package/src/type-name-formatter.js +43 -22
- package/src/util/file-system.js +30 -14
- package/src/util/id.js +2 -2
- package/src/util/internal-case.js +1 -1
- package/src/util/logger.js +46 -20
- package/src/util/name-resolver.js +52 -60
- package/src/util/object-assign.js +7 -3
- package/src/util/pascal-case.js +1 -1
- package/src/util/request.js +5 -5
- package/src/util/sort-by-property.js +17 -0
- package/templates/README.md +17 -17
- package/templates/base/README.md +7 -7
- package/templates/base/data-contract-jsdoc.ejs +37 -37
- package/templates/base/data-contracts.ejs +40 -27
- package/templates/base/enum-data-contract.ejs +12 -12
- package/templates/base/http-client.ejs +3 -3
- package/templates/base/http-clients/axios-http-client.ejs +139 -138
- package/templates/base/http-clients/fetch-http-client.ejs +224 -224
- package/templates/base/interface-data-contract.ejs +10 -10
- package/templates/base/object-field-jsdoc.ejs +28 -28
- package/templates/base/route-docs.ejs +30 -30
- package/templates/base/route-name.ejs +42 -42
- package/templates/base/route-type.ejs +22 -21
- package/templates/base/type-data-contract.ejs +15 -15
- package/templates/default/README.md +6 -6
- package/templates/default/api.ejs +69 -68
- package/templates/default/procedure-call.ejs +100 -100
- package/templates/default/route-types.ejs +32 -32
- package/templates/modular/README.md +6 -6
- package/templates/modular/api.ejs +28 -28
- package/templates/modular/procedure-call.ejs +100 -100
- package/templates/modular/route-types.ejs +18 -18
- package/src/schema-parser/schema-processor.js +0 -79
- package/src/schema-parser/schema-routes.js +0 -950
- package/src/templates.js +0 -182
- package/src/translators/JavaScript.js +0 -60
package/src/code-gen-process.js
CHANGED
|
@@ -1,57 +1,59 @@
|
|
|
1
|
-
const { SwaggerSchemaResolver } = require(
|
|
2
|
-
const { SchemaComponentsMap } = require(
|
|
3
|
-
const { NameResolver } = require(
|
|
4
|
-
const { Logger } = require(
|
|
5
|
-
const { TypeNameFormatter } = require(
|
|
6
|
-
const _ = require(
|
|
7
|
-
const {
|
|
8
|
-
const { SchemaRoutes } = require(
|
|
9
|
-
const { CodeGenConfig } = require(
|
|
10
|
-
const {
|
|
11
|
-
const {
|
|
12
|
-
const {
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const {
|
|
16
|
-
const {
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
schemaComponentMap;
|
|
31
|
-
/**
|
|
32
|
-
* @type {Logger}
|
|
33
|
-
*/
|
|
37
|
+
/** @type {SchemaComponentsMap} */
|
|
38
|
+
schemaComponentsMap;
|
|
39
|
+
/** @type {Logger} */
|
|
34
40
|
logger;
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
|
63
|
-
this.fileSystem = new FileSystem();
|
|
64
|
-
this.
|
|
65
|
-
this.
|
|
66
|
-
this.
|
|
67
|
-
this.
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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.
|
|
95
|
+
this.schemaWalker.addSchema('$usage', swagger.usageSchema);
|
|
96
|
+
this.schemaWalker.addSchema('$original', swagger.originalSchema);
|
|
102
97
|
|
|
103
|
-
this.
|
|
98
|
+
this.logger.event('start generating your typescript api');
|
|
104
99
|
|
|
105
|
-
this.
|
|
106
|
-
|
|
107
|
-
|
|
100
|
+
this.config.update(
|
|
101
|
+
this.config.hooks.onInit(this.config, this) || this.config,
|
|
102
|
+
);
|
|
108
103
|
|
|
109
|
-
this.
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
119
|
+
/**
|
|
120
|
+
* @type {SchemaComponent[]}
|
|
121
|
+
*/
|
|
122
|
+
const componentsToParse = this.schemaComponentsMap.filter(
|
|
123
|
+
_.compact(['schemas', this.config.extractResponses && 'responses']),
|
|
115
124
|
);
|
|
116
125
|
|
|
117
|
-
|
|
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:
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
195
|
-
|
|
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.
|
|
201
|
-
content: file.
|
|
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
|
-
|
|
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
|
|
197
|
+
files,
|
|
226
198
|
configuration,
|
|
227
|
-
getTemplate: this.
|
|
228
|
-
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:
|
|
210
|
+
formatDescription:
|
|
211
|
+
this.schemaParserFabric.schemaFormatters.formatDescription,
|
|
239
212
|
internalCase: internalCase,
|
|
240
213
|
classNameCase: pascalCase,
|
|
241
214
|
pascalCase: pascalCase,
|
|
242
|
-
getInlineParseContent: this.
|
|
243
|
-
getParseContent: this.
|
|
244
|
-
getComponentByRef: this.
|
|
245
|
-
parseSchema: this.
|
|
246
|
-
checkAndAddNull: this.
|
|
247
|
-
safeAddNullToType:
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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 ?
|
|
228
|
+
return ` * ${line}${eol ? '\n' : ''}`;
|
|
254
229
|
},
|
|
255
230
|
NameResolver: NameResolver,
|
|
256
231
|
_,
|
|
257
|
-
require: this.
|
|
232
|
+
require: this.templatesWorker.requireFnFromTemplate,
|
|
258
233
|
},
|
|
259
234
|
config: this.config,
|
|
260
235
|
};
|
|
261
236
|
};
|
|
262
237
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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.
|
|
293
|
+
const name = this.typeNameFormatter.format(originalName);
|
|
274
294
|
|
|
275
295
|
if (name === null) return null;
|
|
276
296
|
|
|
277
|
-
|
|
297
|
+
const preparedModelType = {
|
|
278
298
|
...typeData,
|
|
279
299
|
typeIdentifier,
|
|
280
300
|
name,
|
|
281
301
|
description,
|
|
282
|
-
$content:
|
|
283
|
-
rawContent:
|
|
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
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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.
|
|
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 } =
|
|
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 =
|
|
324
|
-
|
|
325
|
-
|
|
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(
|
|
369
|
+
...(await this.createOutputFileInfo(
|
|
370
|
+
configuration,
|
|
371
|
+
fileNames.outOfModuleApi,
|
|
372
|
+
outOfModuleRouteContent,
|
|
373
|
+
)),
|
|
330
374
|
);
|
|
331
375
|
}
|
|
332
376
|
if (generateClient) {
|
|
333
|
-
const outOfModuleApiContent =
|
|
334
|
-
|
|
335
|
-
|
|
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(
|
|
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
|
|
396
|
+
for (const route of routes.combined) {
|
|
346
397
|
if (generateRouteTypes) {
|
|
347
|
-
const routeModuleContent =
|
|
348
|
-
|
|
349
|
-
|
|
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(
|
|
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 =
|
|
359
|
-
|
|
360
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
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
|
-
|
|
404
|
-
|
|
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
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
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
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
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(
|
|
426
|
-
this.logger.debug(content);
|
|
523
|
+
this.logger.debug('generating output for', `${fileName}${fileExtension}`);
|
|
427
524
|
|
|
428
|
-
return
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
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 =
|
|
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 = {
|