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/configuration.js
CHANGED
|
@@ -1,32 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const {
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
const { objectAssign } = require('./util/object-assign');
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
const CONSTANTS = require('./constants');
|
|
5
|
+
const { ComponentTypeNameResolver } = require('./component-type-name-resolver');
|
|
6
|
+
const { cosmiconfigSync } = require('cosmiconfig');
|
|
7
|
+
const ts = require('typescript');
|
|
6
8
|
|
|
7
9
|
const TsKeyword = {
|
|
8
|
-
Number:
|
|
9
|
-
String:
|
|
10
|
-
Boolean:
|
|
11
|
-
Any:
|
|
12
|
-
Void:
|
|
13
|
-
Unknown:
|
|
14
|
-
Null:
|
|
15
|
-
Undefined:
|
|
16
|
-
Object:
|
|
17
|
-
File:
|
|
18
|
-
Date:
|
|
19
|
-
Type:
|
|
20
|
-
Enum:
|
|
21
|
-
Interface:
|
|
22
|
-
Array:
|
|
23
|
-
Record:
|
|
24
|
-
Intersection:
|
|
25
|
-
Union:
|
|
10
|
+
Number: 'number',
|
|
11
|
+
String: 'string',
|
|
12
|
+
Boolean: 'boolean',
|
|
13
|
+
Any: 'any',
|
|
14
|
+
Void: 'void',
|
|
15
|
+
Unknown: 'unknown',
|
|
16
|
+
Null: 'null',
|
|
17
|
+
Undefined: 'undefined',
|
|
18
|
+
Object: 'object',
|
|
19
|
+
File: 'File',
|
|
20
|
+
Date: 'Date',
|
|
21
|
+
Type: 'type',
|
|
22
|
+
Enum: 'enum',
|
|
23
|
+
Interface: 'interface',
|
|
24
|
+
Array: 'Array',
|
|
25
|
+
Record: 'Record',
|
|
26
|
+
Intersection: '&',
|
|
27
|
+
Union: '|',
|
|
26
28
|
};
|
|
27
29
|
|
|
28
30
|
const TsCodeGenKeyword = {
|
|
29
|
-
UtilRequiredKeys:
|
|
31
|
+
UtilRequiredKeys: 'UtilRequiredKeys',
|
|
30
32
|
};
|
|
31
33
|
|
|
32
34
|
/**
|
|
@@ -35,7 +37,7 @@ const TsCodeGenKeyword = {
|
|
|
35
37
|
class CodeGenConfig {
|
|
36
38
|
version = CONSTANTS.PROJECT_VERSION;
|
|
37
39
|
/** CLI flag */
|
|
38
|
-
templates =
|
|
40
|
+
templates = '';
|
|
39
41
|
/** CLI flag */
|
|
40
42
|
generateResponses = false;
|
|
41
43
|
/** CLI flag */
|
|
@@ -74,10 +76,10 @@ class CodeGenConfig {
|
|
|
74
76
|
extractResponseError = false;
|
|
75
77
|
extractEnums = false;
|
|
76
78
|
fileNames = {
|
|
77
|
-
dataContracts:
|
|
78
|
-
routeTypes:
|
|
79
|
-
httpClient:
|
|
80
|
-
outOfModuleApi:
|
|
79
|
+
dataContracts: 'data-contracts',
|
|
80
|
+
routeTypes: 'route-types',
|
|
81
|
+
httpClient: 'http-client',
|
|
82
|
+
outOfModuleApi: 'Common',
|
|
81
83
|
};
|
|
82
84
|
routeNameDuplicatesMap = new Map();
|
|
83
85
|
prettierOptions = { ...CONSTANTS.PRETTIER_OPTIONS };
|
|
@@ -89,7 +91,7 @@ class CodeGenConfig {
|
|
|
89
91
|
onPreParseSchema: (originalSchema, typeName, schemaType) => void 0,
|
|
90
92
|
onParseSchema: (originalSchema, parsedSchema) => parsedSchema,
|
|
91
93
|
onCreateRoute: (routeData) => routeData,
|
|
92
|
-
onInit: (config) => config,
|
|
94
|
+
onInit: (config, codeGenProcess) => config,
|
|
93
95
|
onPrepareConfig: (apiConfig) => apiConfig,
|
|
94
96
|
onCreateRequestParams: (rawType) => {},
|
|
95
97
|
onCreateRouteName: () => {},
|
|
@@ -102,72 +104,114 @@ class CodeGenConfig {
|
|
|
102
104
|
unwrapResponseData = false;
|
|
103
105
|
disableThrowOnError = false;
|
|
104
106
|
sortTypes = false;
|
|
107
|
+
sortRoutes = false;
|
|
105
108
|
templatePaths = {
|
|
106
109
|
/** `templates/base` */
|
|
107
|
-
base:
|
|
110
|
+
base: '',
|
|
108
111
|
/** `templates/default` */
|
|
109
|
-
default:
|
|
112
|
+
default: '',
|
|
110
113
|
/** `templates/modular` */
|
|
111
|
-
modular:
|
|
114
|
+
modular: '',
|
|
112
115
|
/** usage path if `--templates` option is not set */
|
|
113
|
-
original:
|
|
116
|
+
original: '',
|
|
114
117
|
/** custom path to templates (`--templates`) */
|
|
115
|
-
custom:
|
|
118
|
+
custom: '',
|
|
116
119
|
};
|
|
117
120
|
/** Record<templateName, templateContent> */
|
|
118
121
|
templatesToRender = {
|
|
119
|
-
api:
|
|
120
|
-
dataContracts:
|
|
121
|
-
dataContractJsDoc:
|
|
122
|
-
interfaceDataContract:
|
|
123
|
-
typeDataContract:
|
|
124
|
-
enumDataContract:
|
|
125
|
-
objectFieldJsDoc:
|
|
126
|
-
httpClient:
|
|
127
|
-
routeTypes:
|
|
128
|
-
routeName:
|
|
122
|
+
api: '',
|
|
123
|
+
dataContracts: '',
|
|
124
|
+
dataContractJsDoc: '',
|
|
125
|
+
interfaceDataContract: '',
|
|
126
|
+
typeDataContract: '',
|
|
127
|
+
enumDataContract: '',
|
|
128
|
+
objectFieldJsDoc: '',
|
|
129
|
+
httpClient: '',
|
|
130
|
+
routeTypes: '',
|
|
131
|
+
routeName: '',
|
|
129
132
|
};
|
|
133
|
+
/**
|
|
134
|
+
* @type {Record<string, (...args: any[]) => MonoSchemaParser>}
|
|
135
|
+
*/
|
|
136
|
+
schemaParsers = {};
|
|
130
137
|
toJS = false;
|
|
131
138
|
silent = false;
|
|
132
|
-
typePrefix =
|
|
133
|
-
typeSuffix =
|
|
134
|
-
enumKeyPrefix =
|
|
135
|
-
enumKeySuffix =
|
|
139
|
+
typePrefix = '';
|
|
140
|
+
typeSuffix = '';
|
|
141
|
+
enumKeyPrefix = '';
|
|
142
|
+
enumKeySuffix = '';
|
|
136
143
|
patch = false;
|
|
137
|
-
|
|
144
|
+
/** @type {ComponentTypeNameResolver} */
|
|
145
|
+
componentTypeNameResolver;
|
|
138
146
|
/** name of the main exported class */
|
|
139
|
-
apiClassName =
|
|
147
|
+
apiClassName = 'Api';
|
|
140
148
|
debug = false;
|
|
141
149
|
anotherArrayType = false;
|
|
142
150
|
internalTemplateOptions = {
|
|
143
151
|
addUtilRequiredKeysType: false,
|
|
144
152
|
};
|
|
145
153
|
extraTemplates = [];
|
|
146
|
-
input =
|
|
154
|
+
input = '';
|
|
147
155
|
modular = false;
|
|
148
|
-
output =
|
|
149
|
-
url =
|
|
156
|
+
output = '';
|
|
157
|
+
url = '';
|
|
150
158
|
cleanOutput = false;
|
|
151
159
|
spec = null;
|
|
152
|
-
fileName =
|
|
160
|
+
fileName = 'Api.ts';
|
|
153
161
|
authorizationToken = void 0;
|
|
154
162
|
requestOptions = null;
|
|
155
163
|
|
|
156
164
|
jsPrimitiveTypes = [];
|
|
157
165
|
jsEmptyTypes = [];
|
|
158
|
-
fixInvalidTypeNamePrefix =
|
|
159
|
-
fixInvalidEnumKeyPrefix =
|
|
166
|
+
fixInvalidTypeNamePrefix = 'Type';
|
|
167
|
+
fixInvalidEnumKeyPrefix = 'Value';
|
|
168
|
+
|
|
169
|
+
enumKeyResolverName = 'Value';
|
|
170
|
+
typeNameResolverName = 'ComponentType';
|
|
171
|
+
specificArgNameResolverName = 'arg';
|
|
160
172
|
|
|
161
173
|
successResponseStatusRange = [200, 299];
|
|
162
174
|
|
|
163
175
|
/** @type {ExtractingOptions} */
|
|
164
176
|
extractingOptions = {
|
|
165
|
-
requestBodySuffix: [
|
|
166
|
-
requestParamsSuffix: [
|
|
167
|
-
responseBodySuffix: [
|
|
168
|
-
responseErrorSuffix: [
|
|
177
|
+
requestBodySuffix: ['Payload', 'Body', 'Input'],
|
|
178
|
+
requestParamsSuffix: ['Params'],
|
|
179
|
+
responseBodySuffix: ['Data', 'Result', 'Output'],
|
|
180
|
+
responseErrorSuffix: [
|
|
181
|
+
'Error',
|
|
182
|
+
'Fail',
|
|
183
|
+
'Fails',
|
|
184
|
+
'ErrorData',
|
|
185
|
+
'HttpError',
|
|
186
|
+
'BadResponse',
|
|
187
|
+
],
|
|
188
|
+
enumSuffix: ['Enum'],
|
|
189
|
+
discriminatorMappingSuffix: ['Mapping', 'Mapper', 'MapType'],
|
|
190
|
+
discriminatorAbstractPrefix: [
|
|
191
|
+
'Base',
|
|
192
|
+
'Abstract',
|
|
193
|
+
'Discriminator',
|
|
194
|
+
'Internal',
|
|
195
|
+
'Polymorph',
|
|
196
|
+
],
|
|
169
197
|
};
|
|
170
198
|
|
|
199
|
+
compilerTsConfig = {
|
|
200
|
+
module: 'ESNext',
|
|
201
|
+
noImplicitReturns: true,
|
|
202
|
+
alwaysStrict: true,
|
|
203
|
+
target: ts.ScriptTarget.ESNext,
|
|
204
|
+
declaration: true,
|
|
205
|
+
noImplicitAny: false,
|
|
206
|
+
sourceMap: false,
|
|
207
|
+
removeComments: false,
|
|
208
|
+
disableSizeLimit: true,
|
|
209
|
+
esModuleInterop: true,
|
|
210
|
+
emitDecoratorMetadata: true,
|
|
211
|
+
skipLibCheck: true,
|
|
212
|
+
};
|
|
213
|
+
customTranslator;
|
|
214
|
+
|
|
171
215
|
Ts = {
|
|
172
216
|
Keyword: _.cloneDeep(TsKeyword),
|
|
173
217
|
CodeGenKeyword: _.cloneDeep(TsCodeGenKeyword),
|
|
@@ -200,28 +244,39 @@ class CodeGenConfig {
|
|
|
200
244
|
/**
|
|
201
245
|
* $A1 | $A2
|
|
202
246
|
*/
|
|
203
|
-
UnionType: (contents) =>
|
|
247
|
+
UnionType: (contents) =>
|
|
248
|
+
_.join(_.uniq(contents), ` ${this.Ts.Keyword.Union} `),
|
|
204
249
|
/**
|
|
205
250
|
* ($A1)
|
|
206
251
|
*/
|
|
207
|
-
ExpressionGroup: (content) => (content ? `(${content})` :
|
|
252
|
+
ExpressionGroup: (content) => (content ? `(${content})` : ''),
|
|
208
253
|
/**
|
|
209
254
|
* $A1 & $A2
|
|
210
255
|
*/
|
|
211
|
-
IntersectionType: (contents) =>
|
|
256
|
+
IntersectionType: (contents) =>
|
|
257
|
+
_.join(_.uniq(contents), ` ${this.Ts.Keyword.Intersection} `),
|
|
212
258
|
/**
|
|
213
259
|
* Record<$A1, $A2>
|
|
214
260
|
*/
|
|
215
|
-
RecordType: (key, value) =>
|
|
261
|
+
RecordType: (key, value) =>
|
|
262
|
+
this.Ts.TypeWithGeneric(this.Ts.Keyword.Record, [key, value]),
|
|
216
263
|
/**
|
|
217
264
|
* readonly $key?:$value
|
|
218
265
|
*/
|
|
219
266
|
TypeField: ({ readonly, key, optional, value }) =>
|
|
220
|
-
_.compact([
|
|
267
|
+
_.compact([
|
|
268
|
+
readonly && 'readonly ',
|
|
269
|
+
key,
|
|
270
|
+
optional && '?',
|
|
271
|
+
': ',
|
|
272
|
+
value,
|
|
273
|
+
]).join(''),
|
|
221
274
|
/**
|
|
222
275
|
* [key: $A1]: $A2
|
|
223
276
|
*/
|
|
224
277
|
InterfaceDynamicField: (key, value) => `[key: ${key}]: ${value}`,
|
|
278
|
+
|
|
279
|
+
EnumUsageKey: (enumStruct, key) => `${enumStruct}.${key}`,
|
|
225
280
|
/**
|
|
226
281
|
* $A1 = $A2
|
|
227
282
|
*/
|
|
@@ -232,7 +287,10 @@ class CodeGenConfig {
|
|
|
232
287
|
* $AN.key = $AN.value,
|
|
233
288
|
*/
|
|
234
289
|
EnumFieldsWrapper: (contents) =>
|
|
235
|
-
_.map(
|
|
290
|
+
_.map(
|
|
291
|
+
contents,
|
|
292
|
+
({ key, value }) => ` ${this.Ts.EnumField(key, value)}`,
|
|
293
|
+
).join(',\n'),
|
|
236
294
|
/**
|
|
237
295
|
* {\n $A \n}
|
|
238
296
|
*/
|
|
@@ -244,19 +302,21 @@ class CodeGenConfig {
|
|
|
244
302
|
[
|
|
245
303
|
...(contents.length === 1
|
|
246
304
|
? [`/** ${contents[0]} */`]
|
|
247
|
-
: [
|
|
305
|
+
: ['/**', ...contents.map((content) => ` * ${content}`), ' */']),
|
|
248
306
|
].map((part) => `${formatFn ? formatFn(part) : part}\n`),
|
|
249
307
|
/**
|
|
250
308
|
* $A1<...$A2.join(,)>
|
|
251
309
|
*/
|
|
252
310
|
TypeWithGeneric: (typeName, genericArgs) => {
|
|
253
|
-
return `${typeName}${
|
|
311
|
+
return `${typeName}${
|
|
312
|
+
genericArgs.length ? `<${genericArgs.join(',')}>` : ''
|
|
313
|
+
}`;
|
|
254
314
|
},
|
|
255
315
|
/**
|
|
256
316
|
* [$A1, $A2, ...$AN]
|
|
257
317
|
*/
|
|
258
318
|
Tuple: (values) => {
|
|
259
|
-
return `[${values.join(
|
|
319
|
+
return `[${values.join(', ')}]`;
|
|
260
320
|
},
|
|
261
321
|
};
|
|
262
322
|
|
|
@@ -277,43 +337,39 @@ class CodeGenConfig {
|
|
|
277
337
|
/** formats */
|
|
278
338
|
binary: () => this.Ts.Keyword.File,
|
|
279
339
|
file: () => this.Ts.Keyword.File,
|
|
280
|
-
|
|
340
|
+
'date-time': () => this.Ts.Keyword.String,
|
|
281
341
|
time: () => this.Ts.Keyword.String,
|
|
282
342
|
date: () => this.Ts.Keyword.String,
|
|
283
343
|
duration: () => this.Ts.Keyword.String,
|
|
284
344
|
email: () => this.Ts.Keyword.String,
|
|
285
|
-
|
|
286
|
-
|
|
345
|
+
'idn-email': () => this.Ts.Keyword.String,
|
|
346
|
+
'idn-hostname': () => this.Ts.Keyword.String,
|
|
287
347
|
ipv4: () => this.Ts.Keyword.String,
|
|
288
348
|
ipv6: () => this.Ts.Keyword.String,
|
|
289
349
|
uuid: () => this.Ts.Keyword.String,
|
|
290
350
|
uri: () => this.Ts.Keyword.String,
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
351
|
+
'uri-reference': () => this.Ts.Keyword.String,
|
|
352
|
+
'uri-template': () => this.Ts.Keyword.String,
|
|
353
|
+
'json-pointer': () => this.Ts.Keyword.String,
|
|
354
|
+
'relative-json-pointer': () => this.Ts.Keyword.String,
|
|
295
355
|
regex: () => this.Ts.Keyword.String,
|
|
296
356
|
},
|
|
297
|
-
array: ({ items, ...schemaPart }, parser) => {
|
|
298
|
-
const content = parser.getInlineParseContent(items);
|
|
299
|
-
return parser.schemaUtils.safeAddNullToType(schemaPart, this.Ts.ArrayType(content));
|
|
300
|
-
},
|
|
301
357
|
};
|
|
302
358
|
|
|
303
359
|
templateInfos = [
|
|
304
|
-
{ name:
|
|
305
|
-
{ name:
|
|
306
|
-
{ name:
|
|
307
|
-
{ name:
|
|
308
|
-
{ name:
|
|
309
|
-
{ name:
|
|
310
|
-
{ name:
|
|
311
|
-
{ name:
|
|
312
|
-
{ name:
|
|
313
|
-
{ name:
|
|
360
|
+
{ name: 'api', fileName: 'api' },
|
|
361
|
+
{ name: 'dataContracts', fileName: 'data-contracts' },
|
|
362
|
+
{ name: 'dataContractJsDoc', fileName: 'data-contract-jsdoc' },
|
|
363
|
+
{ name: 'interfaceDataContract', fileName: 'interface-data-contract' },
|
|
364
|
+
{ name: 'typeDataContract', fileName: 'type-data-contract' },
|
|
365
|
+
{ name: 'enumDataContract', fileName: 'enum-data-contract' },
|
|
366
|
+
{ name: 'objectFieldJsDoc', fileName: 'object-field-jsdoc' },
|
|
367
|
+
{ name: 'httpClient', fileName: 'http-client' },
|
|
368
|
+
{ name: 'routeTypes', fileName: 'route-types' },
|
|
369
|
+
{ name: 'routeName', fileName: 'route-name' },
|
|
314
370
|
];
|
|
315
371
|
|
|
316
|
-
templateExtensions = [
|
|
372
|
+
templateExtensions = ['.eta', '.ejs'];
|
|
317
373
|
|
|
318
374
|
/**
|
|
319
375
|
* @param config {Partial<GenerateApiConfiguration['config']>}
|
|
@@ -325,7 +381,7 @@ class CodeGenConfig {
|
|
|
325
381
|
constants,
|
|
326
382
|
templateInfos,
|
|
327
383
|
hooks,
|
|
328
|
-
...
|
|
384
|
+
...otherConfig
|
|
329
385
|
}) {
|
|
330
386
|
objectAssign(this.Ts, codeGenConstructs);
|
|
331
387
|
objectAssign(this.primitiveTypes, primitiveTypeConstructs);
|
|
@@ -333,8 +389,11 @@ class CodeGenConfig {
|
|
|
333
389
|
this.defaultResponseType = this.Ts.Keyword.Void;
|
|
334
390
|
|
|
335
391
|
this.update({
|
|
336
|
-
...
|
|
337
|
-
prettierOptions:
|
|
392
|
+
...otherConfig,
|
|
393
|
+
prettierOptions:
|
|
394
|
+
prettierOptions === undefined
|
|
395
|
+
? getDefaultPrettierOptions()
|
|
396
|
+
: prettierOptions,
|
|
338
397
|
hooks: _.merge(this.hooks, hooks || {}),
|
|
339
398
|
constants: {
|
|
340
399
|
...CONSTANTS,
|
|
@@ -343,8 +402,17 @@ class CodeGenConfig {
|
|
|
343
402
|
templateInfos: templateInfos || this.templateInfos,
|
|
344
403
|
});
|
|
345
404
|
|
|
346
|
-
this.jsPrimitiveTypes = [
|
|
405
|
+
this.jsPrimitiveTypes = [
|
|
406
|
+
this.Ts.Keyword.Number,
|
|
407
|
+
this.Ts.Keyword.String,
|
|
408
|
+
this.Ts.Keyword.Boolean,
|
|
409
|
+
];
|
|
347
410
|
this.jsEmptyTypes = [this.Ts.Keyword.Null, this.Ts.Keyword.Undefined];
|
|
411
|
+
this.componentTypeNameResolver = new ComponentTypeNameResolver(
|
|
412
|
+
this,
|
|
413
|
+
null,
|
|
414
|
+
[],
|
|
415
|
+
);
|
|
348
416
|
}
|
|
349
417
|
|
|
350
418
|
/**
|
|
@@ -357,12 +425,12 @@ class CodeGenConfig {
|
|
|
357
425
|
}
|
|
358
426
|
|
|
359
427
|
const getDefaultPrettierOptions = () => {
|
|
360
|
-
const prettier = cosmiconfigSync(
|
|
428
|
+
const prettier = cosmiconfigSync('prettier').search();
|
|
361
429
|
|
|
362
430
|
if (prettier) {
|
|
363
431
|
return {
|
|
364
432
|
...prettier.config,
|
|
365
|
-
parser:
|
|
433
|
+
parser: 'typescript',
|
|
366
434
|
};
|
|
367
435
|
}
|
|
368
436
|
|
package/src/constants.js
CHANGED
|
@@ -1,27 +1,33 @@
|
|
|
1
|
-
const packageJson = require(
|
|
2
|
-
const RESERVED_QUERY_ARG_NAMES = [
|
|
3
|
-
const RESERVED_BODY_ARG_NAMES = [
|
|
4
|
-
const RESERVED_REQ_PARAMS_ARG_NAMES = [
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
const packageJson = require('../package.json');
|
|
2
|
+
const RESERVED_QUERY_ARG_NAMES = ['query', 'queryParams', 'queryArg'];
|
|
3
|
+
const RESERVED_BODY_ARG_NAMES = ['data', 'body', 'reqBody'];
|
|
4
|
+
const RESERVED_REQ_PARAMS_ARG_NAMES = [
|
|
5
|
+
'params',
|
|
6
|
+
'requestParams',
|
|
7
|
+
'reqParams',
|
|
8
|
+
'httpParams',
|
|
9
|
+
];
|
|
10
|
+
const RESERVED_PATH_ARG_NAMES = ['path', 'pathParams'];
|
|
11
|
+
const RESERVED_HEADER_ARG_NAMES = ['headers', 'headersParams'];
|
|
7
12
|
|
|
8
13
|
const SCHEMA_TYPES = {
|
|
9
|
-
ARRAY:
|
|
10
|
-
OBJECT:
|
|
11
|
-
ENUM:
|
|
12
|
-
REF:
|
|
13
|
-
PRIMITIVE:
|
|
14
|
-
COMPLEX:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
ARRAY: 'array',
|
|
15
|
+
OBJECT: 'object',
|
|
16
|
+
ENUM: 'enum',
|
|
17
|
+
REF: '$ref',
|
|
18
|
+
PRIMITIVE: 'primitive',
|
|
19
|
+
COMPLEX: 'complex',
|
|
20
|
+
DISCRIMINATOR: 'discriminator',
|
|
21
|
+
COMPLEX_ONE_OF: 'oneOf',
|
|
22
|
+
COMPLEX_ANY_OF: 'anyOf',
|
|
23
|
+
COMPLEX_ALL_OF: 'allOf',
|
|
24
|
+
COMPLEX_NOT: 'not',
|
|
25
|
+
COMPLEX_UNKNOWN: '__unknown',
|
|
20
26
|
};
|
|
21
27
|
|
|
22
28
|
const HTTP_CLIENT = {
|
|
23
|
-
FETCH:
|
|
24
|
-
AXIOS:
|
|
29
|
+
FETCH: 'fetch',
|
|
30
|
+
AXIOS: 'axios',
|
|
25
31
|
};
|
|
26
32
|
|
|
27
33
|
const PROJECT_VERSION = packageJson.version;
|
|
@@ -41,7 +47,7 @@ const FILE_PREFIX = `/* eslint-disable */
|
|
|
41
47
|
|
|
42
48
|
module.exports = {
|
|
43
49
|
FILE_PREFIX,
|
|
44
|
-
DEFAULT_BODY_ARG_NAME:
|
|
50
|
+
DEFAULT_BODY_ARG_NAME: 'data',
|
|
45
51
|
PROJECT_VERSION,
|
|
46
52
|
SCHEMA_TYPES,
|
|
47
53
|
HTTP_CLIENT,
|
|
@@ -53,7 +59,7 @@ module.exports = {
|
|
|
53
59
|
PRETTIER_OPTIONS: {
|
|
54
60
|
printWidth: 120,
|
|
55
61
|
tabWidth: 2,
|
|
56
|
-
trailingComma:
|
|
57
|
-
parser:
|
|
62
|
+
trailingComma: 'all',
|
|
63
|
+
parser: 'typescript',
|
|
58
64
|
},
|
|
59
65
|
};
|
package/src/index.js
CHANGED
|
@@ -6,10 +6,9 @@
|
|
|
6
6
|
// License text available at https://opensource.org/licenses/MIT
|
|
7
7
|
// Repository https://github.com/acacode/swagger-typescript-api
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const {
|
|
12
|
-
const { generateTemplates } = require("./commands/generate-templates");
|
|
9
|
+
const constants = require('./constants');
|
|
10
|
+
const { CodeGenProcess } = require('./code-gen-process.js');
|
|
11
|
+
const { generateTemplates } = require('./commands/generate-templates');
|
|
13
12
|
|
|
14
13
|
module.exports = {
|
|
15
14
|
constants: constants,
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
const _ = require(
|
|
1
|
+
const _ = require('lodash');
|
|
2
2
|
|
|
3
3
|
class SchemaComponentsMap {
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
data = {};
|
|
8
|
-
/**
|
|
9
|
-
* @type {CodeGenConfig}
|
|
10
|
-
*/
|
|
4
|
+
/** @type {SchemaComponent[]} */
|
|
5
|
+
_data = [];
|
|
6
|
+
/** @type {CodeGenConfig} */
|
|
11
7
|
config;
|
|
12
8
|
|
|
13
|
-
constructor(config
|
|
9
|
+
constructor({ config }) {
|
|
14
10
|
this.config = config;
|
|
15
|
-
this.processSchema(schema);
|
|
16
11
|
}
|
|
17
12
|
|
|
18
|
-
|
|
19
|
-
this.
|
|
20
|
-
if (!schema) return;
|
|
21
|
-
_.each(schema.components, (component, componentName) =>
|
|
22
|
-
_.each(component, (rawTypeData, typeName) => this.createComponent(componentName, typeName, rawTypeData)),
|
|
23
|
-
);
|
|
13
|
+
clear() {
|
|
14
|
+
this._data = [];
|
|
24
15
|
}
|
|
25
16
|
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
createRef = (paths) => {
|
|
18
|
+
return ['#', ...paths].join('/');
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
parseRef = (ref) => {
|
|
22
|
+
return ref.split('/');
|
|
23
|
+
};
|
|
28
24
|
|
|
25
|
+
createComponent($ref, rawTypeData) {
|
|
26
|
+
const parsed = this.parseRef($ref);
|
|
27
|
+
const typeName = parsed[parsed.length - 1];
|
|
28
|
+
const componentName = parsed[parsed.length - 2];
|
|
29
29
|
const componentSchema = {
|
|
30
30
|
$ref,
|
|
31
31
|
typeName,
|
|
@@ -35,23 +35,39 @@ class SchemaComponentsMap {
|
|
|
35
35
|
typeData: null,
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
const usageComponent =
|
|
38
|
+
const usageComponent =
|
|
39
|
+
this.config.hooks.onCreateComponent(componentSchema) || componentSchema;
|
|
40
|
+
|
|
41
|
+
const refIndex = this._data.findIndex((c) => c.$ref === $ref);
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
if (refIndex === -1) {
|
|
44
|
+
this._data.push(usageComponent);
|
|
45
|
+
} else {
|
|
46
|
+
this._data[refIndex] = usageComponent;
|
|
47
|
+
}
|
|
41
48
|
|
|
42
49
|
return usageComponent;
|
|
43
50
|
}
|
|
44
51
|
|
|
52
|
+
/**
|
|
53
|
+
* @returns {SchemaComponent[]}
|
|
54
|
+
*/
|
|
55
|
+
getComponents() {
|
|
56
|
+
return this._data;
|
|
57
|
+
}
|
|
58
|
+
|
|
45
59
|
/**
|
|
46
60
|
* @param componentName {string}
|
|
47
61
|
* @returns {SchemaComponent[]}
|
|
48
62
|
*/
|
|
49
63
|
filter(componentName) {
|
|
50
|
-
return _.filter(this.
|
|
64
|
+
return _.filter(this._data, (v) =>
|
|
65
|
+
_.startsWith(v.$ref, `#/components/${componentName}`),
|
|
66
|
+
);
|
|
51
67
|
}
|
|
52
68
|
|
|
53
|
-
get(ref) {
|
|
54
|
-
return this.
|
|
69
|
+
get($ref) {
|
|
70
|
+
return this._data.find((c) => c.$ref === $ref) || null;
|
|
55
71
|
}
|
|
56
72
|
}
|
|
57
73
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const { MonoSchemaParser } = require('../mono-schema-parser');
|
|
2
|
+
const _ = require('lodash');
|
|
3
|
+
const { SCHEMA_TYPES } = require('../../constants');
|
|
4
|
+
|
|
5
|
+
class ArraySchemaParser extends MonoSchemaParser {
|
|
6
|
+
parse() {
|
|
7
|
+
let contentType;
|
|
8
|
+
const { type, description, items } = this.schema || {};
|
|
9
|
+
|
|
10
|
+
if (_.isArray(items) && type === SCHEMA_TYPES.ARRAY) {
|
|
11
|
+
const tupleContent = [];
|
|
12
|
+
for (const item of items) {
|
|
13
|
+
tupleContent.push(
|
|
14
|
+
this.schemaParserFabric
|
|
15
|
+
.createSchemaParser({ schema: item, schemaPath: this.schemaPath })
|
|
16
|
+
.getInlineParseContent(),
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
contentType = this.config.Ts.Tuple(tupleContent);
|
|
20
|
+
} else {
|
|
21
|
+
const content = this.schemaParserFabric
|
|
22
|
+
.createSchemaParser({ schema: items, schemaPath: this.schemaPath })
|
|
23
|
+
.getInlineParseContent();
|
|
24
|
+
contentType = this.config.Ts.ArrayType(content);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
...(_.isObject(this.schema) ? this.schema : {}),
|
|
29
|
+
$schemaPath: this.schemaPath.slice(),
|
|
30
|
+
$parsedSchema: true,
|
|
31
|
+
schemaType: SCHEMA_TYPES.PRIMITIVE,
|
|
32
|
+
type: SCHEMA_TYPES.PRIMITIVE,
|
|
33
|
+
typeIdentifier: this.config.Ts.Keyword.Type,
|
|
34
|
+
name: this.typeName,
|
|
35
|
+
description: this.schemaFormatters.formatDescription(description),
|
|
36
|
+
content: this.schemaUtils.safeAddNullToType(this.schema, contentType),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
ArraySchemaParser,
|
|
43
|
+
};
|