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