swagger-typescript-api 12.0.0 → 13.0.0-experimental-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -9
- package/index.d.ts +5 -1
- package/package.json +1 -1
- package/src/code-gen-process.js +76 -71
- package/src/configuration.js +1 -5
- package/src/schema-parser/schema-formatters.js +28 -23
- package/src/schema-parser/schema-parser.js +270 -200
- package/src/schema-parser/schema-processor.js +79 -0
- package/src/schema-parser/schema-routes.js +96 -82
- package/src/schema-parser/schema-utils.js +62 -1
- package/src/templates.js +19 -14
- package/src/{type-name.js → type-name-formatter.js} +2 -2
- package/src/util/request.js +5 -6
- package/templates/base/data-contracts.ejs +4 -5
- package/templates/base/http-client.ejs +1 -1
- package/templates/base/interface-data-contract.ejs +3 -3
- package/templates/base/route-type.ejs +1 -1
- package/templates/base/type-data-contract.ejs +3 -3
- package/templates/default/api.ejs +12 -9
- package/templates/default/procedure-call.ejs +2 -2
- package/templates/default/route-types.ejs +15 -11
- package/templates/modular/api.ejs +3 -3
- package/templates/modular/procedure-call.ejs +2 -2
- package/templates/modular/route-types.ejs +3 -3
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const { SCHEMA_TYPES } = require("../constants.js");
|
|
2
|
+
const _ = require("lodash");
|
|
3
|
+
const { SchemaFormatters } = require("./schema-formatters");
|
|
4
|
+
const { internalCase } = require("../util/internal-case");
|
|
5
|
+
const { SchemaUtils } = require("./schema-utils");
|
|
6
|
+
const { camelCase } = require("lodash");
|
|
7
|
+
const { pascalCase } = require("../util/pascal-case");
|
|
8
|
+
const { SchemaParser } = require("./schema-parser");
|
|
9
|
+
|
|
10
|
+
class SchemaProcessor {
|
|
11
|
+
/**
|
|
12
|
+
* @type {CodeGenConfig}
|
|
13
|
+
*/
|
|
14
|
+
config;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @type {SchemaComponentsMap}
|
|
18
|
+
*/
|
|
19
|
+
schemaComponentsMap;
|
|
20
|
+
/**
|
|
21
|
+
* @type {TypeNameFormatter}
|
|
22
|
+
*/
|
|
23
|
+
typeNameFormatter;
|
|
24
|
+
/**
|
|
25
|
+
* @type {SchemaFormatters}
|
|
26
|
+
*/
|
|
27
|
+
schemaFormatters;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @type {SchemaUtils}
|
|
31
|
+
*/
|
|
32
|
+
schemaUtils;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @type {((schema, typeName) => SchemaParser)}
|
|
36
|
+
*/
|
|
37
|
+
createSchemaParser;
|
|
38
|
+
|
|
39
|
+
constructor(config, logger, templates, schemaComponentsMap, typeNameFormatter) {
|
|
40
|
+
this.config = config;
|
|
41
|
+
this.schemaComponentsMap = schemaComponentsMap;
|
|
42
|
+
this.typeNameFormatter = typeNameFormatter;
|
|
43
|
+
this.schemaFormatters = new SchemaFormatters(config, logger, this, templates);
|
|
44
|
+
this.schemaUtils = new SchemaUtils(config, schemaComponentsMap, typeNameFormatter);
|
|
45
|
+
this.createSchemaParser = SchemaParser.create.bind(
|
|
46
|
+
null,
|
|
47
|
+
config,
|
|
48
|
+
schemaComponentsMap,
|
|
49
|
+
typeNameFormatter,
|
|
50
|
+
this.schemaFormatters,
|
|
51
|
+
this.schemaUtils,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* @param schema {any}
|
|
58
|
+
* @param typeName {null | string}
|
|
59
|
+
* @return {Promise<Record<string, any>>}
|
|
60
|
+
*/
|
|
61
|
+
parseSchema = async (schema, typeName = null) => {
|
|
62
|
+
const schemaParser = this.createSchemaParser(schema, typeName);
|
|
63
|
+
return await schemaParser.parse();
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
getInlineParseContent = async (schema, typeName) => {
|
|
67
|
+
const parser = this.createSchemaParser(schema, typeName);
|
|
68
|
+
return await parser.getInlineContent();
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
getParseContent = async (schema, typeName) => {
|
|
72
|
+
const parser = this.createSchemaParser(schema, typeName);
|
|
73
|
+
return await parser.getContent();
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = {
|
|
78
|
+
SchemaProcessor,
|
|
79
|
+
};
|
|
@@ -25,7 +25,7 @@ class SchemaRoutes {
|
|
|
25
25
|
*/
|
|
26
26
|
config;
|
|
27
27
|
/**
|
|
28
|
-
* @type {
|
|
28
|
+
* @type {SchemaProcessor}
|
|
29
29
|
*/
|
|
30
30
|
schemaParser;
|
|
31
31
|
/**
|
|
@@ -33,7 +33,7 @@ class SchemaRoutes {
|
|
|
33
33
|
*/
|
|
34
34
|
schemaUtils;
|
|
35
35
|
/**
|
|
36
|
-
* @type {
|
|
36
|
+
* @type {TypeNameFormatter}
|
|
37
37
|
*/
|
|
38
38
|
typeName;
|
|
39
39
|
/**
|
|
@@ -64,10 +64,12 @@ class SchemaRoutes {
|
|
|
64
64
|
this.schemaComponentMap = schemaComponentMap;
|
|
65
65
|
this.logger = logger;
|
|
66
66
|
this.templates = templates;
|
|
67
|
+
}
|
|
67
68
|
|
|
69
|
+
async init() {
|
|
68
70
|
this.FORM_DATA_TYPES = _.uniq([
|
|
69
|
-
this.
|
|
70
|
-
this.
|
|
71
|
+
await this.schemaUtils.getSchemaType({ type: "string", format: "file" }),
|
|
72
|
+
await this.schemaUtils.getSchemaType({ type: "string", format: "binary" }),
|
|
71
73
|
]);
|
|
72
74
|
}
|
|
73
75
|
|
|
@@ -308,13 +310,13 @@ class SchemaRoutes {
|
|
|
308
310
|
return null;
|
|
309
311
|
};
|
|
310
312
|
|
|
311
|
-
getTypeFromRequestInfo = ({ requestInfo, parsedSchemas, operationId, defaultType, typeName }) => {
|
|
313
|
+
getTypeFromRequestInfo = async ({ requestInfo, parsedSchemas, operationId, defaultType, typeName }) => {
|
|
312
314
|
// TODO: make more flexible pick schema without content type
|
|
313
315
|
const schema = this.getSchemaFromRequestType(requestInfo);
|
|
314
316
|
const refTypeInfo = this.schemaParser.schemaUtils.getSchemaRefType(requestInfo);
|
|
315
317
|
|
|
316
318
|
if (schema) {
|
|
317
|
-
const content = this.schemaParser.getInlineParseContent(schema, typeName);
|
|
319
|
+
const content = await this.schemaParser.getInlineParseContent(schema, typeName);
|
|
318
320
|
const foundedSchemaByName = _.find(
|
|
319
321
|
parsedSchemas,
|
|
320
322
|
(parsedSchema) => this.typeName.format(parsedSchema.name) === content,
|
|
@@ -341,54 +343,56 @@ class SchemaRoutes {
|
|
|
341
343
|
return this.typeName.format(refTypeInfo.typeName);
|
|
342
344
|
case "responses":
|
|
343
345
|
case "requestBodies":
|
|
344
|
-
return this.schemaParser.getInlineParseContent(
|
|
346
|
+
return await this.schemaParser.getInlineParseContent(
|
|
345
347
|
this.getSchemaFromRequestType(refTypeInfo.rawTypeData),
|
|
346
348
|
refTypeInfo.typeName || null,
|
|
347
349
|
);
|
|
348
350
|
default:
|
|
349
|
-
return this.schemaParser.getInlineParseContent(refTypeInfo.rawTypeData, refTypeInfo.typeName || null);
|
|
351
|
+
return await this.schemaParser.getInlineParseContent(refTypeInfo.rawTypeData, refTypeInfo.typeName || null);
|
|
350
352
|
}
|
|
351
353
|
}
|
|
352
354
|
|
|
353
355
|
return defaultType || this.config.Ts.Keyword.Any;
|
|
354
356
|
};
|
|
355
357
|
|
|
356
|
-
getRequestInfoTypes = ({ requestInfos, parsedSchemas, operationId, defaultType }) =>
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
);
|
|
358
|
+
getRequestInfoTypes = async ({ requestInfos, parsedSchemas, operationId, defaultType }) => {
|
|
359
|
+
const requestInfoTypes = [];
|
|
360
|
+
|
|
361
|
+
const statuses = _.entries(requestInfos);
|
|
362
|
+
|
|
363
|
+
for await (const [status, requestInfo] of statuses) {
|
|
364
|
+
const contentTypes = this.getContentTypes([requestInfo]);
|
|
365
|
+
|
|
366
|
+
const requestInfoType = {
|
|
367
|
+
...(requestInfo || {}),
|
|
368
|
+
contentTypes: contentTypes,
|
|
369
|
+
contentKind: this.getContentKind(contentTypes),
|
|
370
|
+
type: this.schemaParser.schemaUtils.safeAddNullToType(
|
|
371
|
+
requestInfo,
|
|
372
|
+
await this.getTypeFromRequestInfo({
|
|
373
|
+
requestInfo,
|
|
374
|
+
parsedSchemas,
|
|
375
|
+
operationId,
|
|
376
|
+
defaultType,
|
|
377
|
+
}),
|
|
378
|
+
),
|
|
379
|
+
description: this.schemaParser.schemaFormatters.formatDescription(requestInfo.description || "", true),
|
|
380
|
+
status: _.isNaN(+status) ? status : +status,
|
|
381
|
+
isSuccess: this.isSuccessStatus(status),
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
requestInfoTypes.push(requestInfoType);
|
|
385
|
+
}
|
|
385
386
|
|
|
386
|
-
|
|
387
|
+
return requestInfoTypes;
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
getResponseBodyInfo = async (routeInfo, routeParams, parsedSchemas) => {
|
|
387
391
|
const { produces, operationId, responses } = routeInfo;
|
|
388
392
|
|
|
389
393
|
const contentTypes = this.getContentTypes(responses, [...(produces || []), routeInfo["x-accepts"]]);
|
|
390
394
|
|
|
391
|
-
const responseInfos = this.getRequestInfoTypes({
|
|
395
|
+
const responseInfos = await this.getRequestInfoTypes({
|
|
392
396
|
requestInfos: responses,
|
|
393
397
|
parsedSchemas,
|
|
394
398
|
operationId,
|
|
@@ -400,14 +404,16 @@ class SchemaRoutes {
|
|
|
400
404
|
(response) => !response.isSuccess && response.type !== this.config.Ts.Keyword.Any,
|
|
401
405
|
);
|
|
402
406
|
|
|
403
|
-
const handleResponseHeaders = (src) => {
|
|
407
|
+
const handleResponseHeaders = async (src) => {
|
|
404
408
|
if (!src) {
|
|
405
409
|
return "headers: {},";
|
|
406
410
|
}
|
|
407
411
|
const headerTypes = Object.fromEntries(
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
412
|
+
await Promise.all(
|
|
413
|
+
Object.entries(src).map(async ([k, v]) => {
|
|
414
|
+
return [k, await this.schemaUtils.getSchemaType(v)];
|
|
415
|
+
}),
|
|
416
|
+
),
|
|
411
417
|
);
|
|
412
418
|
const r = `headers: { ${Object.entries(headerTypes)
|
|
413
419
|
.map(([k, v]) => `"${k}": ${v}`)
|
|
@@ -429,11 +435,13 @@ class SchemaRoutes {
|
|
|
429
435
|
full: {
|
|
430
436
|
types:
|
|
431
437
|
this.config.Ts.UnionType(
|
|
432
|
-
|
|
433
|
-
(
|
|
438
|
+
await Promise.all(
|
|
439
|
+
responseInfos.map(
|
|
440
|
+
async (response) => `{
|
|
434
441
|
data: ${response.type}, status: ${response.status}, statusCode: ${response.status}, statusText: "${
|
|
435
|
-
|
|
436
|
-
|
|
442
|
+
response.description
|
|
443
|
+
}", ${await handleResponseHeaders(response.headers)} config: {} }`,
|
|
444
|
+
),
|
|
437
445
|
),
|
|
438
446
|
) || this.config.Ts.Keyword.Any,
|
|
439
447
|
},
|
|
@@ -464,7 +472,7 @@ class SchemaRoutes {
|
|
|
464
472
|
);
|
|
465
473
|
};
|
|
466
474
|
|
|
467
|
-
getRequestBodyInfo = (routeInfo, routeParams, parsedSchemas, routeName) => {
|
|
475
|
+
getRequestBodyInfo = async (routeInfo, routeParams, parsedSchemas, routeName) => {
|
|
468
476
|
const { requestBody, consumes, requestBodyName, operationId } = routeInfo;
|
|
469
477
|
let schema = null;
|
|
470
478
|
let type = null;
|
|
@@ -485,15 +493,15 @@ class SchemaRoutes {
|
|
|
485
493
|
if (routeParams.formData.length) {
|
|
486
494
|
contentKind = CONTENT_KIND.FORM_DATA;
|
|
487
495
|
schema = this.convertRouteParamsIntoObject(routeParams.formData);
|
|
488
|
-
type = this.schemaParser.getInlineParseContent(schema, typeName);
|
|
496
|
+
type = await this.schemaParser.getInlineParseContent(schema, typeName);
|
|
489
497
|
} else if (contentKind === CONTENT_KIND.FORM_DATA) {
|
|
490
498
|
schema = this.getSchemaFromRequestType(requestBody);
|
|
491
|
-
type = this.schemaParser.getInlineParseContent(schema, typeName);
|
|
499
|
+
type = await this.schemaParser.getInlineParseContent(schema, typeName);
|
|
492
500
|
} else if (requestBody) {
|
|
493
501
|
schema = this.getSchemaFromRequestType(requestBody);
|
|
494
502
|
type = this.schemaParser.schemaUtils.safeAddNullToType(
|
|
495
503
|
requestBody,
|
|
496
|
-
this.getTypeFromRequestInfo({
|
|
504
|
+
await this.getTypeFromRequestInfo({
|
|
497
505
|
requestInfo: requestBody,
|
|
498
506
|
parsedSchemas,
|
|
499
507
|
operationId,
|
|
@@ -511,7 +519,7 @@ class SchemaRoutes {
|
|
|
511
519
|
|
|
512
520
|
if (schema && !schema.$ref && this.config.extractRequestBody) {
|
|
513
521
|
schema = this.schemaComponentMap.createComponent("schemas", typeName, { ...schema });
|
|
514
|
-
type = this.schemaParser.getInlineParseContent(schema);
|
|
522
|
+
type = await this.schemaParser.getInlineParseContent(schema);
|
|
515
523
|
}
|
|
516
524
|
|
|
517
525
|
return {
|
|
@@ -588,7 +596,7 @@ class SchemaRoutes {
|
|
|
588
596
|
return schema;
|
|
589
597
|
};
|
|
590
598
|
|
|
591
|
-
extractResponseBodyIfItNeeded = (routeInfo, responseBodyInfo, routeName) => {
|
|
599
|
+
extractResponseBodyIfItNeeded = async (routeInfo, responseBodyInfo, routeName) => {
|
|
592
600
|
if (responseBodyInfo.responses.length && responseBodyInfo.success && responseBodyInfo.success.schema) {
|
|
593
601
|
const typeName = this.schemaUtils.resolveTypeName(
|
|
594
602
|
routeName.usage,
|
|
@@ -603,7 +611,7 @@ class SchemaRoutes {
|
|
|
603
611
|
if (successResponse.schema && !successResponse.schema.$ref) {
|
|
604
612
|
const schema = this.getSchemaFromRequestType(successResponse.schema);
|
|
605
613
|
successResponse.schema = this.schemaComponentMap.createComponent("schemas", typeName, { ...schema });
|
|
606
|
-
successResponse.type = this.schemaParser.getInlineParseContent(successResponse.schema);
|
|
614
|
+
successResponse.type = await this.schemaParser.getInlineParseContent(successResponse.schema);
|
|
607
615
|
|
|
608
616
|
if (idx > -1) {
|
|
609
617
|
_.assign(responseBodyInfo.responses[idx], {
|
|
@@ -615,7 +623,7 @@ class SchemaRoutes {
|
|
|
615
623
|
}
|
|
616
624
|
};
|
|
617
625
|
|
|
618
|
-
extractResponseErrorIfItNeeded = (routeInfo, responseBodyInfo, routeName) => {
|
|
626
|
+
extractResponseErrorIfItNeeded = async (routeInfo, responseBodyInfo, routeName) => {
|
|
619
627
|
if (responseBodyInfo.responses.length && responseBodyInfo.error.schemas && responseBodyInfo.error.schemas.length) {
|
|
620
628
|
const typeName = this.schemaUtils.resolveTypeName(
|
|
621
629
|
routeName.usage,
|
|
@@ -627,7 +635,7 @@ class SchemaRoutes {
|
|
|
627
635
|
|
|
628
636
|
if (!errorSchemas.length) return;
|
|
629
637
|
|
|
630
|
-
const schema = this.schemaParser.parseSchema({
|
|
638
|
+
const schema = await this.schemaParser.parseSchema({
|
|
631
639
|
oneOf: errorSchemas,
|
|
632
640
|
title: errorSchemas
|
|
633
641
|
.map((schema) => schema.title)
|
|
@@ -644,12 +652,12 @@ class SchemaRoutes {
|
|
|
644
652
|
}
|
|
645
653
|
};
|
|
646
654
|
|
|
647
|
-
getRouteName = (rawRouteInfo) => {
|
|
655
|
+
getRouteName = async (rawRouteInfo) => {
|
|
648
656
|
const { moduleName } = rawRouteInfo;
|
|
649
657
|
const { routeNameDuplicatesMap, templatesToRender } = this.config;
|
|
650
658
|
const routeNameTemplate = templatesToRender.routeName;
|
|
651
659
|
|
|
652
|
-
const routeNameFromTemplate = this.templates.renderTemplate(routeNameTemplate, {
|
|
660
|
+
const routeNameFromTemplate = await this.templates.renderTemplate(routeNameTemplate, {
|
|
653
661
|
routeInfo: rawRouteInfo,
|
|
654
662
|
});
|
|
655
663
|
|
|
@@ -681,7 +689,7 @@ class SchemaRoutes {
|
|
|
681
689
|
return this.config.hooks.onCreateRouteName(routeNameInfo, rawRouteInfo) || routeNameInfo;
|
|
682
690
|
};
|
|
683
691
|
|
|
684
|
-
parseRouteInfo = (rawRouteName, routeInfo, method, usageSchema, parsedSchemas) => {
|
|
692
|
+
parseRouteInfo = async (rawRouteName, routeInfo, method, usageSchema, parsedSchemas) => {
|
|
685
693
|
const { security: globalSecurity } = usageSchema;
|
|
686
694
|
const { moduleNameIndex, moduleNameFirstTag, extractRequestParams } = this.config;
|
|
687
695
|
const {
|
|
@@ -717,15 +725,17 @@ class SchemaRoutes {
|
|
|
717
725
|
|
|
718
726
|
const routeParams = this.getRouteParams(routeInfo, pathParamsFromRouteName, queryParamsFromRouteName);
|
|
719
727
|
|
|
720
|
-
const pathArgs =
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
728
|
+
const pathArgs = await Promise.all(
|
|
729
|
+
routeParams.path.map(async (pathArgSchema) => ({
|
|
730
|
+
name: pathArgSchema.name,
|
|
731
|
+
optional: !pathArgSchema.required,
|
|
732
|
+
type: await this.schemaParser.getInlineParseContent(pathArgSchema.schema),
|
|
733
|
+
description: pathArgSchema.description,
|
|
734
|
+
})),
|
|
735
|
+
);
|
|
726
736
|
const pathArgsNames = pathArgs.map((arg) => arg.name);
|
|
727
737
|
|
|
728
|
-
const responseBodyInfo = this.getResponseBodyInfo(routeInfo, routeParams, parsedSchemas);
|
|
738
|
+
const responseBodyInfo = await this.getResponseBodyInfo(routeInfo, routeParams, parsedSchemas);
|
|
729
739
|
|
|
730
740
|
const rawRouteInfo = {
|
|
731
741
|
...otherInfo,
|
|
@@ -748,9 +758,9 @@ class SchemaRoutes {
|
|
|
748
758
|
const pathObjectSchema = this.convertRouteParamsIntoObject(routeParams.path);
|
|
749
759
|
const headersObjectSchema = this.convertRouteParamsIntoObject(routeParams.header);
|
|
750
760
|
|
|
751
|
-
const routeName = this.getRouteName(rawRouteInfo);
|
|
761
|
+
const routeName = await this.getRouteName(rawRouteInfo);
|
|
752
762
|
|
|
753
|
-
const requestBodyInfo = this.getRequestBodyInfo(routeInfo, routeParams, parsedSchemas, routeName);
|
|
763
|
+
const requestBodyInfo = await this.getRequestBodyInfo(routeInfo, routeParams, parsedSchemas, routeName);
|
|
754
764
|
|
|
755
765
|
const requestParamsSchema = this.createRequestParamsSchema({
|
|
756
766
|
queryParams: routeParams.query,
|
|
@@ -761,15 +771,19 @@ class SchemaRoutes {
|
|
|
761
771
|
});
|
|
762
772
|
|
|
763
773
|
if (this.config.extractResponseBody) {
|
|
764
|
-
this.extractResponseBodyIfItNeeded(routeInfo, responseBodyInfo, routeName);
|
|
774
|
+
await this.extractResponseBodyIfItNeeded(routeInfo, responseBodyInfo, routeName);
|
|
765
775
|
}
|
|
766
776
|
if (this.config.extractResponseError) {
|
|
767
|
-
this.extractResponseErrorIfItNeeded(routeInfo, responseBodyInfo, routeName);
|
|
777
|
+
await this.extractResponseErrorIfItNeeded(routeInfo, responseBodyInfo, routeName);
|
|
768
778
|
}
|
|
769
779
|
|
|
770
|
-
const queryType = routeParams.query.length
|
|
771
|
-
|
|
772
|
-
|
|
780
|
+
const queryType = routeParams.query.length
|
|
781
|
+
? await this.schemaParser.getInlineParseContent(queryObjectSchema)
|
|
782
|
+
: null;
|
|
783
|
+
const pathType = routeParams.path.length ? await this.schemaParser.getInlineParseContent(pathObjectSchema) : null;
|
|
784
|
+
const headersType = routeParams.header.length
|
|
785
|
+
? await this.schemaParser.getInlineParseContent(headersObjectSchema)
|
|
786
|
+
: null;
|
|
773
787
|
|
|
774
788
|
const nameResolver = new SpecificArgNameResolver(this.logger, pathArgsNames);
|
|
775
789
|
|
|
@@ -777,7 +791,7 @@ class SchemaRoutes {
|
|
|
777
791
|
query: queryType
|
|
778
792
|
? {
|
|
779
793
|
name: nameResolver.resolve(RESERVED_QUERY_ARG_NAMES),
|
|
780
|
-
optional: this.schemaParser.parseSchema(queryObjectSchema).allFieldsAreOptional,
|
|
794
|
+
optional: (await this.schemaParser.parseSchema(queryObjectSchema)).allFieldsAreOptional,
|
|
781
795
|
type: queryType,
|
|
782
796
|
}
|
|
783
797
|
: void 0,
|
|
@@ -791,14 +805,14 @@ class SchemaRoutes {
|
|
|
791
805
|
pathParams: pathType
|
|
792
806
|
? {
|
|
793
807
|
name: nameResolver.resolve(RESERVED_PATH_ARG_NAMES),
|
|
794
|
-
optional: this.schemaParser.parseSchema(pathObjectSchema).allFieldsAreOptional,
|
|
808
|
+
optional: (await this.schemaParser.parseSchema(pathObjectSchema)).allFieldsAreOptional,
|
|
795
809
|
type: pathType,
|
|
796
810
|
}
|
|
797
811
|
: void 0,
|
|
798
812
|
headers: headersType
|
|
799
813
|
? {
|
|
800
814
|
name: nameResolver.resolve(RESERVED_HEADER_ARG_NAMES),
|
|
801
|
-
optional: this.schemaParser.parseSchema(headersObjectSchema).allFieldsAreOptional,
|
|
815
|
+
optional: (await this.schemaParser.parseSchema(headersObjectSchema)).allFieldsAreOptional,
|
|
802
816
|
type: headersType,
|
|
803
817
|
}
|
|
804
818
|
: void 0,
|
|
@@ -843,16 +857,16 @@ class SchemaRoutes {
|
|
|
843
857
|
};
|
|
844
858
|
};
|
|
845
859
|
|
|
846
|
-
attachSchema = ({ usageSchema, parsedSchemas }) => {
|
|
860
|
+
attachSchema = async ({ usageSchema, parsedSchemas }) => {
|
|
847
861
|
this.config.routeNameDuplicatesMap.clear();
|
|
848
862
|
|
|
849
863
|
const pathsEntries = _.entries(usageSchema.paths);
|
|
850
864
|
|
|
851
|
-
|
|
865
|
+
for await (const [rawRouteName, routeInfoByMethodsMap] of pathsEntries) {
|
|
852
866
|
const routeInfosMap = this.createRequestsMap(routeInfoByMethodsMap);
|
|
853
867
|
|
|
854
|
-
|
|
855
|
-
const parsedRouteInfo = this.parseRouteInfo(rawRouteName, routeInfo, method, usageSchema, parsedSchemas);
|
|
868
|
+
for await (const [method, routeInfo] of _.entries(routeInfosMap)) {
|
|
869
|
+
const parsedRouteInfo = await this.parseRouteInfo(rawRouteName, routeInfo, method, usageSchema, parsedSchemas);
|
|
856
870
|
const processedRouteInfo = this.config.hooks.onCreateRoute(parsedRouteInfo);
|
|
857
871
|
const route = processedRouteInfo || parsedRouteInfo;
|
|
858
872
|
|
|
@@ -867,8 +881,8 @@ class SchemaRoutes {
|
|
|
867
881
|
}
|
|
868
882
|
|
|
869
883
|
this.routes.push(route);
|
|
870
|
-
}
|
|
871
|
-
}
|
|
884
|
+
}
|
|
885
|
+
}
|
|
872
886
|
};
|
|
873
887
|
|
|
874
888
|
getGroupedRoutes = () => {
|
|
@@ -12,10 +12,15 @@ class SchemaUtils {
|
|
|
12
12
|
* @type {SchemaComponentsMap}
|
|
13
13
|
*/
|
|
14
14
|
schemaComponentsMap;
|
|
15
|
+
/**
|
|
16
|
+
* @type {TypeNameFormatter}
|
|
17
|
+
*/
|
|
18
|
+
typeNameFormatter;
|
|
15
19
|
|
|
16
|
-
constructor(config, schemaComponentsMap) {
|
|
20
|
+
constructor(config, schemaComponentsMap, typeNameFormatter) {
|
|
17
21
|
this.config = config;
|
|
18
22
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
23
|
+
this.typeNameFormatter = typeNameFormatter;
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
getRequiredProperties = (schema) => {
|
|
@@ -141,6 +146,62 @@ class SchemaUtils {
|
|
|
141
146
|
return childSchema;
|
|
142
147
|
};
|
|
143
148
|
|
|
149
|
+
getComplexType = (schema) => {
|
|
150
|
+
if (schema.oneOf) return SCHEMA_TYPES.COMPLEX_ONE_OF;
|
|
151
|
+
if (schema.allOf) return SCHEMA_TYPES.COMPLEX_ALL_OF;
|
|
152
|
+
if (schema.anyOf) return SCHEMA_TYPES.COMPLEX_ANY_OF;
|
|
153
|
+
// TODO :(
|
|
154
|
+
if (schema.not) return SCHEMA_TYPES.COMPLEX_NOT;
|
|
155
|
+
|
|
156
|
+
return SCHEMA_TYPES.COMPLEX_UNKNOWN;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
getInternalSchemaType = (schema) => {
|
|
160
|
+
if (!_.isEmpty(schema.enum) || !_.isEmpty(this.getEnumNames(schema))) return SCHEMA_TYPES.ENUM;
|
|
161
|
+
if (schema.allOf || schema.oneOf || schema.anyOf || schema.not) return SCHEMA_TYPES.COMPLEX;
|
|
162
|
+
if (!_.isEmpty(schema.properties)) return SCHEMA_TYPES.OBJECT;
|
|
163
|
+
if (schema.type === SCHEMA_TYPES.ARRAY) return SCHEMA_TYPES.ARRAY;
|
|
164
|
+
|
|
165
|
+
return SCHEMA_TYPES.PRIMITIVE;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
getSchemaType = async (schema) => {
|
|
169
|
+
if (!schema) return this.config.Ts.Keyword.Any;
|
|
170
|
+
|
|
171
|
+
const refTypeInfo = this.getSchemaRefType(schema);
|
|
172
|
+
|
|
173
|
+
if (refTypeInfo) {
|
|
174
|
+
return this.checkAndAddRequiredKeys(
|
|
175
|
+
schema,
|
|
176
|
+
this.safeAddNullToType(schema, this.typeNameFormatter.format(refTypeInfo.typeName)),
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const primitiveType = this.getSchemaPrimitiveType(schema);
|
|
181
|
+
|
|
182
|
+
if (primitiveType == null) return this.config.Ts.Keyword.Any;
|
|
183
|
+
|
|
184
|
+
let resultType;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* @type {string | (() => Promise<string>)}
|
|
188
|
+
*/
|
|
189
|
+
const typeAlias =
|
|
190
|
+
_.get(this.config.primitiveTypes, [primitiveType, schema.format]) ||
|
|
191
|
+
_.get(this.config.primitiveTypes, [primitiveType, "$default"]) ||
|
|
192
|
+
this.config.primitiveTypes[primitiveType];
|
|
193
|
+
|
|
194
|
+
if (_.isFunction(typeAlias)) {
|
|
195
|
+
resultType = await typeAlias(schema, this);
|
|
196
|
+
} else {
|
|
197
|
+
resultType = typeAlias || primitiveType;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (!resultType) return this.config.Ts.Keyword.Any;
|
|
201
|
+
|
|
202
|
+
return this.checkAndAddRequiredKeys(schema, this.safeAddNullToType(schema, resultType));
|
|
203
|
+
};
|
|
204
|
+
|
|
144
205
|
filterSchemaContents = (contents, filterFn) => {
|
|
145
206
|
return _.uniq(_.filter(contents, (type) => filterFn(type)));
|
|
146
207
|
};
|
package/src/templates.js
CHANGED
|
@@ -152,23 +152,28 @@ class Templates {
|
|
|
152
152
|
return "";
|
|
153
153
|
};
|
|
154
154
|
|
|
155
|
-
renderTemplate = (template, configuration, options) => {
|
|
155
|
+
renderTemplate = async (template, configuration, options) => {
|
|
156
156
|
if (!template) return "";
|
|
157
157
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
{
|
|
165
|
-
async: false,
|
|
166
|
-
...(options || {}),
|
|
167
|
-
includeFile: (path, configuration, options) => {
|
|
168
|
-
return this.renderTemplate(this.getTemplateContent(path), configuration, options);
|
|
158
|
+
try {
|
|
159
|
+
return await Eta.renderAsync(
|
|
160
|
+
template,
|
|
161
|
+
{
|
|
162
|
+
...this.getRenderTemplateData(),
|
|
163
|
+
...configuration,
|
|
169
164
|
},
|
|
170
|
-
|
|
171
|
-
|
|
165
|
+
{
|
|
166
|
+
async: true,
|
|
167
|
+
...(options || {}),
|
|
168
|
+
includeFile: async (path, configuration, options) => {
|
|
169
|
+
return await this.renderTemplate(this.getTemplateContent(path), configuration, options);
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
);
|
|
173
|
+
} catch (e) {
|
|
174
|
+
console.error("problem in this templates\n", template);
|
|
175
|
+
throw e;
|
|
176
|
+
}
|
|
172
177
|
};
|
|
173
178
|
}
|
|
174
179
|
|
|
@@ -4,7 +4,7 @@ const _ = require("lodash");
|
|
|
4
4
|
* @typedef {"enum-key" | "type-name"} FormattingSchemaType
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
class
|
|
7
|
+
class TypeNameFormatter {
|
|
8
8
|
/** @type {Map<string, string>} */
|
|
9
9
|
formattedModelNamesMap = new Map();
|
|
10
10
|
|
|
@@ -94,5 +94,5 @@ class TypeName {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
module.exports = {
|
|
97
|
-
|
|
97
|
+
TypeNameFormatter,
|
|
98
98
|
};
|
package/src/util/request.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const _ = require("lodash");
|
|
1
2
|
const https = require("https");
|
|
2
3
|
const fetch = require("node-fetch-h2");
|
|
3
4
|
|
|
@@ -18,7 +19,7 @@ class Request {
|
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
*
|
|
21
|
-
* @param url
|
|
22
|
+
* @param url {string}
|
|
22
23
|
* @param disableStrictSSL
|
|
23
24
|
* @param authToken
|
|
24
25
|
* @param options {Partial<import("node-fetch").RequestInit>}
|
|
@@ -28,11 +29,9 @@ class Request {
|
|
|
28
29
|
/**
|
|
29
30
|
* @type {Partial<import("node-fetch").RequestInit>}
|
|
30
31
|
*/
|
|
31
|
-
const requestOptions = {
|
|
32
|
-
...(this.config.requestOptions || {}),
|
|
33
|
-
};
|
|
32
|
+
const requestOptions = {};
|
|
34
33
|
|
|
35
|
-
if (disableStrictSSL) {
|
|
34
|
+
if (disableStrictSSL && !_.startsWith(url, "http://")) {
|
|
36
35
|
requestOptions.agent = new https.Agent({
|
|
37
36
|
rejectUnauthorized: false,
|
|
38
37
|
});
|
|
@@ -43,7 +42,7 @@ class Request {
|
|
|
43
42
|
};
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
|
|
45
|
+
_.merge(requestOptions, options, this.config.requestOptions);
|
|
47
46
|
|
|
48
47
|
try {
|
|
49
48
|
const response = await fetch(url, requestOptions);
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
const { modelTypes, utils, config } = it;
|
|
3
3
|
const { formatDescription, require, _, Ts } = utils;
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
const dataContractTemplates = {
|
|
7
6
|
enum: (contract) => {
|
|
8
7
|
return `enum ${contract.name} {\r\n${contract.content} \r\n }`;
|
|
@@ -20,9 +19,9 @@ const dataContractTemplates = {
|
|
|
20
19
|
type <%~ config.Ts.CodeGenKeyword.UtilRequiredKeys %><T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>
|
|
21
20
|
<% } %>
|
|
22
21
|
|
|
23
|
-
<%
|
|
24
|
-
<%~ includeFile('@base/data-contract-jsdoc.ejs', { ...it, data: { ...contract, ...contract.typeData } }) %>
|
|
25
|
-
export <%~ (dataContractTemplates[contract.typeIdentifier] || dataContractTemplates.type)(contract) %>
|
|
22
|
+
<% for await (const contract of modelTypes) { %>
|
|
26
23
|
|
|
24
|
+
<%~ await includeFile('@base/data-contract-jsdoc.ejs', { ...it, data: { ...contract, ...contract.typeData } }) %>
|
|
25
|
+
export <%~ (dataContractTemplates[contract.typeIdentifier] || dataContractTemplates.type)(contract) %>
|
|
27
26
|
|
|
28
|
-
<% }
|
|
27
|
+
<% } %>
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
<% const { config } = it; %>
|
|
2
2
|
<% /* https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/http-clients/ */ %>
|
|
3
|
-
<%~ includeFile(`@base/http-clients/${config.httpClientType}-http-client`, it) %>
|
|
3
|
+
<%~ await includeFile(`@base/http-clients/${config.httpClientType}-http-client`, it) %>
|