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.
@@ -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 };