swagger-typescript-api 13.0.11 → 13.0.13
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/dist/{chunk-R4CYI34W.js → chunk-O6K2HOIW.js} +2 -2
- package/dist/chunk-O6K2HOIW.js.map +1 -0
- package/dist/{chunk-3OGOYA5P.cjs → chunk-T7GDAZLY.cjs} +2 -2
- package/dist/chunk-T7GDAZLY.cjs.map +1 -0
- package/dist/cli.cjs +9 -9
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +9 -9
- package/dist/cli.js.map +1 -1
- package/dist/lib.cjs +4 -4
- package/dist/lib.js +1 -1
- package/dist/types.d.cts +1818 -0
- package/dist/types.d.ts +1818 -0
- package/package.json +9 -10
- package/cli/index.d.ts +0 -35
- package/dist/chunk-3OGOYA5P.cjs.map +0 -1
- package/dist/chunk-R4CYI34W.js.map +0 -1
- package/index.d.ts +0 -784
package/dist/types.d.cts
ADDED
|
@@ -0,0 +1,1818 @@
|
|
|
1
|
+
import * as eta from 'eta';
|
|
2
|
+
import * as lodash from 'lodash';
|
|
3
|
+
import * as swagger_schema_official from 'swagger-schema-official';
|
|
4
|
+
|
|
5
|
+
declare class NameResolver {
|
|
6
|
+
reservedNames = [];
|
|
7
|
+
getFallbackName = null;
|
|
8
|
+
|
|
9
|
+
/** @type {CodeGenConfig} */
|
|
10
|
+
config;
|
|
11
|
+
/** @type {Logger} */
|
|
12
|
+
logger;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {CodeGenConfig} config;
|
|
16
|
+
* @param {Logger} logger;
|
|
17
|
+
* @param {string[]} reservedNames
|
|
18
|
+
*/
|
|
19
|
+
constructor(config, logger, reservedNames, getFallbackName) {
|
|
20
|
+
this.config = config;
|
|
21
|
+
this.logger = logger;
|
|
22
|
+
this.getFallbackName = getFallbackName;
|
|
23
|
+
this.reserve(reservedNames);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {string[]} names
|
|
28
|
+
*/
|
|
29
|
+
reserve(names) {
|
|
30
|
+
const fixedNames = _.uniq(_.compact(names));
|
|
31
|
+
for (const name of fixedNames) {
|
|
32
|
+
if (this.reservedNames.indexOf(name) === -1) {
|
|
33
|
+
this.reservedNames.push(name);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
unreserve(names) {
|
|
39
|
+
this.reservedNames.filter(
|
|
40
|
+
(reservedName) => !names.some((name) => name === reservedName),
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
isReserved(name) {
|
|
45
|
+
return _.some(this.reservedNames, (reservedName) => reservedName === name);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
* @param {(string[])} variants
|
|
51
|
+
* @param {(reserved: string[]) => string)} [resolver]
|
|
52
|
+
* @param {any} [extras]
|
|
53
|
+
* @returns {string | null}
|
|
54
|
+
*/
|
|
55
|
+
resolve(variants, resolver, extras, shouldReserve = true) {
|
|
56
|
+
if (typeof resolver === "function") {
|
|
57
|
+
let usageName = null;
|
|
58
|
+
while (usageName === null) {
|
|
59
|
+
const variant = resolver(variants, extras);
|
|
60
|
+
|
|
61
|
+
if (variant === undefined) {
|
|
62
|
+
this.logger.warn(
|
|
63
|
+
"unable to resolve name. current reserved names: ",
|
|
64
|
+
this.reservedNames,
|
|
65
|
+
);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
if (!shouldReserve || !this.isReserved(variant)) {
|
|
69
|
+
usageName = variant;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
shouldReserve && this.reserve([usageName]);
|
|
74
|
+
return usageName;
|
|
75
|
+
} else if (Array.isArray(variants)) {
|
|
76
|
+
let usageName = null;
|
|
77
|
+
const uniqVariants = _.uniq(_.compact(variants));
|
|
78
|
+
|
|
79
|
+
_.forEach(uniqVariants, (variant) => {
|
|
80
|
+
if (!usageName && (!shouldReserve || !this.isReserved(variant))) {
|
|
81
|
+
usageName = variant;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
if (usageName) {
|
|
86
|
+
shouldReserve && this.reserve([usageName]);
|
|
87
|
+
return usageName;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
this.logger.debug(
|
|
91
|
+
"trying to resolve name with using fallback name generator using variants",
|
|
92
|
+
variants,
|
|
93
|
+
);
|
|
94
|
+
return this.resolve(variants, this.getFallbackName, extras);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
this.logger.debug(
|
|
98
|
+
"problem with reserving names. current reserved names: ",
|
|
99
|
+
this.reservedNames,
|
|
100
|
+
);
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
declare class ComponentTypeNameResolver extends NameResolver {
|
|
106
|
+
counter = 1;
|
|
107
|
+
fallbackNameCounter = 1;
|
|
108
|
+
countersByVariant = new Map();
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {CodeGenConfig} config;
|
|
112
|
+
* @param {Logger} logger;
|
|
113
|
+
* @param {string[]} reservedNames
|
|
114
|
+
*/
|
|
115
|
+
constructor(config, logger, reservedNames) {
|
|
116
|
+
super(config, logger, reservedNames, (variants) => {
|
|
117
|
+
const randomVariant = variants[getRandomInt(0, variants.length - 1)];
|
|
118
|
+
if (randomVariant) {
|
|
119
|
+
if (!this.countersByVariant.has(randomVariant)) {
|
|
120
|
+
this.countersByVariant.set(randomVariant, 0);
|
|
121
|
+
}
|
|
122
|
+
const variantCounter = this.countersByVariant.get(randomVariant) + 1;
|
|
123
|
+
this.countersByVariant.set(randomVariant, variantCounter);
|
|
124
|
+
const dirtyResolvedName = `${randomVariant}${variantCounter}`;
|
|
125
|
+
this.logger.debug(
|
|
126
|
+
"generated dirty resolved type name for component - ",
|
|
127
|
+
dirtyResolvedName,
|
|
128
|
+
);
|
|
129
|
+
return dirtyResolvedName;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const fallbackName = `${this.config.componentTypeNameResolver}${this
|
|
133
|
+
.fallbackNameCounter++}`;
|
|
134
|
+
this.logger.debug(
|
|
135
|
+
"generated fallback type name for component - ",
|
|
136
|
+
fallbackName,
|
|
137
|
+
);
|
|
138
|
+
return fallbackName;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
declare class MonoSchemaParser {
|
|
144
|
+
schema;
|
|
145
|
+
typeName;
|
|
146
|
+
schemaPath;
|
|
147
|
+
|
|
148
|
+
/** @type {Logger} */
|
|
149
|
+
logger;
|
|
150
|
+
/** @type {SchemaParser} */
|
|
151
|
+
schemaParser;
|
|
152
|
+
/** @type {SchemaParserFabric} */
|
|
153
|
+
schemaParserFabric;
|
|
154
|
+
/** @type {TypeNameFormatter} */
|
|
155
|
+
typeNameFormatter;
|
|
156
|
+
/** @type {SchemaComponentsMap} */
|
|
157
|
+
schemaComponentsMap;
|
|
158
|
+
/** @type {SchemaUtils} */
|
|
159
|
+
schemaUtils;
|
|
160
|
+
/** @type {CodeGenConfig} */
|
|
161
|
+
config;
|
|
162
|
+
/** @type {SchemaFormatters} */
|
|
163
|
+
schemaFormatters;
|
|
164
|
+
|
|
165
|
+
constructor(schemaParser, schema, typeName = null, schemaPath = []) {
|
|
166
|
+
this.schemaParser = schemaParser;
|
|
167
|
+
this.schemaParserFabric = schemaParser.schemaParserFabric;
|
|
168
|
+
this.logger = schemaParser.logger;
|
|
169
|
+
this.schema = schema;
|
|
170
|
+
this.typeName = typeName;
|
|
171
|
+
this.typeNameFormatter = schemaParser.typeNameFormatter;
|
|
172
|
+
this.schemaPath = schemaPath;
|
|
173
|
+
this.schemaComponentsMap = this.schemaParser.schemaComponentsMap;
|
|
174
|
+
this.schemaUtils = this.schemaParser.schemaUtils;
|
|
175
|
+
this.config = this.schemaParser.config;
|
|
176
|
+
this.schemaFormatters = this.schemaParser.schemaFormatters;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
parse() {
|
|
180
|
+
throw new Error("not implemented");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
buildTypeNameFromPath = () => {
|
|
184
|
+
return this.schemaUtils.buildTypeNameFromPath(this.schemaPath);
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
declare class SchemaParser {
|
|
189
|
+
/** @type {SchemaParserFabric} */
|
|
190
|
+
schemaParserFabric;
|
|
191
|
+
/** @type {CodeGenConfig} */
|
|
192
|
+
config;
|
|
193
|
+
/** @type {Logger} */
|
|
194
|
+
logger;
|
|
195
|
+
/** @type {SchemaComponentsMap} */
|
|
196
|
+
schemaComponentsMap;
|
|
197
|
+
/** @type {TypeNameFormatter} */
|
|
198
|
+
typeNameFormatter;
|
|
199
|
+
/** @type {SchemaFormatters} */
|
|
200
|
+
schemaFormatters;
|
|
201
|
+
/** @type {SchemaUtils} */
|
|
202
|
+
schemaUtils;
|
|
203
|
+
/** @type {TemplatesWorker} */
|
|
204
|
+
templatesWorker;
|
|
205
|
+
/** @type {SchemaWalker} */
|
|
206
|
+
schemaWalker;
|
|
207
|
+
|
|
208
|
+
typeName;
|
|
209
|
+
schema;
|
|
210
|
+
schemaPath = [];
|
|
211
|
+
|
|
212
|
+
constructor(schemaParserFabric, { typeName, schema, schemaPath } = {}) {
|
|
213
|
+
this.schemaParserFabric = schemaParserFabric;
|
|
214
|
+
this.config = schemaParserFabric.config;
|
|
215
|
+
this.logger = schemaParserFabric.logger;
|
|
216
|
+
this.templatesWorker = schemaParserFabric.templatesWorker;
|
|
217
|
+
this.schemaComponentsMap = schemaParserFabric.schemaComponentsMap;
|
|
218
|
+
this.typeNameFormatter = schemaParserFabric.typeNameFormatter;
|
|
219
|
+
this.schemaWalker = schemaParserFabric.schemaWalker;
|
|
220
|
+
this.schemaFormatters = schemaParserFabric.schemaFormatters;
|
|
221
|
+
this.schemaUtils = schemaParserFabric.schemaUtils;
|
|
222
|
+
|
|
223
|
+
this.typeName = typeName || null;
|
|
224
|
+
this.schema = schema;
|
|
225
|
+
this.schemaPath = [...(schemaPath || [])];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
_complexSchemaParsers = {
|
|
229
|
+
[SCHEMA_TYPES.COMPLEX_ONE_OF]: (schema) => {
|
|
230
|
+
const SchemaParser =
|
|
231
|
+
this.config.schemaParsers.complexOneOf || OneOfSchemaParser;
|
|
232
|
+
const schemaParser = new SchemaParser(
|
|
233
|
+
this,
|
|
234
|
+
schema,
|
|
235
|
+
null,
|
|
236
|
+
this.schemaPath,
|
|
237
|
+
);
|
|
238
|
+
return schemaParser.parse();
|
|
239
|
+
},
|
|
240
|
+
[SCHEMA_TYPES.COMPLEX_ALL_OF]: (schema) => {
|
|
241
|
+
const SchemaParser =
|
|
242
|
+
this.config.schemaParsers.complexAllOf || AllOfSchemaParser;
|
|
243
|
+
const schemaParser = new SchemaParser(
|
|
244
|
+
this,
|
|
245
|
+
schema,
|
|
246
|
+
null,
|
|
247
|
+
this.schemaPath,
|
|
248
|
+
);
|
|
249
|
+
return schemaParser.parse();
|
|
250
|
+
},
|
|
251
|
+
[SCHEMA_TYPES.COMPLEX_ANY_OF]: (schema) => {
|
|
252
|
+
const SchemaParser =
|
|
253
|
+
this.config.schemaParsers.complexAnyOf || AnyOfSchemaParser;
|
|
254
|
+
const schemaParser = new SchemaParser(
|
|
255
|
+
this,
|
|
256
|
+
schema,
|
|
257
|
+
null,
|
|
258
|
+
this.schemaPath,
|
|
259
|
+
);
|
|
260
|
+
return schemaParser.parse();
|
|
261
|
+
},
|
|
262
|
+
[SCHEMA_TYPES.COMPLEX_NOT]: (schema) => {
|
|
263
|
+
const SchemaParser =
|
|
264
|
+
this.config.schemaParsers.complexNot || NotSchemaParser;
|
|
265
|
+
const schemaParser = new SchemaParser(
|
|
266
|
+
this,
|
|
267
|
+
schema,
|
|
268
|
+
null,
|
|
269
|
+
this.schemaPath,
|
|
270
|
+
);
|
|
271
|
+
return schemaParser.parse();
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
_baseSchemaParsers = {
|
|
276
|
+
[SCHEMA_TYPES.ENUM]: (schema, typeName) => {
|
|
277
|
+
const SchemaParser = this.config.schemaParsers.enum || EnumSchemaParser;
|
|
278
|
+
const schemaParser = new SchemaParser(
|
|
279
|
+
this,
|
|
280
|
+
schema,
|
|
281
|
+
typeName,
|
|
282
|
+
this.schemaPath,
|
|
283
|
+
);
|
|
284
|
+
return schemaParser.parse();
|
|
285
|
+
},
|
|
286
|
+
[SCHEMA_TYPES.OBJECT]: (schema, typeName) => {
|
|
287
|
+
const SchemaParser =
|
|
288
|
+
this.config.schemaParsers.object || ObjectSchemaParser;
|
|
289
|
+
const schemaParser = new SchemaParser(
|
|
290
|
+
this,
|
|
291
|
+
schema,
|
|
292
|
+
typeName,
|
|
293
|
+
this.schemaPath,
|
|
294
|
+
);
|
|
295
|
+
return schemaParser.parse();
|
|
296
|
+
},
|
|
297
|
+
[SCHEMA_TYPES.COMPLEX]: (schema, typeName) => {
|
|
298
|
+
const SchemaParser =
|
|
299
|
+
this.config.schemaParsers.complex || ComplexSchemaParser;
|
|
300
|
+
const schemaParser = new SchemaParser(
|
|
301
|
+
this,
|
|
302
|
+
schema,
|
|
303
|
+
typeName,
|
|
304
|
+
this.schemaPath,
|
|
305
|
+
);
|
|
306
|
+
return schemaParser.parse();
|
|
307
|
+
},
|
|
308
|
+
[SCHEMA_TYPES.PRIMITIVE]: (schema, typeName) => {
|
|
309
|
+
const SchemaParser =
|
|
310
|
+
this.config.schemaParsers.primitive || PrimitiveSchemaParser;
|
|
311
|
+
const schemaParser = new SchemaParser(
|
|
312
|
+
this,
|
|
313
|
+
schema,
|
|
314
|
+
typeName,
|
|
315
|
+
this.schemaPath,
|
|
316
|
+
);
|
|
317
|
+
return schemaParser.parse();
|
|
318
|
+
},
|
|
319
|
+
[SCHEMA_TYPES.DISCRIMINATOR]: (schema, typeName) => {
|
|
320
|
+
const SchemaParser =
|
|
321
|
+
this.config.schemaParsers.discriminator || DiscriminatorSchemaParser;
|
|
322
|
+
const schemaParser = new SchemaParser(
|
|
323
|
+
this,
|
|
324
|
+
schema,
|
|
325
|
+
typeName,
|
|
326
|
+
this.schemaPath,
|
|
327
|
+
);
|
|
328
|
+
return schemaParser.parse();
|
|
329
|
+
},
|
|
330
|
+
[SCHEMA_TYPES.ARRAY]: (schema, typeName) => {
|
|
331
|
+
const SchemaParser = this.config.schemaParsers.array || ArraySchemaParser;
|
|
332
|
+
const schemaParser = new SchemaParser(
|
|
333
|
+
this,
|
|
334
|
+
schema,
|
|
335
|
+
typeName,
|
|
336
|
+
this.schemaPath,
|
|
337
|
+
);
|
|
338
|
+
return schemaParser.parse();
|
|
339
|
+
},
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* @return {Record<string, any>}
|
|
344
|
+
*/
|
|
345
|
+
parseSchema = () => {
|
|
346
|
+
if (!this.schema)
|
|
347
|
+
return this._baseSchemaParsers[SCHEMA_TYPES.PRIMITIVE](
|
|
348
|
+
null,
|
|
349
|
+
this.typeName,
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
let schemaType = null;
|
|
353
|
+
let parsedSchema = null;
|
|
354
|
+
|
|
355
|
+
if (typeof this.schema === "string") {
|
|
356
|
+
return this.schema;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (!this.schema.$parsed) {
|
|
360
|
+
if (!this.typeName && this.schemaUtils.isRefSchema(this.schema)) {
|
|
361
|
+
this.typeName = this.schemaUtils.getSchemaType(this.schema);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
//#region swagger schemas fixes
|
|
365
|
+
|
|
366
|
+
// schema has items but don't have array type
|
|
367
|
+
if (
|
|
368
|
+
this.schema.items &&
|
|
369
|
+
!Array.isArray(this.schema.items) &&
|
|
370
|
+
!this.schema.type
|
|
371
|
+
) {
|
|
372
|
+
this.schema.type = SCHEMA_TYPES.ARRAY;
|
|
373
|
+
}
|
|
374
|
+
// schema is enum with one null value
|
|
375
|
+
if (
|
|
376
|
+
Array.isArray(this.schema.enum) &&
|
|
377
|
+
this.schema.enum.length === 1 &&
|
|
378
|
+
this.schema.enum[0] == null
|
|
379
|
+
) {
|
|
380
|
+
this.logger.debug("invalid enum schema", this.schema);
|
|
381
|
+
this.schema = { type: this.config.Ts.Keyword.Null };
|
|
382
|
+
}
|
|
383
|
+
// schema is response schema
|
|
384
|
+
if ("content" in this.schema && typeof this.schema.content === "object") {
|
|
385
|
+
const schema = this.extractSchemaFromResponseStruct(this.schema);
|
|
386
|
+
const schemaParser = this.schemaParserFabric.createSchemaParser({
|
|
387
|
+
schema,
|
|
388
|
+
typeName: this.typeName,
|
|
389
|
+
schemaPath: this.schemaPath,
|
|
390
|
+
});
|
|
391
|
+
this.schema.$parsed = schemaParser.parseSchema();
|
|
392
|
+
return this.schema.$parsed;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
//#endregion
|
|
396
|
+
|
|
397
|
+
schemaType = this.schemaUtils.getInternalSchemaType(this.schema);
|
|
398
|
+
|
|
399
|
+
this.schemaPath.push(this.typeName);
|
|
400
|
+
|
|
401
|
+
_.merge(
|
|
402
|
+
this.schema,
|
|
403
|
+
this.config.hooks.onPreParseSchema(
|
|
404
|
+
this.schema,
|
|
405
|
+
this.typeName,
|
|
406
|
+
schemaType,
|
|
407
|
+
),
|
|
408
|
+
);
|
|
409
|
+
parsedSchema = this._baseSchemaParsers[schemaType](
|
|
410
|
+
this.schema,
|
|
411
|
+
this.typeName,
|
|
412
|
+
);
|
|
413
|
+
this.schema.$parsed =
|
|
414
|
+
this.config.hooks.onParseSchema(this.schema, parsedSchema) ||
|
|
415
|
+
parsedSchema;
|
|
416
|
+
|
|
417
|
+
if (
|
|
418
|
+
this.config.sortTypes &&
|
|
419
|
+
Array.isArray(this.schema.$parsed?.content)
|
|
420
|
+
) {
|
|
421
|
+
this.schema.$parsed.content = this.schema.$parsed.content.sort(
|
|
422
|
+
sortByProperty("name"),
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
this.schemaPath.pop();
|
|
428
|
+
|
|
429
|
+
return this.schema.$parsed;
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
getInlineParseContent = () => {
|
|
433
|
+
const parsedSchema = this.parseSchema();
|
|
434
|
+
const formattedSchema = this.schemaFormatters.formatSchema(
|
|
435
|
+
parsedSchema,
|
|
436
|
+
"inline",
|
|
437
|
+
);
|
|
438
|
+
return formattedSchema.content;
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
getParseContent = () => {
|
|
442
|
+
const parsedSchema = this.parseSchema();
|
|
443
|
+
const formattedSchema = this.schemaFormatters.formatSchema(
|
|
444
|
+
parsedSchema,
|
|
445
|
+
"base",
|
|
446
|
+
);
|
|
447
|
+
return formattedSchema.content;
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
extractSchemaFromResponseStruct = (responseStruct) => {
|
|
451
|
+
const { content, ...extras } = responseStruct;
|
|
452
|
+
|
|
453
|
+
const firstResponse = _.first(_.values(content));
|
|
454
|
+
const firstSchema = _.get(firstResponse, "schema");
|
|
455
|
+
|
|
456
|
+
if (!firstSchema) return;
|
|
457
|
+
|
|
458
|
+
return {
|
|
459
|
+
...extras,
|
|
460
|
+
..._.omit(firstResponse, "schema"),
|
|
461
|
+
...firstSchema,
|
|
462
|
+
};
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* @typedef {{ fileName: string, fileExtension: string, fileContent: string }} TranslatorIO
|
|
468
|
+
*/
|
|
469
|
+
|
|
470
|
+
declare class Translator {
|
|
471
|
+
/** @type {Logger} */
|
|
472
|
+
logger;
|
|
473
|
+
/** @type {CodeGenConfig} */
|
|
474
|
+
config;
|
|
475
|
+
/** @type {CodeFormatter} */
|
|
476
|
+
codeFormatter;
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* @param codeGenProcess
|
|
480
|
+
*/
|
|
481
|
+
constructor(codeGenProcess) {
|
|
482
|
+
this.logger = codeGenProcess.logger;
|
|
483
|
+
this.config = codeGenProcess.config;
|
|
484
|
+
this.codeFormatter = codeGenProcess.codeFormatter;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
*
|
|
489
|
+
* @param input {TranslatorIO}
|
|
490
|
+
* @return {Promise<TranslatorIO[]>}
|
|
491
|
+
*/
|
|
492
|
+
// eslint-disable-next-line no-unused-vars
|
|
493
|
+
translate(input) {
|
|
494
|
+
throw new Error("not implemented");
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
declare class CodeGenProcess {
|
|
499
|
+
/** @type {CodeGenConfig} */
|
|
500
|
+
config;
|
|
501
|
+
/** @type {SwaggerSchemaResolver} */
|
|
502
|
+
swaggerSchemaResolver;
|
|
503
|
+
/** @type {SchemaComponentsMap} */
|
|
504
|
+
schemaComponentsMap;
|
|
505
|
+
/** @type {Logger} */
|
|
506
|
+
logger;
|
|
507
|
+
/** @type {TypeNameFormatter} */
|
|
508
|
+
typeNameFormatter;
|
|
509
|
+
/** @type {SchemaParserFabric} */
|
|
510
|
+
schemaParserFabric;
|
|
511
|
+
/** @type {SchemaRoutes} */
|
|
512
|
+
schemaRoutes;
|
|
513
|
+
/** @type {FileSystem} */
|
|
514
|
+
fileSystem;
|
|
515
|
+
/** @type {CodeFormatter} */
|
|
516
|
+
codeFormatter;
|
|
517
|
+
/** type {TemplatesWorker} */
|
|
518
|
+
templatesWorker;
|
|
519
|
+
/** @type {SchemaWalker} */
|
|
520
|
+
schemaWalker;
|
|
521
|
+
/** @type {JavascriptTranslator} */
|
|
522
|
+
javascriptTranslator;
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
*
|
|
526
|
+
* @param config {Partial<import("../index.d.ts").GenerateApiConfiguration['config']>}
|
|
527
|
+
*/
|
|
528
|
+
constructor(config) {
|
|
529
|
+
this.config = new CodeGenConfig(config);
|
|
530
|
+
this.logger = new Logger(this);
|
|
531
|
+
this.fileSystem = new FileSystem(this);
|
|
532
|
+
this.schemaWalker = new SchemaWalker(this);
|
|
533
|
+
this.swaggerSchemaResolver = new SwaggerSchemaResolver(this);
|
|
534
|
+
this.schemaComponentsMap = new SchemaComponentsMap(this);
|
|
535
|
+
this.typeNameFormatter = new TypeNameFormatter(this);
|
|
536
|
+
this.templatesWorker = new TemplatesWorker(this);
|
|
537
|
+
this.codeFormatter = new CodeFormatter(this);
|
|
538
|
+
this.schemaParserFabric = new SchemaParserFabric(this);
|
|
539
|
+
this.schemaRoutes = new SchemaRoutes(this);
|
|
540
|
+
this.javascriptTranslator = new JavascriptTranslator(this);
|
|
541
|
+
this.config.componentTypeNameResolver.logger = this.logger;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
async start() {
|
|
545
|
+
this.config.update({
|
|
546
|
+
templatePaths: this.templatesWorker.getTemplatePaths(this.config),
|
|
547
|
+
});
|
|
548
|
+
this.config.update({
|
|
549
|
+
templatesToRender: this.templatesWorker.getTemplates(this.config),
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
const swagger = await this.swaggerSchemaResolver.create();
|
|
553
|
+
|
|
554
|
+
this.swaggerSchemaResolver.fixSwaggerSchema(swagger);
|
|
555
|
+
|
|
556
|
+
this.config.update({
|
|
557
|
+
swaggerSchema: swagger.usageSchema,
|
|
558
|
+
originalSchema: swagger.originalSchema,
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
this.schemaWalker.addSchema("$usage", swagger.usageSchema);
|
|
562
|
+
this.schemaWalker.addSchema("$original", swagger.originalSchema);
|
|
563
|
+
|
|
564
|
+
this.logger.event("start generating your typescript api");
|
|
565
|
+
|
|
566
|
+
this.config.update(
|
|
567
|
+
this.config.hooks.onInit(this.config, this) || this.config,
|
|
568
|
+
);
|
|
569
|
+
|
|
570
|
+
this.schemaComponentsMap.clear();
|
|
571
|
+
|
|
572
|
+
_.each(swagger.usageSchema.components, (component, componentName) =>
|
|
573
|
+
_.each(component, (rawTypeData, typeName) => {
|
|
574
|
+
this.schemaComponentsMap.createComponent(
|
|
575
|
+
this.schemaComponentsMap.createRef([
|
|
576
|
+
"components",
|
|
577
|
+
componentName,
|
|
578
|
+
typeName,
|
|
579
|
+
]),
|
|
580
|
+
rawTypeData,
|
|
581
|
+
);
|
|
582
|
+
}),
|
|
583
|
+
);
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* @type {SchemaComponent[]}
|
|
587
|
+
*/
|
|
588
|
+
const componentsToParse = this.schemaComponentsMap.filter(
|
|
589
|
+
_.compact(["schemas", this.config.extractResponses && "responses"]),
|
|
590
|
+
);
|
|
591
|
+
|
|
592
|
+
const parsedSchemas = componentsToParse.map((schemaComponent) => {
|
|
593
|
+
const parsed = this.schemaParserFabric.parseSchema(
|
|
594
|
+
schemaComponent.rawTypeData,
|
|
595
|
+
schemaComponent.typeName,
|
|
596
|
+
);
|
|
597
|
+
schemaComponent.typeData = parsed;
|
|
598
|
+
return parsed;
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
this.schemaRoutes.attachSchema({
|
|
602
|
+
usageSchema: swagger.usageSchema,
|
|
603
|
+
parsedSchemas,
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
const rawConfiguration = {
|
|
607
|
+
apiConfig: this.createApiConfig(swagger.usageSchema),
|
|
608
|
+
config: this.config,
|
|
609
|
+
modelTypes: this.collectModelTypes(),
|
|
610
|
+
hasSecurityRoutes: this.schemaRoutes.hasSecurityRoutes,
|
|
611
|
+
hasQueryRoutes: this.schemaRoutes.hasQueryRoutes,
|
|
612
|
+
hasFormDataRoutes: this.schemaRoutes.hasFormDataRoutes,
|
|
613
|
+
generateResponses: this.config.generateResponses,
|
|
614
|
+
routes: this.schemaRoutes.getGroupedRoutes(),
|
|
615
|
+
extraTemplates: this.config.extraTemplates,
|
|
616
|
+
fileName: this.config.fileName,
|
|
617
|
+
translateToJavaScript: this.config.toJS,
|
|
618
|
+
customTranslator: this.config.customTranslator
|
|
619
|
+
? new this.config.customTranslator(this)
|
|
620
|
+
: null,
|
|
621
|
+
utils: this.getRenderTemplateData().utils,
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
const configuration =
|
|
625
|
+
this.config.hooks.onPrepareConfig(rawConfiguration) || rawConfiguration;
|
|
626
|
+
|
|
627
|
+
if (this.fileSystem.pathIsExist(this.config.output)) {
|
|
628
|
+
if (this.config.cleanOutput) {
|
|
629
|
+
this.logger.debug(`cleaning dir ${this.config.output}`);
|
|
630
|
+
this.fileSystem.cleanDir(this.config.output);
|
|
631
|
+
}
|
|
632
|
+
} else {
|
|
633
|
+
this.logger.debug(
|
|
634
|
+
`path ${this.config.output} is not exist. creating dir by this path`,
|
|
635
|
+
);
|
|
636
|
+
this.fileSystem.createDir(this.config.output);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
const files = await this.generateOutputFiles({
|
|
640
|
+
configuration: configuration,
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
const isDirPath = this.fileSystem.pathIsDir(this.config.output);
|
|
644
|
+
|
|
645
|
+
if (isDirPath) {
|
|
646
|
+
files.forEach((file) => {
|
|
647
|
+
this.fileSystem.createFile({
|
|
648
|
+
path: this.config.output,
|
|
649
|
+
fileName: `${file.fileName}${file.fileExtension}`,
|
|
650
|
+
content: file.fileContent,
|
|
651
|
+
withPrefix: true,
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
this.logger.success(
|
|
655
|
+
"api file",
|
|
656
|
+
`"${file.fileName}${file.fileExtension}"`,
|
|
657
|
+
`created in ${this.config.output}`,
|
|
658
|
+
);
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
return {
|
|
663
|
+
files,
|
|
664
|
+
configuration,
|
|
665
|
+
getTemplate: this.templatesWorker.getTemplate,
|
|
666
|
+
renderTemplate: this.templatesWorker.renderTemplate,
|
|
667
|
+
createFile: this.fileSystem.createFile,
|
|
668
|
+
formatTSContent: this.codeFormatter.formatCode,
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
getRenderTemplateData = () => {
|
|
673
|
+
return {
|
|
674
|
+
utils: {
|
|
675
|
+
Ts: this.config.Ts,
|
|
676
|
+
formatDescription:
|
|
677
|
+
this.schemaParserFabric.schemaFormatters.formatDescription,
|
|
678
|
+
internalCase: internalCase,
|
|
679
|
+
classNameCase: pascalCase,
|
|
680
|
+
pascalCase: pascalCase,
|
|
681
|
+
getInlineParseContent: this.schemaParserFabric.getInlineParseContent,
|
|
682
|
+
getParseContent: this.schemaParserFabric.getParseContent,
|
|
683
|
+
getComponentByRef: this.schemaComponentsMap.get,
|
|
684
|
+
parseSchema: this.schemaParserFabric.parseSchema,
|
|
685
|
+
checkAndAddNull: this.schemaParserFabric.schemaUtils.safeAddNullToType,
|
|
686
|
+
safeAddNullToType:
|
|
687
|
+
this.schemaParserFabric.schemaUtils.safeAddNullToType,
|
|
688
|
+
isNeedToAddNull:
|
|
689
|
+
this.schemaParserFabric.schemaUtils.isNullMissingInType,
|
|
690
|
+
inlineExtraFormatters: this.schemaParserFabric.schemaFormatters.inline,
|
|
691
|
+
formatters: this.schemaParserFabric.schemaFormatters.base,
|
|
692
|
+
formatModelName: this.typeNameFormatter.format,
|
|
693
|
+
fmtToJSDocLine: function fmtToJSDocLine(line, { eol = true }) {
|
|
694
|
+
return ` * ${line}${eol ? "\n" : ""}`;
|
|
695
|
+
},
|
|
696
|
+
NameResolver: NameResolver,
|
|
697
|
+
_,
|
|
698
|
+
require: this.templatesWorker.requireFnFromTemplate,
|
|
699
|
+
},
|
|
700
|
+
config: this.config,
|
|
701
|
+
};
|
|
702
|
+
};
|
|
703
|
+
|
|
704
|
+
collectModelTypes = () => {
|
|
705
|
+
const components = this.schemaComponentsMap.getComponents();
|
|
706
|
+
let modelTypes = [];
|
|
707
|
+
|
|
708
|
+
const modelTypeComponents = _.compact([
|
|
709
|
+
"schemas",
|
|
710
|
+
this.config.extractResponses && "responses",
|
|
711
|
+
]);
|
|
712
|
+
|
|
713
|
+
const getSchemaComponentsCount = () =>
|
|
714
|
+
this.schemaComponentsMap.filter(...modelTypeComponents).length;
|
|
715
|
+
|
|
716
|
+
let schemaComponentsCount = getSchemaComponentsCount();
|
|
717
|
+
let processedCount = 0;
|
|
718
|
+
|
|
719
|
+
while (processedCount < schemaComponentsCount) {
|
|
720
|
+
modelTypes = [];
|
|
721
|
+
processedCount = 0;
|
|
722
|
+
for (const component of components) {
|
|
723
|
+
if (modelTypeComponents.includes(component.componentName)) {
|
|
724
|
+
const modelType = this.prepareModelType(component);
|
|
725
|
+
if (modelType) {
|
|
726
|
+
modelTypes.push(modelType);
|
|
727
|
+
}
|
|
728
|
+
processedCount++;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
schemaComponentsCount = getSchemaComponentsCount();
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
if (this.config.sortTypes) {
|
|
735
|
+
return modelTypes.sort(sortByProperty("name"));
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
return modelTypes;
|
|
739
|
+
};
|
|
740
|
+
|
|
741
|
+
prepareModelType = (typeInfo) => {
|
|
742
|
+
if (typeInfo.$prepared) return typeInfo.$prepared;
|
|
743
|
+
|
|
744
|
+
if (!typeInfo.typeData) {
|
|
745
|
+
typeInfo.typeData = this.schemaParserFabric.parseSchema(
|
|
746
|
+
typeInfo.rawTypeData,
|
|
747
|
+
typeInfo.typeName,
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
const rawTypeData = typeInfo.typeData;
|
|
751
|
+
const typeData = this.schemaParserFabric.schemaFormatters.base[
|
|
752
|
+
rawTypeData.type
|
|
753
|
+
]
|
|
754
|
+
? this.schemaParserFabric.schemaFormatters.base[rawTypeData.type](
|
|
755
|
+
rawTypeData,
|
|
756
|
+
)
|
|
757
|
+
: rawTypeData;
|
|
758
|
+
let { typeIdentifier, name: originalName, content, description } = typeData;
|
|
759
|
+
const name = this.typeNameFormatter.format(originalName);
|
|
760
|
+
|
|
761
|
+
if (name === null) return null;
|
|
762
|
+
|
|
763
|
+
const preparedModelType = {
|
|
764
|
+
...typeData,
|
|
765
|
+
typeIdentifier,
|
|
766
|
+
name,
|
|
767
|
+
description,
|
|
768
|
+
$content: rawTypeData.content,
|
|
769
|
+
rawContent: rawTypeData.content,
|
|
770
|
+
content: content,
|
|
771
|
+
typeData,
|
|
772
|
+
};
|
|
773
|
+
|
|
774
|
+
typeInfo.$prepared = preparedModelType;
|
|
775
|
+
|
|
776
|
+
return preparedModelType;
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
/**
|
|
780
|
+
*
|
|
781
|
+
* @param configuration
|
|
782
|
+
* @returns {Promise<TranslatorIO[]>}
|
|
783
|
+
*/
|
|
784
|
+
generateOutputFiles = async ({ configuration }) => {
|
|
785
|
+
const { modular, templatesToRender } = this.config;
|
|
786
|
+
|
|
787
|
+
const output = modular
|
|
788
|
+
? await this.createMultipleFileInfos(templatesToRender, configuration)
|
|
789
|
+
: await this.createSingleFileInfo(templatesToRender, configuration);
|
|
790
|
+
|
|
791
|
+
if (!_.isEmpty(configuration.extraTemplates)) {
|
|
792
|
+
for (const extraTemplate of configuration.extraTemplates) {
|
|
793
|
+
const content = this.templatesWorker.renderTemplate(
|
|
794
|
+
this.fileSystem.getFileContent(extraTemplate.path),
|
|
795
|
+
configuration,
|
|
796
|
+
);
|
|
797
|
+
output.push(
|
|
798
|
+
...(await this.createOutputFileInfo(
|
|
799
|
+
configuration,
|
|
800
|
+
extraTemplate.name,
|
|
801
|
+
content,
|
|
802
|
+
)),
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
return output.filter((fileInfo) => !!fileInfo && !!fileInfo.fileContent);
|
|
808
|
+
};
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* @param templatesToRender
|
|
812
|
+
* @param configuration
|
|
813
|
+
* @returns {Promise<TranslatorIO[]>}
|
|
814
|
+
*/
|
|
815
|
+
createMultipleFileInfos = async (templatesToRender, configuration) => {
|
|
816
|
+
const { routes } = configuration;
|
|
817
|
+
const { fileNames, generateRouteTypes, generateClient } =
|
|
818
|
+
configuration.config;
|
|
819
|
+
/**
|
|
820
|
+
* @type {TranslatorIO[]}
|
|
821
|
+
*/
|
|
822
|
+
const modularApiFileInfos = [];
|
|
823
|
+
|
|
824
|
+
if (routes.$outOfModule) {
|
|
825
|
+
if (generateRouteTypes) {
|
|
826
|
+
const outOfModuleRouteContent = this.templatesWorker.renderTemplate(
|
|
827
|
+
templatesToRender.routeTypes,
|
|
828
|
+
{
|
|
829
|
+
...configuration,
|
|
830
|
+
route: configuration.routes.$outOfModule,
|
|
831
|
+
},
|
|
832
|
+
);
|
|
833
|
+
|
|
834
|
+
modularApiFileInfos.push(
|
|
835
|
+
...(await this.createOutputFileInfo(
|
|
836
|
+
configuration,
|
|
837
|
+
fileNames.outOfModuleApi,
|
|
838
|
+
outOfModuleRouteContent,
|
|
839
|
+
)),
|
|
840
|
+
);
|
|
841
|
+
}
|
|
842
|
+
if (generateClient) {
|
|
843
|
+
const outOfModuleApiContent = this.templatesWorker.renderTemplate(
|
|
844
|
+
templatesToRender.api,
|
|
845
|
+
{
|
|
846
|
+
...configuration,
|
|
847
|
+
route: configuration.routes.$outOfModule,
|
|
848
|
+
},
|
|
849
|
+
);
|
|
850
|
+
|
|
851
|
+
modularApiFileInfos.push(
|
|
852
|
+
...(await this.createOutputFileInfo(
|
|
853
|
+
configuration,
|
|
854
|
+
fileNames.outOfModuleApi,
|
|
855
|
+
outOfModuleApiContent,
|
|
856
|
+
)),
|
|
857
|
+
);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
if (routes.combined) {
|
|
862
|
+
for (const route of routes.combined) {
|
|
863
|
+
if (generateRouteTypes) {
|
|
864
|
+
const routeModuleContent = this.templatesWorker.renderTemplate(
|
|
865
|
+
templatesToRender.routeTypes,
|
|
866
|
+
{
|
|
867
|
+
...configuration,
|
|
868
|
+
route,
|
|
869
|
+
},
|
|
870
|
+
);
|
|
871
|
+
|
|
872
|
+
modularApiFileInfos.push(
|
|
873
|
+
...(await this.createOutputFileInfo(
|
|
874
|
+
configuration,
|
|
875
|
+
pascalCase(`${route.moduleName}_Route`),
|
|
876
|
+
routeModuleContent,
|
|
877
|
+
)),
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
if (generateClient) {
|
|
882
|
+
const apiModuleContent = this.templatesWorker.renderTemplate(
|
|
883
|
+
templatesToRender.api,
|
|
884
|
+
{
|
|
885
|
+
...configuration,
|
|
886
|
+
route,
|
|
887
|
+
},
|
|
888
|
+
);
|
|
889
|
+
|
|
890
|
+
modularApiFileInfos.push(
|
|
891
|
+
...(await this.createOutputFileInfo(
|
|
892
|
+
configuration,
|
|
893
|
+
pascalCase(route.moduleName),
|
|
894
|
+
apiModuleContent,
|
|
895
|
+
)),
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
return [
|
|
902
|
+
...(await this.createOutputFileInfo(
|
|
903
|
+
configuration,
|
|
904
|
+
fileNames.dataContracts,
|
|
905
|
+
this.templatesWorker.renderTemplate(
|
|
906
|
+
templatesToRender.dataContracts,
|
|
907
|
+
configuration,
|
|
908
|
+
),
|
|
909
|
+
)),
|
|
910
|
+
...(generateClient
|
|
911
|
+
? await this.createOutputFileInfo(
|
|
912
|
+
configuration,
|
|
913
|
+
fileNames.httpClient,
|
|
914
|
+
this.templatesWorker.renderTemplate(
|
|
915
|
+
templatesToRender.httpClient,
|
|
916
|
+
configuration,
|
|
917
|
+
),
|
|
918
|
+
)
|
|
919
|
+
: []),
|
|
920
|
+
...modularApiFileInfos,
|
|
921
|
+
];
|
|
922
|
+
};
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
*
|
|
926
|
+
* @param templatesToRender
|
|
927
|
+
* @param configuration
|
|
928
|
+
* @returns {Promise<TranslatorIO[]>}
|
|
929
|
+
*/
|
|
930
|
+
createSingleFileInfo = async (templatesToRender, configuration) => {
|
|
931
|
+
const { generateRouteTypes, generateClient } = configuration.config;
|
|
932
|
+
|
|
933
|
+
return await this.createOutputFileInfo(
|
|
934
|
+
configuration,
|
|
935
|
+
configuration.fileName,
|
|
936
|
+
_.compact([
|
|
937
|
+
this.templatesWorker.renderTemplate(
|
|
938
|
+
templatesToRender.dataContracts,
|
|
939
|
+
configuration,
|
|
940
|
+
),
|
|
941
|
+
generateRouteTypes &&
|
|
942
|
+
this.templatesWorker.renderTemplate(
|
|
943
|
+
templatesToRender.routeTypes,
|
|
944
|
+
configuration,
|
|
945
|
+
),
|
|
946
|
+
generateClient &&
|
|
947
|
+
this.templatesWorker.renderTemplate(
|
|
948
|
+
templatesToRender.httpClient,
|
|
949
|
+
configuration,
|
|
950
|
+
),
|
|
951
|
+
generateClient &&
|
|
952
|
+
this.templatesWorker.renderTemplate(
|
|
953
|
+
templatesToRender.api,
|
|
954
|
+
configuration,
|
|
955
|
+
),
|
|
956
|
+
]).join("\n"),
|
|
957
|
+
);
|
|
958
|
+
};
|
|
959
|
+
|
|
960
|
+
/**
|
|
961
|
+
*
|
|
962
|
+
* @param configuration
|
|
963
|
+
* @param fileNameFull
|
|
964
|
+
* @param content
|
|
965
|
+
* @returns {Promise<TranslatorIO[]>}
|
|
966
|
+
*/
|
|
967
|
+
createOutputFileInfo = async (configuration, fileNameFull, content) => {
|
|
968
|
+
const fileName = this.fileSystem.cropExtension(fileNameFull);
|
|
969
|
+
const fileExtension = ts.Extension.Ts;
|
|
970
|
+
|
|
971
|
+
if (configuration.translateToJavaScript) {
|
|
972
|
+
this.logger.debug("using js translator for", fileName);
|
|
973
|
+
return await this.javascriptTranslator.translate({
|
|
974
|
+
fileName: fileName,
|
|
975
|
+
fileExtension: fileExtension,
|
|
976
|
+
fileContent: content,
|
|
977
|
+
});
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
if (configuration.customTranslator) {
|
|
981
|
+
this.logger.debug("using custom translator for", fileName);
|
|
982
|
+
return await configuration.customTranslator.translate({
|
|
983
|
+
fileName: fileName,
|
|
984
|
+
fileExtension: fileExtension,
|
|
985
|
+
fileContent: content,
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
this.logger.debug("generating output for", `${fileName}${fileExtension}`);
|
|
990
|
+
|
|
991
|
+
return [
|
|
992
|
+
{
|
|
993
|
+
fileName,
|
|
994
|
+
fileExtension: fileExtension,
|
|
995
|
+
fileContent: await this.codeFormatter.formatCode(content),
|
|
996
|
+
},
|
|
997
|
+
];
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
createApiConfig = (swaggerSchema) => {
|
|
1001
|
+
const { info, servers, host, basePath, externalDocs, tags } = swaggerSchema;
|
|
1002
|
+
const server = servers?.[0] || { url: "" };
|
|
1003
|
+
const { title = "No title", version } = info || {};
|
|
1004
|
+
const { url: serverUrl } = server;
|
|
1005
|
+
|
|
1006
|
+
return {
|
|
1007
|
+
info: info || {},
|
|
1008
|
+
servers: servers || [],
|
|
1009
|
+
basePath,
|
|
1010
|
+
host,
|
|
1011
|
+
externalDocs: _.merge(
|
|
1012
|
+
{
|
|
1013
|
+
url: "",
|
|
1014
|
+
description: "",
|
|
1015
|
+
},
|
|
1016
|
+
externalDocs,
|
|
1017
|
+
),
|
|
1018
|
+
tags: _.compact(tags),
|
|
1019
|
+
baseUrl: serverUrl,
|
|
1020
|
+
title,
|
|
1021
|
+
version,
|
|
1022
|
+
};
|
|
1023
|
+
};
|
|
1024
|
+
|
|
1025
|
+
injectClassInstance = (key, value) => {
|
|
1026
|
+
this[key] = value;
|
|
1027
|
+
PATCHABLE_INSTANCES.forEach((instanceKey) => {
|
|
1028
|
+
if (instanceKey !== key && key in this[instanceKey]) {
|
|
1029
|
+
this[instanceKey][key] = value;
|
|
1030
|
+
}
|
|
1031
|
+
});
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
type HttpClientType = "axios" | "fetch";
|
|
1036
|
+
|
|
1037
|
+
interface GenerateApiParamsBase {
|
|
1038
|
+
/**
|
|
1039
|
+
* default 'api.ts'
|
|
1040
|
+
*/
|
|
1041
|
+
name?: string;
|
|
1042
|
+
|
|
1043
|
+
/**
|
|
1044
|
+
* name of the main exported class
|
|
1045
|
+
*/
|
|
1046
|
+
apiClassName?: string;
|
|
1047
|
+
|
|
1048
|
+
/**
|
|
1049
|
+
* path to folder where will be located the created api module.
|
|
1050
|
+
*
|
|
1051
|
+
* may set to `false` to skip writing content to disk. in this case,
|
|
1052
|
+
* you may access the `files` on the return value.
|
|
1053
|
+
*/
|
|
1054
|
+
output?: string | false;
|
|
1055
|
+
|
|
1056
|
+
/**
|
|
1057
|
+
* path to folder containing templates (default: ./src/templates)
|
|
1058
|
+
*/
|
|
1059
|
+
templates?: string;
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* generate all "enum" types as union types (T1 | T2 | TN) (default: false)
|
|
1063
|
+
*/
|
|
1064
|
+
generateUnionEnums?: boolean;
|
|
1065
|
+
|
|
1066
|
+
/**
|
|
1067
|
+
* generate type definitions for API routes (default: false)
|
|
1068
|
+
*/
|
|
1069
|
+
generateRouteTypes?: boolean;
|
|
1070
|
+
|
|
1071
|
+
/**
|
|
1072
|
+
* do not generate an API class
|
|
1073
|
+
*/
|
|
1074
|
+
generateClient?: boolean;
|
|
1075
|
+
/**
|
|
1076
|
+
* generated http client type
|
|
1077
|
+
*/
|
|
1078
|
+
httpClientType?: HttpClientType;
|
|
1079
|
+
/**
|
|
1080
|
+
* use "default" response status code as success response too.
|
|
1081
|
+
* some swagger schemas use "default" response status code as success response type by default.
|
|
1082
|
+
*/
|
|
1083
|
+
defaultResponseAsSuccess?: boolean;
|
|
1084
|
+
|
|
1085
|
+
/**
|
|
1086
|
+
* generate additional information about request responses
|
|
1087
|
+
* also add typings for bad responses
|
|
1088
|
+
*/
|
|
1089
|
+
generateResponses?: boolean;
|
|
1090
|
+
|
|
1091
|
+
/**
|
|
1092
|
+
* unwrap the data item from the response
|
|
1093
|
+
*/
|
|
1094
|
+
unwrapResponseData?: boolean;
|
|
1095
|
+
|
|
1096
|
+
/**
|
|
1097
|
+
* sort data contracts in alphabetical order
|
|
1098
|
+
*/
|
|
1099
|
+
sortTypes?: boolean;
|
|
1100
|
+
|
|
1101
|
+
/**
|
|
1102
|
+
* sort routes in alphabetical order
|
|
1103
|
+
*/
|
|
1104
|
+
sortRoutes?: boolean;
|
|
1105
|
+
|
|
1106
|
+
/**
|
|
1107
|
+
* generate js api module with declaration file (default: false)
|
|
1108
|
+
*/
|
|
1109
|
+
toJS?: boolean;
|
|
1110
|
+
|
|
1111
|
+
/**
|
|
1112
|
+
* determines which path index should be used for routes separation
|
|
1113
|
+
*/
|
|
1114
|
+
moduleNameIndex?: number;
|
|
1115
|
+
/**
|
|
1116
|
+
* users operation's first tag for route separation
|
|
1117
|
+
*/
|
|
1118
|
+
moduleNameFirstTag?: boolean;
|
|
1119
|
+
/**
|
|
1120
|
+
* disabled SSL check
|
|
1121
|
+
*/
|
|
1122
|
+
disableStrictSSL?: boolean;
|
|
1123
|
+
/**
|
|
1124
|
+
* disabled Proxy
|
|
1125
|
+
*/
|
|
1126
|
+
disableProxy?: boolean;
|
|
1127
|
+
/**
|
|
1128
|
+
* generate separated files for http client, data contracts, and routes (default: false)
|
|
1129
|
+
*/
|
|
1130
|
+
modular?: boolean;
|
|
1131
|
+
/**
|
|
1132
|
+
* extract request params to data contract (Also combine path params and query params into one object)
|
|
1133
|
+
*/
|
|
1134
|
+
extractRequestParams?: boolean;
|
|
1135
|
+
/**
|
|
1136
|
+
* extract request body type to data contract
|
|
1137
|
+
*/
|
|
1138
|
+
extractRequestBody?: boolean;
|
|
1139
|
+
/**
|
|
1140
|
+
* extract response body type to data contract
|
|
1141
|
+
*/
|
|
1142
|
+
extractResponseBody?: boolean;
|
|
1143
|
+
/**
|
|
1144
|
+
* extract response error type to data contract
|
|
1145
|
+
*/
|
|
1146
|
+
extractResponseError?: boolean;
|
|
1147
|
+
/**
|
|
1148
|
+
* prettier configuration
|
|
1149
|
+
*/
|
|
1150
|
+
prettier?: object;
|
|
1151
|
+
/**
|
|
1152
|
+
* Output only errors to console (default: false)
|
|
1153
|
+
*/
|
|
1154
|
+
silent?: boolean;
|
|
1155
|
+
/**
|
|
1156
|
+
* default type for empty response schema (default: "void")
|
|
1157
|
+
*/
|
|
1158
|
+
defaultResponseType?: string;
|
|
1159
|
+
/**
|
|
1160
|
+
* Ability to send HttpClient instance to Api constructor
|
|
1161
|
+
*/
|
|
1162
|
+
singleHttpClient?: boolean;
|
|
1163
|
+
cleanOutput?: boolean;
|
|
1164
|
+
enumNamesAsValues?: boolean;
|
|
1165
|
+
|
|
1166
|
+
hooks?: Partial<Hooks>;
|
|
1167
|
+
/**
|
|
1168
|
+
* extra templates
|
|
1169
|
+
*/
|
|
1170
|
+
extraTemplates?: { name: string; path: string }[];
|
|
1171
|
+
|
|
1172
|
+
/**
|
|
1173
|
+
* fix up small errors in the swagger source definition
|
|
1174
|
+
*/
|
|
1175
|
+
patch?: boolean;
|
|
1176
|
+
/**
|
|
1177
|
+
* authorization token
|
|
1178
|
+
*/
|
|
1179
|
+
authorizationToken?: string;
|
|
1180
|
+
/**
|
|
1181
|
+
* generate readonly properties (default: false)
|
|
1182
|
+
*/
|
|
1183
|
+
addReadonly?: boolean;
|
|
1184
|
+
|
|
1185
|
+
primitiveTypeConstructs?: (
|
|
1186
|
+
struct: PrimitiveTypeStruct,
|
|
1187
|
+
) => Partial<PrimitiveTypeStruct>;
|
|
1188
|
+
|
|
1189
|
+
codeGenConstructs?: (struct: CodeGenConstruct) => Partial<CodeGenConstruct>;
|
|
1190
|
+
|
|
1191
|
+
/** extract all enums from nested types\interfaces to `enum` construction */
|
|
1192
|
+
extractEnums?: boolean;
|
|
1193
|
+
|
|
1194
|
+
/** prefix string value needed to fix invalid type names (default: 'Type') */
|
|
1195
|
+
fixInvalidTypeNamePrefix?: string;
|
|
1196
|
+
|
|
1197
|
+
/** prefix string value needed to fix invalid enum keys (default: 'Value') */
|
|
1198
|
+
fixInvalidEnumKeyPrefix?: string;
|
|
1199
|
+
|
|
1200
|
+
/** prefix string value for enum keys */
|
|
1201
|
+
enumKeyPrefix?: string;
|
|
1202
|
+
|
|
1203
|
+
/** suffix string value for enum keys */
|
|
1204
|
+
enumKeySuffix?: string;
|
|
1205
|
+
|
|
1206
|
+
/** prefix string value for type names */
|
|
1207
|
+
typePrefix?: string;
|
|
1208
|
+
|
|
1209
|
+
/** suffix string value for type names */
|
|
1210
|
+
typeSuffix?: string;
|
|
1211
|
+
|
|
1212
|
+
/** extra configuration for extracting type names operations */
|
|
1213
|
+
extractingOptions?: Partial<ExtractingOptions>;
|
|
1214
|
+
|
|
1215
|
+
/** configuration for fetching swagger schema requests */
|
|
1216
|
+
requestOptions?: null | Partial<RequestInit>;
|
|
1217
|
+
|
|
1218
|
+
/** ts compiler configuration object (for --to-js option) */
|
|
1219
|
+
compilerTsConfig?: Record<string, any>;
|
|
1220
|
+
|
|
1221
|
+
/**
|
|
1222
|
+
* custom ts->* translator
|
|
1223
|
+
* do not use constructor args, it can break functionality of this property, just send class reference
|
|
1224
|
+
*
|
|
1225
|
+
* @example
|
|
1226
|
+
* ```ts
|
|
1227
|
+
* import { Translator } from "swagger-typescript-api/src/translators/translator";
|
|
1228
|
+
*
|
|
1229
|
+
* class MyTranslator extends Translator {
|
|
1230
|
+
*
|
|
1231
|
+
* translate({ fileName, fileExtension, fileContent }) {
|
|
1232
|
+
* this.codeFormatter.format()
|
|
1233
|
+
* this.config.
|
|
1234
|
+
* this.logger.
|
|
1235
|
+
*
|
|
1236
|
+
* return [
|
|
1237
|
+
* {
|
|
1238
|
+
* fileName,
|
|
1239
|
+
* fileExtension,
|
|
1240
|
+
* fileContent,
|
|
1241
|
+
* }
|
|
1242
|
+
* ]
|
|
1243
|
+
* }
|
|
1244
|
+
* }
|
|
1245
|
+
* ```
|
|
1246
|
+
*/
|
|
1247
|
+
customTranslator?: new () => typeof Translator;
|
|
1248
|
+
/** fallback name for enum key resolver */
|
|
1249
|
+
enumKeyResolverName?: string;
|
|
1250
|
+
/** fallback name for type name resolver */
|
|
1251
|
+
typeNameResolverName?: string;
|
|
1252
|
+
/** fallback name for specific arg name resolver */
|
|
1253
|
+
specificArgNameResolverName?: string;
|
|
1254
|
+
schemaParsers?: {
|
|
1255
|
+
complexOneOf?: MonoSchemaParser;
|
|
1256
|
+
complexAllOf?: MonoSchemaParser;
|
|
1257
|
+
complexAnyOf?: MonoSchemaParser;
|
|
1258
|
+
complexNot?: MonoSchemaParser;
|
|
1259
|
+
enum?: MonoSchemaParser;
|
|
1260
|
+
object?: MonoSchemaParser;
|
|
1261
|
+
complex?: MonoSchemaParser;
|
|
1262
|
+
primitive?: MonoSchemaParser;
|
|
1263
|
+
discriminator?: MonoSchemaParser;
|
|
1264
|
+
array?: MonoSchemaParser;
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
type CodeGenConstruct = {
|
|
1269
|
+
Keyword: {
|
|
1270
|
+
Number: string;
|
|
1271
|
+
String: string;
|
|
1272
|
+
Boolean: string;
|
|
1273
|
+
Any: string;
|
|
1274
|
+
Void: string;
|
|
1275
|
+
Unknown: string;
|
|
1276
|
+
Null: string;
|
|
1277
|
+
Undefined: string;
|
|
1278
|
+
Object: string;
|
|
1279
|
+
File: string;
|
|
1280
|
+
Date: string;
|
|
1281
|
+
Type: string;
|
|
1282
|
+
Enum: string;
|
|
1283
|
+
Interface: string;
|
|
1284
|
+
Array: string;
|
|
1285
|
+
Record: string;
|
|
1286
|
+
Intersection: string;
|
|
1287
|
+
Union: string;
|
|
1288
|
+
};
|
|
1289
|
+
CodeGenKeyword: {
|
|
1290
|
+
UtilRequiredKeys: string;
|
|
1291
|
+
};
|
|
1292
|
+
ArrayType: (content: any) => string;
|
|
1293
|
+
StringValue: (content: any) => string;
|
|
1294
|
+
BooleanValue: (content: any) => string;
|
|
1295
|
+
NumberValue: (content: any) => string;
|
|
1296
|
+
NullValue: (content: any) => string;
|
|
1297
|
+
UnionType: (content: any) => string;
|
|
1298
|
+
ExpressionGroup: (content: any) => string;
|
|
1299
|
+
IntersectionType: (content: any) => string;
|
|
1300
|
+
RecordType: (content: any) => string;
|
|
1301
|
+
TypeField: (content: any) => string;
|
|
1302
|
+
InterfaceDynamicField: (content: any) => string;
|
|
1303
|
+
EnumField: (content: any) => string;
|
|
1304
|
+
EnumFieldsWrapper: (content: any) => string;
|
|
1305
|
+
ObjectWrapper: (content: any) => string;
|
|
1306
|
+
MultilineComment: (content: any) => string;
|
|
1307
|
+
TypeWithGeneric: (content: any) => string;
|
|
1308
|
+
};
|
|
1309
|
+
|
|
1310
|
+
type PrimitiveTypeStructValue =
|
|
1311
|
+
| string
|
|
1312
|
+
| ((
|
|
1313
|
+
schema: Record<string, any>,
|
|
1314
|
+
parser: SchemaParser,
|
|
1315
|
+
) => string);
|
|
1316
|
+
|
|
1317
|
+
type PrimitiveTypeStruct = Record<
|
|
1318
|
+
"integer" | "number" | "boolean" | "object" | "file" | "string" | "array",
|
|
1319
|
+
| string
|
|
1320
|
+
| ({ $default: PrimitiveTypeStructValue } & Record<
|
|
1321
|
+
string,
|
|
1322
|
+
PrimitiveTypeStructValue
|
|
1323
|
+
>)
|
|
1324
|
+
>;
|
|
1325
|
+
|
|
1326
|
+
interface GenerateApiParamsFromPath extends GenerateApiParamsBase {
|
|
1327
|
+
/**
|
|
1328
|
+
* path to swagger schema
|
|
1329
|
+
*/
|
|
1330
|
+
input: string;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
interface GenerateApiParamsFromUrl extends GenerateApiParamsBase {
|
|
1334
|
+
/**
|
|
1335
|
+
* url to swagger schema
|
|
1336
|
+
*/
|
|
1337
|
+
url: string;
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
interface GenerateApiParamsFromSpecLiteral extends GenerateApiParamsBase {
|
|
1341
|
+
/**
|
|
1342
|
+
* swagger schema JSON
|
|
1343
|
+
*/
|
|
1344
|
+
spec: swagger_schema_official.Spec;
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
type GenerateApiParams =
|
|
1348
|
+
| GenerateApiParamsFromPath
|
|
1349
|
+
| GenerateApiParamsFromUrl
|
|
1350
|
+
| GenerateApiParamsFromSpecLiteral;
|
|
1351
|
+
|
|
1352
|
+
type BuildRouteParam = {
|
|
1353
|
+
/** {bar} */
|
|
1354
|
+
$match: string;
|
|
1355
|
+
name: string;
|
|
1356
|
+
required: boolean;
|
|
1357
|
+
type: "string";
|
|
1358
|
+
description: string;
|
|
1359
|
+
schema: {
|
|
1360
|
+
type: string;
|
|
1361
|
+
};
|
|
1362
|
+
in: "path" | "query";
|
|
1363
|
+
};
|
|
1364
|
+
|
|
1365
|
+
type BuildRoutePath = {
|
|
1366
|
+
/** /foo/{bar}/baz */
|
|
1367
|
+
originalRoute: string;
|
|
1368
|
+
/** /foo/${bar}/baz */
|
|
1369
|
+
route: string;
|
|
1370
|
+
pathParams: BuildRouteParam[];
|
|
1371
|
+
queryParams: BuildRouteParam[];
|
|
1372
|
+
};
|
|
1373
|
+
|
|
1374
|
+
interface Hooks {
|
|
1375
|
+
/** calls before parse\process route path */
|
|
1376
|
+
onPreBuildRoutePath: (routePath: string) => string | void;
|
|
1377
|
+
/** calls after parse\process route path */
|
|
1378
|
+
onBuildRoutePath: (data: BuildRoutePath) => BuildRoutePath | void;
|
|
1379
|
+
/** calls before insert path param name into string path interpolation */
|
|
1380
|
+
onInsertPathParam: (
|
|
1381
|
+
paramName: string,
|
|
1382
|
+
index: number,
|
|
1383
|
+
arr: BuildRouteParam[],
|
|
1384
|
+
resultRoute: string,
|
|
1385
|
+
) => string | void;
|
|
1386
|
+
/** calls after parse schema component */
|
|
1387
|
+
onCreateComponent: (component: SchemaComponent) => SchemaComponent | void;
|
|
1388
|
+
/** calls before parse any kind of schema */
|
|
1389
|
+
onPreParseSchema: (
|
|
1390
|
+
originalSchema: any,
|
|
1391
|
+
typeName: string,
|
|
1392
|
+
schemaType: string,
|
|
1393
|
+
) => any;
|
|
1394
|
+
/** calls after parse any kind of schema */
|
|
1395
|
+
onParseSchema: (originalSchema: any, parsedSchema: any) => any | void;
|
|
1396
|
+
/** calls after parse route (return type: customized route (ParsedRoute), nothing change (void), false (ignore this route)) */
|
|
1397
|
+
onCreateRoute: (routeData: ParsedRoute) => ParsedRoute | void | false;
|
|
1398
|
+
/** Start point of work this tool (after fetching schema) */
|
|
1399
|
+
onInit?: <C extends GenerateApiConfiguration["config"]>(
|
|
1400
|
+
configuration: C,
|
|
1401
|
+
codeGenProcess: CodeGenProcess,
|
|
1402
|
+
) => C | void;
|
|
1403
|
+
/** customize configuration object before sending it to ETA templates */
|
|
1404
|
+
onPrepareConfig?: <C extends GenerateApiConfiguration>(
|
|
1405
|
+
currentConfiguration: C,
|
|
1406
|
+
) => C | void;
|
|
1407
|
+
/** customize route name as you need */
|
|
1408
|
+
onCreateRouteName?: (
|
|
1409
|
+
routeNameInfo: RouteNameInfo,
|
|
1410
|
+
rawRouteInfo: RawRouteInfo,
|
|
1411
|
+
) => RouteNameInfo | void;
|
|
1412
|
+
/** customize request params (path params, query params) */
|
|
1413
|
+
onCreateRequestParams?: (
|
|
1414
|
+
rawType: SchemaComponent["rawTypeData"],
|
|
1415
|
+
) => SchemaComponent["rawTypeData"] | void;
|
|
1416
|
+
/** customize name of model type */
|
|
1417
|
+
onFormatTypeName?: (
|
|
1418
|
+
typeName: string,
|
|
1419
|
+
rawTypeName?: string,
|
|
1420
|
+
schemaType?: "type-name" | "enum-key",
|
|
1421
|
+
) => string | void;
|
|
1422
|
+
/** customize name of route (operationId), you can do it with using onCreateRouteName too */
|
|
1423
|
+
onFormatRouteName?: (
|
|
1424
|
+
routeInfo: RawRouteInfo,
|
|
1425
|
+
templateRouteName: string,
|
|
1426
|
+
) => string | void;
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
type RouteNameRouteInfo = {};
|
|
1430
|
+
|
|
1431
|
+
type RouteNameInfo = {
|
|
1432
|
+
usage: string;
|
|
1433
|
+
original: string;
|
|
1434
|
+
duplicate: boolean;
|
|
1435
|
+
};
|
|
1436
|
+
|
|
1437
|
+
type SchemaTypePrimitiveContent = {
|
|
1438
|
+
$parsedSchema: boolean;
|
|
1439
|
+
schemaType: string;
|
|
1440
|
+
type: string;
|
|
1441
|
+
typeIdentifier: string;
|
|
1442
|
+
name?: any;
|
|
1443
|
+
description: string;
|
|
1444
|
+
content: string;
|
|
1445
|
+
};
|
|
1446
|
+
|
|
1447
|
+
type SchemaTypeObjectContent = {
|
|
1448
|
+
$$raw: {
|
|
1449
|
+
type: string;
|
|
1450
|
+
required: boolean;
|
|
1451
|
+
$parsed: SchemaTypePrimitiveContent;
|
|
1452
|
+
};
|
|
1453
|
+
isRequired: boolean;
|
|
1454
|
+
field: string;
|
|
1455
|
+
}[];
|
|
1456
|
+
|
|
1457
|
+
type SchemaTypeEnumContent = {
|
|
1458
|
+
key: string;
|
|
1459
|
+
type: string;
|
|
1460
|
+
value: string;
|
|
1461
|
+
};
|
|
1462
|
+
|
|
1463
|
+
interface ParsedSchema<C> {
|
|
1464
|
+
$parsedSchema: boolean;
|
|
1465
|
+
schemaType: string;
|
|
1466
|
+
type: string;
|
|
1467
|
+
typeIdentifier: string;
|
|
1468
|
+
name: string;
|
|
1469
|
+
description?: string;
|
|
1470
|
+
allFieldsAreOptional?: boolean;
|
|
1471
|
+
content: C;
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
interface PathArgInfo {
|
|
1475
|
+
name: string;
|
|
1476
|
+
optional: boolean;
|
|
1477
|
+
type: string;
|
|
1478
|
+
description?: string;
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
interface SchemaComponent {
|
|
1482
|
+
$ref: string;
|
|
1483
|
+
typeName: string;
|
|
1484
|
+
rawTypeData?: {
|
|
1485
|
+
type: string;
|
|
1486
|
+
required?: string[];
|
|
1487
|
+
properties?: Record<
|
|
1488
|
+
string,
|
|
1489
|
+
{
|
|
1490
|
+
name?: string;
|
|
1491
|
+
type: string;
|
|
1492
|
+
required: boolean;
|
|
1493
|
+
$parsed?: SchemaTypePrimitiveContent;
|
|
1494
|
+
}
|
|
1495
|
+
>;
|
|
1496
|
+
discriminator?: {
|
|
1497
|
+
propertyName?: string;
|
|
1498
|
+
};
|
|
1499
|
+
$parsed: ParsedSchema<
|
|
1500
|
+
| SchemaTypeObjectContent
|
|
1501
|
+
| SchemaTypeEnumContent
|
|
1502
|
+
| SchemaTypePrimitiveContent
|
|
1503
|
+
>;
|
|
1504
|
+
};
|
|
1505
|
+
componentName: "schemas" | "paths";
|
|
1506
|
+
typeData: ParsedSchema<
|
|
1507
|
+
SchemaTypeObjectContent | SchemaTypeEnumContent | SchemaTypePrimitiveContent
|
|
1508
|
+
> | null;
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
declare enum RequestContentKind {
|
|
1512
|
+
JSON = "JSON",
|
|
1513
|
+
URL_ENCODED = "URL_ENCODED",
|
|
1514
|
+
FORM_DATA = "FORM_DATA",
|
|
1515
|
+
IMAGE = "IMAGE",
|
|
1516
|
+
OTHER = "OTHER",
|
|
1517
|
+
TEXT = "TEXT",
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
interface RequestResponseInfo {
|
|
1521
|
+
contentTypes: string[];
|
|
1522
|
+
contentKind: RequestContentKind;
|
|
1523
|
+
type: string;
|
|
1524
|
+
description: string;
|
|
1525
|
+
status: string | number;
|
|
1526
|
+
isSuccess: boolean;
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
type RawRouteInfo = {
|
|
1530
|
+
operationId: string;
|
|
1531
|
+
method: string;
|
|
1532
|
+
route: string;
|
|
1533
|
+
moduleName: string;
|
|
1534
|
+
responsesTypes: RequestResponseInfo[];
|
|
1535
|
+
description?: string;
|
|
1536
|
+
tags?: string[];
|
|
1537
|
+
summary?: string;
|
|
1538
|
+
responses?: swagger_schema_official.Spec["responses"];
|
|
1539
|
+
produces?: string[];
|
|
1540
|
+
requestBody?: object;
|
|
1541
|
+
consumes?: string[];
|
|
1542
|
+
};
|
|
1543
|
+
|
|
1544
|
+
interface ParsedRoute {
|
|
1545
|
+
id: string;
|
|
1546
|
+
jsDocLines: string;
|
|
1547
|
+
namespace: string;
|
|
1548
|
+
request: Request;
|
|
1549
|
+
response: Response;
|
|
1550
|
+
routeName: RouteNameInfo;
|
|
1551
|
+
raw: RawRouteInfo;
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
type ModelType = {
|
|
1555
|
+
typeIdentifier: string;
|
|
1556
|
+
name: string;
|
|
1557
|
+
rawContent: string;
|
|
1558
|
+
description: string;
|
|
1559
|
+
content: string;
|
|
1560
|
+
};
|
|
1561
|
+
|
|
1562
|
+
declare enum SCHEMA_TYPES {
|
|
1563
|
+
ARRAY = "array",
|
|
1564
|
+
OBJECT = "object",
|
|
1565
|
+
ENUM = "enum",
|
|
1566
|
+
REF = "$ref",
|
|
1567
|
+
PRIMITIVE = "primitive",
|
|
1568
|
+
COMPLEX = "complex",
|
|
1569
|
+
COMPLEX_ONE_OF = "oneOf",
|
|
1570
|
+
COMPLEX_ANY_OF = "anyOf",
|
|
1571
|
+
COMPLEX_ALL_OF = "allOf",
|
|
1572
|
+
COMPLEX_NOT = "not",
|
|
1573
|
+
COMPLEX_UNKNOWN = "__unknown",
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
type MAIN_SCHEMA_TYPES =
|
|
1577
|
+
| SCHEMA_TYPES.PRIMITIVE
|
|
1578
|
+
| SCHEMA_TYPES.OBJECT
|
|
1579
|
+
| SCHEMA_TYPES.ENUM;
|
|
1580
|
+
|
|
1581
|
+
type ExtractingOptions = {
|
|
1582
|
+
requestBodySuffix: string[];
|
|
1583
|
+
responseBodySuffix: string[];
|
|
1584
|
+
responseErrorSuffix: string[];
|
|
1585
|
+
requestParamsSuffix: string[];
|
|
1586
|
+
enumSuffix: string[];
|
|
1587
|
+
discriminatorMappingSuffix: string[];
|
|
1588
|
+
discriminatorAbstractPrefix: string[];
|
|
1589
|
+
requestBodyNameResolver: (
|
|
1590
|
+
name: string,
|
|
1591
|
+
reservedNames: string,
|
|
1592
|
+
) => string | undefined;
|
|
1593
|
+
responseBodyNameResolver: (
|
|
1594
|
+
name: string,
|
|
1595
|
+
reservedNames: string,
|
|
1596
|
+
) => string | undefined;
|
|
1597
|
+
responseErrorNameResolver: (
|
|
1598
|
+
name: string,
|
|
1599
|
+
reservedNames: string,
|
|
1600
|
+
) => string | undefined;
|
|
1601
|
+
requestParamsNameResolver: (
|
|
1602
|
+
name: string,
|
|
1603
|
+
reservedNames: string,
|
|
1604
|
+
) => string | undefined;
|
|
1605
|
+
enumNameResolver: (name: string, reservedNames: string) => string | undefined;
|
|
1606
|
+
discriminatorMappingNameResolver: (
|
|
1607
|
+
name: string,
|
|
1608
|
+
reservedNames: string,
|
|
1609
|
+
) => string | undefined;
|
|
1610
|
+
discriminatorAbstractResolver: (
|
|
1611
|
+
name: string,
|
|
1612
|
+
reservedNames: string,
|
|
1613
|
+
) => string | undefined;
|
|
1614
|
+
};
|
|
1615
|
+
|
|
1616
|
+
interface GenerateApiConfiguration {
|
|
1617
|
+
apiConfig: {
|
|
1618
|
+
baseUrl: string;
|
|
1619
|
+
title: string;
|
|
1620
|
+
version: string;
|
|
1621
|
+
description: string[];
|
|
1622
|
+
hasDescription: boolean;
|
|
1623
|
+
};
|
|
1624
|
+
config: {
|
|
1625
|
+
input: string;
|
|
1626
|
+
output: string;
|
|
1627
|
+
url: string;
|
|
1628
|
+
spec: any;
|
|
1629
|
+
fileName: string;
|
|
1630
|
+
templatePaths: {
|
|
1631
|
+
/** `templates/base` */
|
|
1632
|
+
base: string;
|
|
1633
|
+
/** `templates/default` */
|
|
1634
|
+
default: string;
|
|
1635
|
+
/** `templates/modular` */
|
|
1636
|
+
modular: string;
|
|
1637
|
+
/** usage path if `--templates` option is not set */
|
|
1638
|
+
original: string;
|
|
1639
|
+
/** custom path to templates (`--templates`) */
|
|
1640
|
+
custom: string | null;
|
|
1641
|
+
};
|
|
1642
|
+
authorizationToken?: string;
|
|
1643
|
+
generateResponses: boolean;
|
|
1644
|
+
defaultResponseAsSuccess: boolean;
|
|
1645
|
+
generateRouteTypes: boolean;
|
|
1646
|
+
generateClient: boolean;
|
|
1647
|
+
generateUnionEnums: boolean;
|
|
1648
|
+
swaggerSchema: object;
|
|
1649
|
+
originalSchema: object;
|
|
1650
|
+
componentsMap: Record<string, SchemaComponent>;
|
|
1651
|
+
convertedFromSwagger2: boolean;
|
|
1652
|
+
moduleNameIndex: number;
|
|
1653
|
+
moduleNameFirstTag: boolean;
|
|
1654
|
+
extraTemplates: { name: string; path: string }[];
|
|
1655
|
+
disableStrictSSL: boolean;
|
|
1656
|
+
disableProxy: boolean;
|
|
1657
|
+
extractRequestParams: boolean;
|
|
1658
|
+
unwrapResponseData: boolean;
|
|
1659
|
+
sortTypes: boolean;
|
|
1660
|
+
sortRoutes: boolean;
|
|
1661
|
+
singleHttpClient: boolean;
|
|
1662
|
+
typePrefix: string;
|
|
1663
|
+
typeSuffix: string;
|
|
1664
|
+
enumKeyPrefix: string;
|
|
1665
|
+
enumKeySuffix: string;
|
|
1666
|
+
patch: boolean;
|
|
1667
|
+
cleanOutput: boolean;
|
|
1668
|
+
debug: boolean;
|
|
1669
|
+
anotherArrayType: boolean;
|
|
1670
|
+
extractRequestBody: boolean;
|
|
1671
|
+
httpClientType: "axios" | "fetch";
|
|
1672
|
+
addReadonly: boolean;
|
|
1673
|
+
extractResponseBody: boolean;
|
|
1674
|
+
extractResponseError: boolean;
|
|
1675
|
+
extractEnums: boolean;
|
|
1676
|
+
fixInvalidTypeNamePrefix: string;
|
|
1677
|
+
fixInvalidEnumKeyPrefix: string;
|
|
1678
|
+
defaultResponseType: string;
|
|
1679
|
+
toJS: boolean;
|
|
1680
|
+
disableThrowOnError: boolean;
|
|
1681
|
+
silent: boolean;
|
|
1682
|
+
hooks: Hooks;
|
|
1683
|
+
enumNamesAsValues: boolean;
|
|
1684
|
+
version: string;
|
|
1685
|
+
compilerTsConfig: Record<string, any>;
|
|
1686
|
+
enumKeyResolverName: string;
|
|
1687
|
+
typeNameResolverName: string;
|
|
1688
|
+
specificArgNameResolverName: string;
|
|
1689
|
+
/** do not use constructor args, it can break functionality of this property, just send class reference */
|
|
1690
|
+
customTranslator?: new (
|
|
1691
|
+
...args: never[]
|
|
1692
|
+
) => typeof Translator;
|
|
1693
|
+
internalTemplateOptions: {
|
|
1694
|
+
addUtilRequiredKeysType: boolean;
|
|
1695
|
+
};
|
|
1696
|
+
componentTypeNameResolver: typeof ComponentTypeNameResolver;
|
|
1697
|
+
fileNames: {
|
|
1698
|
+
dataContracts: string;
|
|
1699
|
+
routeTypes: string;
|
|
1700
|
+
httpClient: string;
|
|
1701
|
+
outOfModuleApi: string;
|
|
1702
|
+
};
|
|
1703
|
+
templatesToRender: {
|
|
1704
|
+
api: string;
|
|
1705
|
+
dataContracts: string;
|
|
1706
|
+
httpClient: string;
|
|
1707
|
+
routeTypes: string;
|
|
1708
|
+
routeName: string;
|
|
1709
|
+
dataContractJsDoc: string;
|
|
1710
|
+
interfaceDataContract: string;
|
|
1711
|
+
typeDataContract: string;
|
|
1712
|
+
enumDataContract: string;
|
|
1713
|
+
objectFieldJsDoc: string;
|
|
1714
|
+
};
|
|
1715
|
+
routeNameDuplicatesMap: Map<string, string>;
|
|
1716
|
+
apiClassName: string;
|
|
1717
|
+
requestOptions?: RequestInit;
|
|
1718
|
+
extractingOptions: ExtractingOptions;
|
|
1719
|
+
};
|
|
1720
|
+
modelTypes: ModelType[];
|
|
1721
|
+
hasFormDataRoutes: boolean;
|
|
1722
|
+
hasSecurityRoutes: boolean;
|
|
1723
|
+
hasQueryRoutes: boolean;
|
|
1724
|
+
generateResponses: boolean;
|
|
1725
|
+
routes: {
|
|
1726
|
+
outOfModule: ParsedRoute[];
|
|
1727
|
+
combined?: {
|
|
1728
|
+
moduleName: string;
|
|
1729
|
+
routes: ParsedRoute[];
|
|
1730
|
+
}[];
|
|
1731
|
+
};
|
|
1732
|
+
requestOptions?: null | Partial<RequestInit>;
|
|
1733
|
+
utils: {
|
|
1734
|
+
formatDescription: (description: string, inline?: boolean) => string;
|
|
1735
|
+
internalCase: (value: string) => string;
|
|
1736
|
+
/** @deprecated */
|
|
1737
|
+
classNameCase: (value: string) => string;
|
|
1738
|
+
pascalCase: (value: string) => string;
|
|
1739
|
+
getInlineParseContent: (
|
|
1740
|
+
rawTypeData: SchemaComponent["rawTypeData"],
|
|
1741
|
+
typeName?: string,
|
|
1742
|
+
) => string;
|
|
1743
|
+
getParseContent: (
|
|
1744
|
+
rawTypeData: SchemaComponent["rawTypeData"],
|
|
1745
|
+
typeName?: string,
|
|
1746
|
+
) => ModelType;
|
|
1747
|
+
getComponentByRef: (ref: string) => SchemaComponent;
|
|
1748
|
+
parseSchema: (
|
|
1749
|
+
rawSchema: string | SchemaComponent["rawTypeData"],
|
|
1750
|
+
typeName?: string,
|
|
1751
|
+
formattersMap?: Record<MAIN_SCHEMA_TYPES, (content: ModelType) => string>,
|
|
1752
|
+
) => ModelType;
|
|
1753
|
+
formatters: Record<
|
|
1754
|
+
MAIN_SCHEMA_TYPES,
|
|
1755
|
+
(content: string | object | string[] | object[]) => string
|
|
1756
|
+
>;
|
|
1757
|
+
inlineExtraFormatters: Record<
|
|
1758
|
+
Exclude<MAIN_SCHEMA_TYPES, SCHEMA_TYPES.PRIMITIVE>,
|
|
1759
|
+
(schema: ModelType) => string
|
|
1760
|
+
>;
|
|
1761
|
+
formatModelName: (name: string) => string;
|
|
1762
|
+
fmtToJSDocLine: (line: string, params?: { eol?: boolean }) => string;
|
|
1763
|
+
_: lodash.LoDashStatic;
|
|
1764
|
+
require: (path: string) => unknown;
|
|
1765
|
+
};
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
type FileInfo = {
|
|
1769
|
+
/** @example myFilename */
|
|
1770
|
+
fileName: string;
|
|
1771
|
+
/** @example .d.ts */
|
|
1772
|
+
fileExtension: string;
|
|
1773
|
+
/** content of the file */
|
|
1774
|
+
fileContent: string;
|
|
1775
|
+
};
|
|
1776
|
+
|
|
1777
|
+
interface GenerateApiOutput {
|
|
1778
|
+
configuration: GenerateApiConfiguration;
|
|
1779
|
+
files: FileInfo[];
|
|
1780
|
+
createFile: (params: {
|
|
1781
|
+
path: string;
|
|
1782
|
+
fileName: string;
|
|
1783
|
+
content: string;
|
|
1784
|
+
withPrefix?: boolean;
|
|
1785
|
+
}) => void;
|
|
1786
|
+
renderTemplate: (
|
|
1787
|
+
templateContent: string,
|
|
1788
|
+
data: Record<string, unknown>,
|
|
1789
|
+
etaOptions?: Partial<eta.EtaConfig>,
|
|
1790
|
+
) => string;
|
|
1791
|
+
getTemplate: (params: {
|
|
1792
|
+
fileName?: string;
|
|
1793
|
+
name?: string;
|
|
1794
|
+
path?: string;
|
|
1795
|
+
}) => string;
|
|
1796
|
+
formatTSContent: (content: string) => Promise<string>;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
declare function generateApi(
|
|
1800
|
+
params: GenerateApiParams,
|
|
1801
|
+
): Promise<GenerateApiOutput>;
|
|
1802
|
+
|
|
1803
|
+
interface GenerateTemplatesParams {
|
|
1804
|
+
cleanOutput?: boolean;
|
|
1805
|
+
output?: string;
|
|
1806
|
+
httpClientType?: HttpClientType;
|
|
1807
|
+
modular?: boolean;
|
|
1808
|
+
silent?: boolean;
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
interface GenerateTemplatesOutput
|
|
1812
|
+
extends Pick<GenerateApiOutput, "files" | "createFile"> {}
|
|
1813
|
+
|
|
1814
|
+
declare function generateTemplates(
|
|
1815
|
+
params: GenerateTemplatesParams,
|
|
1816
|
+
): Promise<GenerateTemplatesOutput>;
|
|
1817
|
+
|
|
1818
|
+
export { type GenerateApiConfiguration, type GenerateApiOutput, type GenerateApiParams, type GenerateTemplatesOutput, type GenerateTemplatesParams, type Hooks, type ModelType, type ParsedRoute, type ParsedSchema, type PathArgInfo, type RawRouteInfo, RequestContentKind, type RequestResponseInfo, type RouteNameInfo, type RouteNameRouteInfo, SCHEMA_TYPES, type SchemaComponent, type SchemaTypeEnumContent, type SchemaTypeObjectContent, type SchemaTypePrimitiveContent, generateApi, generateTemplates };
|