swagger-typescript-api 13.2.17 → 13.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/{generate-templates-BO-5CKCm.mjs → generate-templates-BaT2BiRR.mjs} +553 -146
- package/dist/generate-templates-BaT2BiRR.mjs.map +1 -0
- package/dist/{generate-templates-wjE78AWV.cjs → generate-templates-BlSkwa8l.cjs} +518 -109
- package/dist/generate-templates-BlSkwa8l.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +213 -182
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +213 -182
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -10
- package/templates/base/data-contract-jsdoc.ejs +16 -16
- package/templates/base/object-field-jsdoc.ejs +8 -8
- package/templates/base/route-docs.ejs +13 -7
- package/templates/default/api.ejs +11 -11
- package/dist/generate-templates-BO-5CKCm.mjs.map +0 -1
- package/dist/generate-templates-wjE78AWV.cjs.map +0 -1
|
@@ -39,6 +39,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
39
39
|
|
|
40
40
|
//#endregion
|
|
41
41
|
let consola = require("consola");
|
|
42
|
+
consola = __toESM(consola);
|
|
42
43
|
let es_toolkit = require("es-toolkit");
|
|
43
44
|
es_toolkit = __toESM(es_toolkit);
|
|
44
45
|
let es_toolkit_compat = require("es-toolkit/compat");
|
|
@@ -50,19 +51,22 @@ node_path = __toESM(node_path);
|
|
|
50
51
|
let _biomejs_js_api = require("@biomejs/js-api");
|
|
51
52
|
let nanoid = require("nanoid");
|
|
52
53
|
nanoid = __toESM(nanoid);
|
|
54
|
+
let yummies_type_guard = require("yummies/type-guard");
|
|
53
55
|
let node_crypto = require("node:crypto");
|
|
54
56
|
node_crypto = __toESM(node_crypto);
|
|
55
57
|
let swagger2openapi = require("swagger2openapi");
|
|
56
58
|
swagger2openapi = __toESM(swagger2openapi);
|
|
57
59
|
let yaml = require("yaml");
|
|
58
60
|
yaml = __toESM(yaml);
|
|
61
|
+
let node_fs = require("node:fs");
|
|
62
|
+
node_fs = __toESM(node_fs);
|
|
63
|
+
let _apidevtools_swagger_parser = require("@apidevtools/swagger-parser");
|
|
64
|
+
_apidevtools_swagger_parser = __toESM(_apidevtools_swagger_parser);
|
|
59
65
|
let node_module = require("node:module");
|
|
60
66
|
node_module = __toESM(node_module);
|
|
61
67
|
let node_url = require("node:url");
|
|
62
68
|
node_url = __toESM(node_url);
|
|
63
69
|
let eta = require("eta");
|
|
64
|
-
let node_fs = require("node:fs");
|
|
65
|
-
node_fs = __toESM(node_fs);
|
|
66
70
|
|
|
67
71
|
//#region src/code-formatter.ts
|
|
68
72
|
var CodeFormatter = class {
|
|
@@ -223,7 +227,7 @@ var ComponentTypeNameResolver = class extends NameResolver {
|
|
|
223
227
|
//#endregion
|
|
224
228
|
//#region package.json
|
|
225
229
|
var name = "swagger-typescript-api";
|
|
226
|
-
var version = "13.
|
|
230
|
+
var version = "13.3.0";
|
|
227
231
|
var description = "Generate the API client for Fetch or Axios from an OpenAPI Specification";
|
|
228
232
|
|
|
229
233
|
//#endregion
|
|
@@ -292,6 +296,17 @@ const SCHEMA_TYPES$1 = {
|
|
|
292
296
|
COMPLEX_UNKNOWN: "__unknown"
|
|
293
297
|
};
|
|
294
298
|
|
|
299
|
+
//#endregion
|
|
300
|
+
//#region src/util/object-assign.ts
|
|
301
|
+
const objectAssign = (target, updater) => {
|
|
302
|
+
if (!updater) return;
|
|
303
|
+
const update = typeof updater === "function" ? updater(target) : updater;
|
|
304
|
+
if (!update) return;
|
|
305
|
+
const undefinedKeys = Object.entries(update).filter(([, value]) => value === void 0).map(([key]) => key);
|
|
306
|
+
(0, es_toolkit.merge)(target, update);
|
|
307
|
+
for (const key of undefinedKeys) target[key] = void 0;
|
|
308
|
+
};
|
|
309
|
+
|
|
295
310
|
//#endregion
|
|
296
311
|
//#region src/configuration.ts
|
|
297
312
|
const TsKeyword = {
|
|
@@ -373,6 +388,7 @@ var CodeGenConfig = class {
|
|
|
373
388
|
onFormatTypeName: (_typeName, _rawTypeName, _schemaType) => {},
|
|
374
389
|
onFormatRouteName: (_routeInfo, _templateRouteName) => {}
|
|
375
390
|
};
|
|
391
|
+
resolvedSwaggerSchema;
|
|
376
392
|
defaultResponseType;
|
|
377
393
|
singleHttpClient = false;
|
|
378
394
|
httpClientType = HTTP_CLIENT.FETCH;
|
|
@@ -602,8 +618,8 @@ var CodeGenConfig = class {
|
|
|
602
618
|
];
|
|
603
619
|
templateExtensions = [".eta", ".ejs"];
|
|
604
620
|
constructor({ codeGenConstructs, primitiveTypeConstructs, constants, templateInfos, hooks, ...otherConfig }) {
|
|
605
|
-
|
|
606
|
-
|
|
621
|
+
objectAssign(this.Ts, codeGenConstructs);
|
|
622
|
+
objectAssign(this.primitiveTypes, primitiveTypeConstructs);
|
|
607
623
|
this.defaultResponseType = this.Ts.Keyword.Void;
|
|
608
624
|
this.update({
|
|
609
625
|
...otherConfig,
|
|
@@ -623,16 +639,21 @@ var CodeGenConfig = class {
|
|
|
623
639
|
this.componentTypeNameResolver = new ComponentTypeNameResolver(this, []);
|
|
624
640
|
}
|
|
625
641
|
update = (update) => {
|
|
626
|
-
|
|
642
|
+
objectAssign(this, update);
|
|
627
643
|
if (this.enumNamesAsValues) this.extractEnums = true;
|
|
628
644
|
};
|
|
629
645
|
};
|
|
630
646
|
|
|
647
|
+
//#endregion
|
|
648
|
+
//#region src/util/pascal-case.ts
|
|
649
|
+
function pascalCase(value) {
|
|
650
|
+
return (0, es_toolkit_compat.upperFirst)((0, es_toolkit_compat.camelCase)(value));
|
|
651
|
+
}
|
|
652
|
+
|
|
631
653
|
//#endregion
|
|
632
654
|
//#region src/schema-components-map.ts
|
|
633
655
|
var SchemaComponentsMap = class {
|
|
634
656
|
_data = [];
|
|
635
|
-
config;
|
|
636
657
|
constructor(config) {
|
|
637
658
|
this.config = config;
|
|
638
659
|
}
|
|
@@ -645,18 +666,27 @@ var SchemaComponentsMap = class {
|
|
|
645
666
|
parseRef = (ref) => {
|
|
646
667
|
return ref.split("/");
|
|
647
668
|
};
|
|
648
|
-
|
|
669
|
+
createComponentDraft($ref, rawTypeData) {
|
|
670
|
+
if (yummies_type_guard.typeGuard.isObject(rawTypeData) && rawTypeData.typeName && rawTypeData.rawTypeData && rawTypeData.$ref) return rawTypeData;
|
|
649
671
|
const parsed = this.parseRef($ref);
|
|
650
|
-
const
|
|
672
|
+
const [, rawPointer = ""] = $ref.split("#");
|
|
673
|
+
const pointerParts = (rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}`).split("/").filter(Boolean);
|
|
674
|
+
const typeName = pointerParts.at(-1) || parsed.at(-1) || "Unknown";
|
|
675
|
+
const rawComponentName = pointerParts.at(-2) || parsed[parsed.length - 2] || "schemas";
|
|
676
|
+
return {
|
|
651
677
|
$ref,
|
|
652
|
-
typeName
|
|
678
|
+
typeName,
|
|
653
679
|
rawTypeData,
|
|
654
|
-
componentName:
|
|
680
|
+
componentName: rawComponentName === "definitions" ? "schemas" : rawComponentName,
|
|
655
681
|
typeData: null
|
|
656
682
|
};
|
|
683
|
+
}
|
|
684
|
+
createComponent($ref, rawTypeData, addAtStart) {
|
|
685
|
+
const componentSchema = this.createComponentDraft($ref, rawTypeData);
|
|
657
686
|
const usageComponent = this.config.hooks.onCreateComponent(componentSchema) || componentSchema;
|
|
658
687
|
const refIndex = this._data.findIndex((c) => c.$ref === $ref);
|
|
659
|
-
if (refIndex === -1) this._data.
|
|
688
|
+
if (refIndex === -1) if (addAtStart) this._data.unshift(usageComponent);
|
|
689
|
+
else this._data.push(usageComponent);
|
|
660
690
|
else this._data[refIndex] = usageComponent;
|
|
661
691
|
return usageComponent;
|
|
662
692
|
}
|
|
@@ -667,7 +697,19 @@ var SchemaComponentsMap = class {
|
|
|
667
697
|
return this._data.filter((it) => componentNames.some((componentName) => it.$ref.startsWith(`#/components/${componentName}`)));
|
|
668
698
|
}
|
|
669
699
|
get = ($ref) => {
|
|
670
|
-
|
|
700
|
+
const localFound = this._data.find((c) => c.$ref === $ref) || null;
|
|
701
|
+
if (localFound != null) return localFound;
|
|
702
|
+
const { resolvedSwaggerSchema } = this.config;
|
|
703
|
+
if (resolvedSwaggerSchema.isLocalRef($ref)) return null;
|
|
704
|
+
const foundByRef = resolvedSwaggerSchema.getRef($ref);
|
|
705
|
+
const refDetails = resolvedSwaggerSchema.getRefDetails($ref);
|
|
706
|
+
if (foundByRef != null) {
|
|
707
|
+
const componentDraft = this.createComponentDraft($ref, foundByRef);
|
|
708
|
+
componentDraft.typeName = this.config.hooks.onFormatExternalTypeName?.(componentDraft.typeName, refDetails) || componentDraft.typeName;
|
|
709
|
+
if (this._data.some((component) => component.typeName === componentDraft.typeName)) componentDraft.typeName = this.config.hooks.onFixDuplicateExternalTypeName?.(componentDraft.typeName, refDetails, this._data.map((it) => it.typeName)) ?? `${pascalCase(refDetails.externalOpenapiFileName || "External")}${componentDraft.typeName}`;
|
|
710
|
+
return this.createComponent($ref, componentDraft);
|
|
711
|
+
}
|
|
712
|
+
return null;
|
|
671
713
|
};
|
|
672
714
|
enumsFirst() {
|
|
673
715
|
this._data.sort((a, b) => {
|
|
@@ -703,10 +745,14 @@ var SchemaFormatters = class {
|
|
|
703
745
|
$content: parsedSchema.content,
|
|
704
746
|
content: this.config.Ts.UnionType(parsedSchema.content.map(({ value }) => value))
|
|
705
747
|
};
|
|
748
|
+
const escapedContent = parsedSchema.content.map((item) => ({
|
|
749
|
+
...item,
|
|
750
|
+
description: item.description ? this.escapeJSDocContent(item.description) : ""
|
|
751
|
+
}));
|
|
706
752
|
return {
|
|
707
753
|
...parsedSchema,
|
|
708
754
|
$content: parsedSchema.content,
|
|
709
|
-
content: this.config.Ts.EnumFieldsWrapper(
|
|
755
|
+
content: this.config.Ts.EnumFieldsWrapper(escapedContent)
|
|
710
756
|
};
|
|
711
757
|
},
|
|
712
758
|
[SCHEMA_TYPES$1.OBJECT]: (parsedSchema) => {
|
|
@@ -748,11 +794,16 @@ var SchemaFormatters = class {
|
|
|
748
794
|
const schemaType = (0, es_toolkit_compat.get)(parsedSchema, ["schemaType"]) || (0, es_toolkit_compat.get)(parsedSchema, ["$parsed", "schemaType"]);
|
|
749
795
|
return (0, es_toolkit_compat.get)(this, [formatType, schemaType])?.(parsedSchema) || parsedSchema;
|
|
750
796
|
};
|
|
797
|
+
escapeJSDocContent = (content) => {
|
|
798
|
+
if (content === void 0) return "";
|
|
799
|
+
return (typeof content === "string" ? content : String(content)).replace(/\*\//g, "*\\/");
|
|
800
|
+
};
|
|
751
801
|
formatDescription = (description, inline) => {
|
|
752
802
|
if (!description) return "";
|
|
753
|
-
|
|
754
|
-
if (
|
|
755
|
-
return
|
|
803
|
+
const escapedDescription = this.escapeJSDocContent(description);
|
|
804
|
+
if (!escapedDescription.includes("\n")) return escapedDescription;
|
|
805
|
+
if (inline) return (0, es_toolkit.compact)(escapedDescription.split(/\n/g).map((part) => part.trim())).join(" ");
|
|
806
|
+
return escapedDescription.replace(/\n$/g, "");
|
|
756
807
|
};
|
|
757
808
|
formatObjectContent = (content) => {
|
|
758
809
|
const fields = [];
|
|
@@ -1316,17 +1367,15 @@ var SchemaParser = class {
|
|
|
1316
1367
|
schemaFormatters;
|
|
1317
1368
|
schemaUtils;
|
|
1318
1369
|
templatesWorker;
|
|
1319
|
-
schemaWalker;
|
|
1320
1370
|
typeName;
|
|
1321
1371
|
schema;
|
|
1322
|
-
schemaPath
|
|
1372
|
+
schemaPath;
|
|
1323
1373
|
constructor(schemaParserFabric, { typeName, schema, schemaPath } = {}) {
|
|
1324
1374
|
this.schemaParserFabric = schemaParserFabric;
|
|
1325
1375
|
this.config = schemaParserFabric.config;
|
|
1326
1376
|
this.templatesWorker = schemaParserFabric.templatesWorker;
|
|
1327
1377
|
this.schemaComponentsMap = schemaParserFabric.schemaComponentsMap;
|
|
1328
1378
|
this.typeNameFormatter = schemaParserFabric.typeNameFormatter;
|
|
1329
|
-
this.schemaWalker = schemaParserFabric.schemaWalker;
|
|
1330
1379
|
this.schemaFormatters = schemaParserFabric.schemaFormatters;
|
|
1331
1380
|
this.schemaUtils = schemaParserFabric.schemaUtils;
|
|
1332
1381
|
this.typeName = typeName || null;
|
|
@@ -1421,24 +1470,13 @@ var SchemaParser = class {
|
|
|
1421
1470
|
};
|
|
1422
1471
|
};
|
|
1423
1472
|
|
|
1424
|
-
//#endregion
|
|
1425
|
-
//#region src/util/pascal-case.ts
|
|
1426
|
-
function pascalCase(value) {
|
|
1427
|
-
return (0, es_toolkit_compat.upperFirst)((0, es_toolkit_compat.camelCase)(value));
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
1473
|
//#endregion
|
|
1431
1474
|
//#region src/schema-parser/schema-utils.ts
|
|
1432
1475
|
var SchemaUtils = class {
|
|
1433
|
-
config
|
|
1434
|
-
schemaComponentsMap;
|
|
1435
|
-
typeNameFormatter;
|
|
1436
|
-
schemaWalker;
|
|
1437
|
-
constructor({ config, schemaComponentsMap, typeNameFormatter, schemaWalker }) {
|
|
1476
|
+
constructor(config, schemaComponentsMap, typeNameFormatter) {
|
|
1438
1477
|
this.config = config;
|
|
1439
1478
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
1440
1479
|
this.typeNameFormatter = typeNameFormatter;
|
|
1441
|
-
this.schemaWalker = schemaWalker;
|
|
1442
1480
|
}
|
|
1443
1481
|
getRequiredProperties = (schema) => {
|
|
1444
1482
|
return (0, es_toolkit.uniq)(schema && Array.isArray(schema.required) && schema.required || []);
|
|
@@ -1584,14 +1622,12 @@ var SchemaParserFabric = class {
|
|
|
1584
1622
|
schemaFormatters;
|
|
1585
1623
|
templatesWorker;
|
|
1586
1624
|
schemaUtils;
|
|
1587
|
-
|
|
1588
|
-
constructor(config, templatesWorker, schemaComponentsMap, typeNameFormatter, schemaWalker) {
|
|
1625
|
+
constructor(config, templatesWorker, schemaComponentsMap, typeNameFormatter) {
|
|
1589
1626
|
this.config = config;
|
|
1590
1627
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
1591
1628
|
this.typeNameFormatter = typeNameFormatter;
|
|
1592
1629
|
this.templatesWorker = templatesWorker;
|
|
1593
|
-
this.
|
|
1594
|
-
this.schemaUtils = new SchemaUtils(this);
|
|
1630
|
+
this.schemaUtils = new SchemaUtils(this.config, this.schemaComponentsMap, this.typeNameFormatter);
|
|
1595
1631
|
this.schemaFormatters = new SchemaFormatters(this);
|
|
1596
1632
|
}
|
|
1597
1633
|
createSchemaParser = ({ schema, typeName, schemaPath }) => {
|
|
@@ -1676,12 +1712,7 @@ const CONTENT_KIND = {
|
|
|
1676
1712
|
TEXT: "TEXT"
|
|
1677
1713
|
};
|
|
1678
1714
|
var SchemaRoutes = class {
|
|
1679
|
-
config;
|
|
1680
|
-
schemaParserFabric;
|
|
1681
1715
|
schemaUtils;
|
|
1682
|
-
typeNameFormatter;
|
|
1683
|
-
schemaComponentsMap;
|
|
1684
|
-
templatesWorker;
|
|
1685
1716
|
FORM_DATA_TYPES = [];
|
|
1686
1717
|
routes = [];
|
|
1687
1718
|
hasSecurityRoutes = false;
|
|
@@ -1690,10 +1721,10 @@ var SchemaRoutes = class {
|
|
|
1690
1721
|
constructor(config, schemaParserFabric, schemaComponentsMap, templatesWorker, typeNameFormatter) {
|
|
1691
1722
|
this.config = config;
|
|
1692
1723
|
this.schemaParserFabric = schemaParserFabric;
|
|
1693
|
-
this.schemaUtils = this.schemaParserFabric.schemaUtils;
|
|
1694
|
-
this.typeNameFormatter = typeNameFormatter;
|
|
1695
1724
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
1696
1725
|
this.templatesWorker = templatesWorker;
|
|
1726
|
+
this.typeNameFormatter = typeNameFormatter;
|
|
1727
|
+
this.schemaUtils = this.schemaParserFabric.schemaUtils;
|
|
1697
1728
|
this.FORM_DATA_TYPES = (0, es_toolkit.uniq)([this.schemaUtils.getSchemaType({
|
|
1698
1729
|
type: "string",
|
|
1699
1730
|
format: "file"
|
|
@@ -1702,11 +1733,16 @@ var SchemaRoutes = class {
|
|
|
1702
1733
|
format: "binary"
|
|
1703
1734
|
})]);
|
|
1704
1735
|
}
|
|
1705
|
-
createRequestsMap = (routesByMethod) => {
|
|
1736
|
+
createRequestsMap = (resolvedSwaggerSchema, routesByMethod) => {
|
|
1706
1737
|
const parameters = (0, es_toolkit_compat.get)(routesByMethod, "parameters");
|
|
1707
1738
|
const result = {};
|
|
1708
1739
|
for (const [method, requestInfo] of Object.entries(routesByMethod)) {
|
|
1709
|
-
if (method.startsWith("x-") || ["parameters"
|
|
1740
|
+
if (method.startsWith("x-") || ["parameters"].includes(method)) continue;
|
|
1741
|
+
if (method === "$ref") {
|
|
1742
|
+
const refData = resolvedSwaggerSchema.getRef(requestInfo);
|
|
1743
|
+
if (yummies_type_guard.typeGuard.isObject(refData)) Object.assign(result, this.createRequestsMap(resolvedSwaggerSchema, refData));
|
|
1744
|
+
continue;
|
|
1745
|
+
}
|
|
1710
1746
|
result[method] = {
|
|
1711
1747
|
...requestInfo,
|
|
1712
1748
|
parameters: (0, es_toolkit.compact)([...parameters || [], ...requestInfo.parameters || []])
|
|
@@ -1775,7 +1811,7 @@ var SchemaRoutes = class {
|
|
|
1775
1811
|
for (const parameter of parameters || []) {
|
|
1776
1812
|
const refTypeInfo = this.schemaParserFabric.schemaUtils.getSchemaRefType(parameter);
|
|
1777
1813
|
let routeParam = null;
|
|
1778
|
-
if (refTypeInfo?.rawTypeData
|
|
1814
|
+
if (!!refTypeInfo?.rawTypeData && typeof refTypeInfo === "object" && refTypeInfo?.rawTypeData.in) {
|
|
1779
1815
|
if (!routeParams[refTypeInfo.rawTypeData.in]) routeParams[refTypeInfo.rawTypeData.in] = [];
|
|
1780
1816
|
routeParam = {
|
|
1781
1817
|
...refTypeInfo.rawTypeData,
|
|
@@ -1845,10 +1881,11 @@ var SchemaRoutes = class {
|
|
|
1845
1881
|
}
|
|
1846
1882
|
return defaultType || this.config.Ts.Keyword.Any;
|
|
1847
1883
|
};
|
|
1848
|
-
getRequestInfoTypes = ({ requestInfos, parsedSchemas, operationId, defaultType }) => {
|
|
1884
|
+
getRequestInfoTypes = ({ requestInfos, parsedSchemas, operationId, defaultType, resolvedSwaggerSchema }) => {
|
|
1849
1885
|
const result = [];
|
|
1850
1886
|
for (const [status, requestInfo] of Object.entries(requestInfos || {})) {
|
|
1851
1887
|
const contentTypes = this.getContentTypes([requestInfo], operationId);
|
|
1888
|
+
const links = this.getRouteLinksFromResponse(resolvedSwaggerSchema, requestInfo, status);
|
|
1852
1889
|
result.push({
|
|
1853
1890
|
...requestInfo || {},
|
|
1854
1891
|
contentTypes,
|
|
@@ -1860,21 +1897,48 @@ var SchemaRoutes = class {
|
|
|
1860
1897
|
defaultType
|
|
1861
1898
|
})),
|
|
1862
1899
|
description: this.schemaParserFabric.schemaFormatters.formatDescription(requestInfo.description || "", true),
|
|
1900
|
+
links,
|
|
1863
1901
|
status: Number.isNaN(+status) ? status : +status,
|
|
1864
1902
|
isSuccess: this.isSuccessStatus(status)
|
|
1865
1903
|
});
|
|
1866
1904
|
}
|
|
1867
1905
|
return result;
|
|
1868
1906
|
};
|
|
1869
|
-
|
|
1907
|
+
getRouteLinksFromResponse = (resolvedSwaggerSchema, responseInfo, status) => {
|
|
1908
|
+
const links = (0, es_toolkit_compat.get)(responseInfo, "links");
|
|
1909
|
+
if (!yummies_type_guard.typeGuard.isObject(links)) return [];
|
|
1910
|
+
return (0, es_toolkit_compat.reduce)(links, (acc, linkInfo, linkName) => {
|
|
1911
|
+
if (!yummies_type_guard.typeGuard.isObject(linkInfo)) return acc;
|
|
1912
|
+
let normalizedLinkInfo = linkInfo;
|
|
1913
|
+
if (typeof linkInfo.$ref === "string") {
|
|
1914
|
+
const refData = resolvedSwaggerSchema.getRef(linkInfo.$ref);
|
|
1915
|
+
if (yummies_type_guard.typeGuard.isObject(refData)) normalizedLinkInfo = refData;
|
|
1916
|
+
}
|
|
1917
|
+
const operationId = typeof normalizedLinkInfo.operationId === "string" ? normalizedLinkInfo.operationId : void 0;
|
|
1918
|
+
const operationRef = typeof normalizedLinkInfo.operationRef === "string" ? normalizedLinkInfo.operationRef : typeof linkInfo.$ref === "string" ? linkInfo.$ref : void 0;
|
|
1919
|
+
if (!operationId && !operationRef) return acc;
|
|
1920
|
+
const parameters = yummies_type_guard.typeGuard.isObject(normalizedLinkInfo.parameters) ? (0, es_toolkit.mapValues)(normalizedLinkInfo.parameters, (value) => String(value)) : void 0;
|
|
1921
|
+
acc.push({
|
|
1922
|
+
status: Number.isNaN(+status) ? status : +status,
|
|
1923
|
+
name: String(linkName),
|
|
1924
|
+
operationId,
|
|
1925
|
+
operationRef,
|
|
1926
|
+
parameters
|
|
1927
|
+
});
|
|
1928
|
+
return acc;
|
|
1929
|
+
}, []);
|
|
1930
|
+
};
|
|
1931
|
+
getResponseBodyInfo = (routeInfo, parsedSchemas, resolvedSwaggerSchema) => {
|
|
1870
1932
|
const { produces, operationId, responses } = routeInfo;
|
|
1871
1933
|
const contentTypes = this.getContentTypes(responses, [...produces || [], routeInfo["x-accepts"]]);
|
|
1872
1934
|
const responseInfos = this.getRequestInfoTypes({
|
|
1873
1935
|
requestInfos: responses,
|
|
1874
1936
|
parsedSchemas,
|
|
1875
1937
|
operationId,
|
|
1876
|
-
defaultType: this.config.defaultResponseType
|
|
1938
|
+
defaultType: this.config.defaultResponseType,
|
|
1939
|
+
resolvedSwaggerSchema
|
|
1877
1940
|
});
|
|
1941
|
+
const links = responseInfos.flatMap((responseInfo) => responseInfo.links || []);
|
|
1878
1942
|
const successResponse = responseInfos.find((response) => response.isSuccess);
|
|
1879
1943
|
const errorResponses = responseInfos.filter((response) => !response.isSuccess && response.type !== this.config.Ts.Keyword.Any);
|
|
1880
1944
|
const handleResponseHeaders = (src) => {
|
|
@@ -1887,6 +1951,7 @@ var SchemaRoutes = class {
|
|
|
1887
1951
|
return {
|
|
1888
1952
|
contentTypes,
|
|
1889
1953
|
responses: responseInfos,
|
|
1954
|
+
links,
|
|
1890
1955
|
success: {
|
|
1891
1956
|
schema: successResponse,
|
|
1892
1957
|
type: successResponse?.type || this.config.Ts.Keyword.Any
|
|
@@ -2057,7 +2122,7 @@ var SchemaRoutes = class {
|
|
|
2057
2122
|
const { routeNameDuplicatesMap, templatesToRender } = this.config;
|
|
2058
2123
|
const routeNameTemplate = templatesToRender.routeName;
|
|
2059
2124
|
const routeNameFromTemplate = this.templatesWorker.renderTemplate(routeNameTemplate, { routeInfo: rawRouteInfo });
|
|
2060
|
-
const routeName = this.config.hooks.onFormatRouteName(rawRouteInfo, routeNameFromTemplate) || routeNameFromTemplate;
|
|
2125
|
+
const routeName = this.config.hooks.onFormatRouteName?.(rawRouteInfo, routeNameFromTemplate) || routeNameFromTemplate;
|
|
2061
2126
|
const duplicateIdentifier = `${moduleName}|${routeName}`;
|
|
2062
2127
|
if (routeNameDuplicatesMap.has(duplicateIdentifier)) {
|
|
2063
2128
|
routeNameDuplicatesMap.set(duplicateIdentifier, routeNameDuplicatesMap.get(duplicateIdentifier) + 1);
|
|
@@ -2069,10 +2134,10 @@ var SchemaRoutes = class {
|
|
|
2069
2134
|
original: routeName,
|
|
2070
2135
|
duplicate: duplicates > 1
|
|
2071
2136
|
};
|
|
2072
|
-
return this.config.hooks.onCreateRouteName(routeNameInfo, rawRouteInfo) || routeNameInfo;
|
|
2137
|
+
return this.config.hooks.onCreateRouteName?.(routeNameInfo, rawRouteInfo) || routeNameInfo;
|
|
2073
2138
|
};
|
|
2074
|
-
parseRouteInfo = (rawRouteName, routeInfo, method,
|
|
2075
|
-
const { security: globalSecurity } = usageSchema;
|
|
2139
|
+
parseRouteInfo = (rawRouteName, routeInfo, method, resolvedSwaggerSchema, parsedSchemas) => {
|
|
2140
|
+
const { security: globalSecurity } = resolvedSwaggerSchema.usageSchema;
|
|
2076
2141
|
const { moduleNameIndex, moduleNameFirstTag, extractRequestParams } = this.config;
|
|
2077
2142
|
const { operationId, requestBody, security, parameters, summary, description, tags, responses, requestBodyName, produces, consumes, ...otherInfo } = routeInfo;
|
|
2078
2143
|
const { route, pathParams: pathParamsFromRouteName, queryParams: queryParamsFromRouteName } = this.parseRouteName(rawRouteName);
|
|
@@ -2089,7 +2154,7 @@ var SchemaRoutes = class {
|
|
|
2089
2154
|
description: pathArgSchema.description
|
|
2090
2155
|
}));
|
|
2091
2156
|
const pathArgsNames = pathArgs.map((arg) => arg.name);
|
|
2092
|
-
const responseBodyInfo = this.getResponseBodyInfo(routeInfo, parsedSchemas);
|
|
2157
|
+
const responseBodyInfo = this.getResponseBodyInfo(routeInfo, parsedSchemas, resolvedSwaggerSchema);
|
|
2093
2158
|
const rawRouteInfo = {
|
|
2094
2159
|
...otherInfo,
|
|
2095
2160
|
pathArgs,
|
|
@@ -2098,6 +2163,7 @@ var SchemaRoutes = class {
|
|
|
2098
2163
|
route: rawRouteName,
|
|
2099
2164
|
moduleName,
|
|
2100
2165
|
responsesTypes: responseBodyInfo.responses,
|
|
2166
|
+
links: responseBodyInfo.links,
|
|
2101
2167
|
description,
|
|
2102
2168
|
tags,
|
|
2103
2169
|
summary,
|
|
@@ -2193,13 +2259,13 @@ var SchemaRoutes = class {
|
|
|
2193
2259
|
raw: rawRouteInfo
|
|
2194
2260
|
};
|
|
2195
2261
|
};
|
|
2196
|
-
attachSchema = (
|
|
2262
|
+
attachSchema = (resolvedSwaggerSchema, parsedSchemas) => {
|
|
2197
2263
|
this.config.routeNameDuplicatesMap.clear();
|
|
2198
|
-
const pathsEntries = Object.entries(usageSchema.paths || {});
|
|
2264
|
+
const pathsEntries = Object.entries(resolvedSwaggerSchema.usageSchema.paths || {});
|
|
2199
2265
|
for (const [rawRouteName, routeInfoByMethodsMap] of pathsEntries) {
|
|
2200
|
-
const routeInfosMap = this.createRequestsMap(routeInfoByMethodsMap);
|
|
2266
|
+
const routeInfosMap = this.createRequestsMap(resolvedSwaggerSchema, routeInfoByMethodsMap);
|
|
2201
2267
|
for (const [method, routeInfo] of Object.entries(routeInfosMap)) {
|
|
2202
|
-
const parsedRouteInfo = this.parseRouteInfo(rawRouteName, routeInfo, method,
|
|
2268
|
+
const parsedRouteInfo = this.parseRouteInfo(rawRouteName, routeInfo, method, resolvedSwaggerSchema, parsedSchemas);
|
|
2203
2269
|
const processedRouteInfo = this.config.hooks.onCreateRoute(parsedRouteInfo);
|
|
2204
2270
|
if (processedRouteInfo !== false) {
|
|
2205
2271
|
const route = processedRouteInfo || parsedRouteInfo;
|
|
@@ -2253,30 +2319,353 @@ var SchemaRoutes = class {
|
|
|
2253
2319
|
};
|
|
2254
2320
|
|
|
2255
2321
|
//#endregion
|
|
2256
|
-
//#region src/schema
|
|
2257
|
-
var
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2322
|
+
//#region src/resolved-swagger-schema.ts
|
|
2323
|
+
var ResolvedSwaggerSchema = class ResolvedSwaggerSchema {
|
|
2324
|
+
parsedRefsCache = /* @__PURE__ */ new Map();
|
|
2325
|
+
externalSchemaCache = /* @__PURE__ */ new Map();
|
|
2326
|
+
httpMethodSegments = new Set([
|
|
2327
|
+
"get",
|
|
2328
|
+
"put",
|
|
2329
|
+
"post",
|
|
2330
|
+
"delete",
|
|
2331
|
+
"patch",
|
|
2332
|
+
"options",
|
|
2333
|
+
"head",
|
|
2334
|
+
"trace",
|
|
2335
|
+
"parameters"
|
|
2336
|
+
]);
|
|
2337
|
+
normalizeRef(ref) {
|
|
2338
|
+
let normalizedRef = ref;
|
|
2339
|
+
normalizedRef = normalizedRef.replace(/\/#(?=\/)/, "#");
|
|
2340
|
+
normalizedRef = normalizedRef.replace(/#(?!\/)/, "#/");
|
|
2341
|
+
return normalizedRef;
|
|
2342
|
+
}
|
|
2343
|
+
createEscapedPathsRefVariant(ref) {
|
|
2344
|
+
const [prefix = "", rawPointer = ""] = this.normalizeRef(ref).split("#");
|
|
2345
|
+
const pointer = rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}`;
|
|
2346
|
+
if (!pointer.startsWith("/paths/") || pointer.startsWith("/paths/~1")) return null;
|
|
2347
|
+
const rest = pointer.slice(7);
|
|
2348
|
+
if (!rest) return null;
|
|
2349
|
+
const parts = rest.split("/");
|
|
2350
|
+
const last = parts.at(-1)?.toLowerCase() || "";
|
|
2351
|
+
const hasTailSegment = this.httpMethodSegments.has(last);
|
|
2352
|
+
const pathParts = hasTailSegment ? parts.slice(0, -1) : parts;
|
|
2353
|
+
const tail = hasTailSegment ? `/${parts.at(-1)}` : "";
|
|
2354
|
+
if (!pathParts.length) return null;
|
|
2355
|
+
return `${prefix}#/paths/${`~1${pathParts.join("/").replace(/\//g, "~1")}`}${tail}`;
|
|
2356
|
+
}
|
|
2357
|
+
isHttpUrl(value) {
|
|
2358
|
+
return /^https?:\/\//i.test(value);
|
|
2359
|
+
}
|
|
2360
|
+
getRemoteRequestHeaders() {
|
|
2361
|
+
return Object.assign({}, this.config.authorizationToken ? { Authorization: this.config.authorizationToken } : {}, this.config.requestOptions?.headers || {});
|
|
2362
|
+
}
|
|
2363
|
+
stripHash(urlOrPath) {
|
|
2364
|
+
return urlOrPath.split("#")[0] || urlOrPath;
|
|
2365
|
+
}
|
|
2366
|
+
extractRefsFromSchema(schema) {
|
|
2367
|
+
const refs = /* @__PURE__ */ new Set();
|
|
2368
|
+
const walk = (node) => {
|
|
2369
|
+
if (!node || typeof node !== "object") return;
|
|
2370
|
+
if (Array.isArray(node)) {
|
|
2371
|
+
for (const item of node) walk(item);
|
|
2372
|
+
return;
|
|
2373
|
+
}
|
|
2374
|
+
const recordNode = node;
|
|
2375
|
+
if (typeof recordNode.$ref === "string") refs.add(recordNode.$ref);
|
|
2376
|
+
for (const value of Object.values(recordNode)) walk(value);
|
|
2377
|
+
};
|
|
2378
|
+
walk(schema);
|
|
2379
|
+
return [...refs];
|
|
2380
|
+
}
|
|
2381
|
+
async fetchRemoteSchemaDocument(url) {
|
|
2382
|
+
try {
|
|
2383
|
+
const response = await fetch(url, { headers: this.getRemoteRequestHeaders() });
|
|
2384
|
+
if (!response.ok) return null;
|
|
2385
|
+
const content = await response.text();
|
|
2386
|
+
try {
|
|
2387
|
+
const parsed = JSON.parse(content);
|
|
2388
|
+
if (parsed && typeof parsed === "object") return parsed;
|
|
2389
|
+
} catch {
|
|
2390
|
+
const parsed = yaml.parse(content);
|
|
2391
|
+
if (parsed && typeof parsed === "object") return parsed;
|
|
2392
|
+
}
|
|
2393
|
+
} catch (e) {
|
|
2394
|
+
consola.default.debug(e);
|
|
2395
|
+
}
|
|
2396
|
+
return null;
|
|
2397
|
+
}
|
|
2398
|
+
async warmUpRemoteSchemasCache() {
|
|
2399
|
+
if (typeof this.config.url !== "string" || !this.isHttpUrl(this.config.url)) return;
|
|
2400
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2401
|
+
const queue = [this.stripHash(this.config.url)];
|
|
2402
|
+
while (queue.length > 0) {
|
|
2403
|
+
const currentUrl = queue.shift();
|
|
2404
|
+
if (!currentUrl || visited.has(currentUrl)) continue;
|
|
2405
|
+
visited.add(currentUrl);
|
|
2406
|
+
if (this.externalSchemaCache.has(currentUrl)) continue;
|
|
2407
|
+
const schema = await this.fetchRemoteSchemaDocument(currentUrl);
|
|
2408
|
+
if (!schema) continue;
|
|
2409
|
+
this.externalSchemaCache.set(currentUrl, schema);
|
|
2410
|
+
for (const ref of this.extractRefsFromSchema(schema)) {
|
|
2411
|
+
const normalizedRef = this.normalizeRef(ref);
|
|
2412
|
+
if (normalizedRef.startsWith("#")) continue;
|
|
2413
|
+
const [externalPath = ""] = normalizedRef.split("#");
|
|
2414
|
+
if (!externalPath) continue;
|
|
2415
|
+
let absoluteUrl = "";
|
|
2416
|
+
try {
|
|
2417
|
+
absoluteUrl = this.isHttpUrl(externalPath) ? this.stripHash(externalPath) : this.stripHash(new URL(externalPath, currentUrl).toString());
|
|
2418
|
+
} catch (e) {
|
|
2419
|
+
consola.default.debug(e);
|
|
2420
|
+
}
|
|
2421
|
+
if (absoluteUrl && !visited.has(absoluteUrl)) queue.push(absoluteUrl);
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
collectRemoteAbsoluteRefCandidates(ref) {
|
|
2426
|
+
if (!ref || this.isHttpUrl(ref) || ref.startsWith("#")) return [];
|
|
2427
|
+
const [relativePath = "", rawPointer = ""] = this.normalizeRef(ref).split("#");
|
|
2428
|
+
if (!relativePath) return [];
|
|
2429
|
+
const pointer = rawPointer ? rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}` : "";
|
|
2430
|
+
const bases = /* @__PURE__ */ new Set();
|
|
2431
|
+
if (typeof this.config.url === "string" && this.isHttpUrl(this.config.url)) bases.add(this.config.url);
|
|
2432
|
+
for (const cachedUrl of this.externalSchemaCache.keys()) if (this.isHttpUrl(cachedUrl)) bases.add(cachedUrl);
|
|
2433
|
+
for (const resolver of this.resolvers) try {
|
|
2434
|
+
const resolverPaths = typeof resolver.paths === "function" ? resolver.paths() : [];
|
|
2435
|
+
for (const resolverPath of resolverPaths) if (typeof resolverPath === "string" && this.isHttpUrl(resolverPath)) bases.add(resolverPath);
|
|
2436
|
+
} catch (e) {
|
|
2437
|
+
consola.default.debug(e);
|
|
2438
|
+
}
|
|
2439
|
+
const results = /* @__PURE__ */ new Set();
|
|
2440
|
+
for (const base of bases) try {
|
|
2441
|
+
const absolutePath = new URL(relativePath, base).toString();
|
|
2442
|
+
results.add(pointer ? `${absolutePath}#${pointer}` : absolutePath);
|
|
2443
|
+
} catch (e) {
|
|
2444
|
+
consola.default.debug(e);
|
|
2445
|
+
}
|
|
2446
|
+
return [...results];
|
|
2447
|
+
}
|
|
2448
|
+
resolveFromRemoteSchemaCache(absoluteRef) {
|
|
2449
|
+
const [externalPath = "", rawPointer = ""] = this.normalizeRef(absoluteRef).split("#");
|
|
2450
|
+
if (!externalPath || !this.isHttpUrl(externalPath)) return null;
|
|
2451
|
+
const schema = this.externalSchemaCache.get(this.stripHash(externalPath));
|
|
2452
|
+
if (!schema) return null;
|
|
2453
|
+
const pointer = rawPointer ? rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}` : "/";
|
|
2454
|
+
const resolved = this.resolveJsonPointer(schema, pointer);
|
|
2455
|
+
if (resolved == null) return null;
|
|
2456
|
+
return this.absolutizeLocalRefs(resolved, this.stripHash(externalPath));
|
|
2457
|
+
}
|
|
2458
|
+
constructor(config, usageSchema, originalSchema, resolvers) {
|
|
2263
2459
|
this.config = config;
|
|
2264
|
-
this.
|
|
2460
|
+
this.usageSchema = usageSchema;
|
|
2461
|
+
this.originalSchema = originalSchema;
|
|
2462
|
+
this.resolvers = resolvers;
|
|
2463
|
+
this.usageSchema = usageSchema;
|
|
2464
|
+
this.originalSchema = originalSchema;
|
|
2465
|
+
}
|
|
2466
|
+
getRefDetails(ref) {
|
|
2467
|
+
const normalizedRef = this.normalizeRef(ref);
|
|
2468
|
+
if (!this.parsedRefsCache.has(ref)) {
|
|
2469
|
+
const isLocal = normalizedRef.startsWith("#");
|
|
2470
|
+
if (isLocal) this.parsedRefsCache.set(ref, {
|
|
2471
|
+
ref: normalizedRef,
|
|
2472
|
+
isLocal,
|
|
2473
|
+
externalUrlOrPath: null
|
|
2474
|
+
});
|
|
2475
|
+
else {
|
|
2476
|
+
const externalUrlOrPath = normalizedRef.split("#")[0] || "";
|
|
2477
|
+
let externalOpenapiFileName = externalUrlOrPath.replace(/\/$/, "").split("/").at(-1) || "";
|
|
2478
|
+
if (externalOpenapiFileName.endsWith(".json") || externalOpenapiFileName.endsWith(".yaml")) externalOpenapiFileName = externalOpenapiFileName.slice(0, -5);
|
|
2479
|
+
else if (externalOpenapiFileName.endsWith(".yml")) externalOpenapiFileName = externalOpenapiFileName.slice(0, -4);
|
|
2480
|
+
this.parsedRefsCache.set(ref, {
|
|
2481
|
+
ref: normalizedRef,
|
|
2482
|
+
isLocal,
|
|
2483
|
+
externalUrlOrPath,
|
|
2484
|
+
externalOpenapiFileName
|
|
2485
|
+
});
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
const cachedRef = this.parsedRefsCache.get(ref);
|
|
2489
|
+
if (cachedRef) return cachedRef;
|
|
2490
|
+
if (normalizedRef.startsWith("#")) return {
|
|
2491
|
+
ref: normalizedRef,
|
|
2492
|
+
isLocal: true,
|
|
2493
|
+
externalUrlOrPath: null
|
|
2494
|
+
};
|
|
2495
|
+
return {
|
|
2496
|
+
ref: normalizedRef,
|
|
2497
|
+
isLocal: false,
|
|
2498
|
+
externalUrlOrPath: normalizedRef.split("#")[0] || null,
|
|
2499
|
+
externalOpenapiFileName: ""
|
|
2500
|
+
};
|
|
2501
|
+
}
|
|
2502
|
+
isLocalRef(ref) {
|
|
2503
|
+
return this.getRefDetails(ref).isLocal;
|
|
2504
|
+
}
|
|
2505
|
+
getRef(ref) {
|
|
2506
|
+
if (!ref) return null;
|
|
2507
|
+
const normalizedRef = this.normalizeRef(ref);
|
|
2508
|
+
const escapedPathsRefVariant = this.createEscapedPathsRefVariant(ref);
|
|
2509
|
+
if (normalizedRef !== ref) {
|
|
2510
|
+
const resolvedByNormalizedRef = this.tryToResolveRef(normalizedRef);
|
|
2511
|
+
if (resolvedByNormalizedRef) return this.normalizeResolvedExternalSchemaRef(normalizedRef, resolvedByNormalizedRef);
|
|
2512
|
+
}
|
|
2513
|
+
if (escapedPathsRefVariant) {
|
|
2514
|
+
const resolvedByEscapedPathsRef = this.tryToResolveRef(escapedPathsRefVariant);
|
|
2515
|
+
if (resolvedByEscapedPathsRef) return this.normalizeResolvedExternalSchemaRef(escapedPathsRefVariant, resolvedByEscapedPathsRef);
|
|
2516
|
+
}
|
|
2517
|
+
const remoteAbsoluteCandidates = this.collectRemoteAbsoluteRefCandidates(ref);
|
|
2518
|
+
for (const remoteAbsoluteRef of remoteAbsoluteCandidates) {
|
|
2519
|
+
const resolvedFromRemoteCache = this.resolveFromRemoteSchemaCache(remoteAbsoluteRef);
|
|
2520
|
+
if (resolvedFromRemoteCache) return resolvedFromRemoteCache;
|
|
2521
|
+
const resolvedByRemoteAbsoluteRef = this.tryToResolveRef(remoteAbsoluteRef);
|
|
2522
|
+
if (resolvedByRemoteAbsoluteRef) return this.normalizeResolvedExternalSchemaRef(remoteAbsoluteRef, resolvedByRemoteAbsoluteRef);
|
|
2523
|
+
}
|
|
2524
|
+
const resolvedByOrigRef = this.tryToResolveRef(ref);
|
|
2525
|
+
if (resolvedByOrigRef) return this.normalizeResolvedExternalSchemaRef(ref, resolvedByOrigRef);
|
|
2526
|
+
if (/#[a-z]/.test(ref)) {
|
|
2527
|
+
const fixedRef = ref.replace(/#[a-z]/, (match) => {
|
|
2528
|
+
const [hashtag, char] = match.split("");
|
|
2529
|
+
return `${hashtag}/${char}`;
|
|
2530
|
+
});
|
|
2531
|
+
const resolvedByFixedRef = this.tryToResolveRef(fixedRef);
|
|
2532
|
+
if (resolvedByFixedRef) return this.normalizeResolvedExternalSchemaRef(fixedRef, resolvedByFixedRef);
|
|
2533
|
+
}
|
|
2534
|
+
return this.tryToResolveRefFromFile(normalizedRef);
|
|
2535
|
+
}
|
|
2536
|
+
tryToResolveRef(ref) {
|
|
2537
|
+
if (!this.resolvers || !ref) return null;
|
|
2538
|
+
for (const resolver of this.resolvers) try {
|
|
2539
|
+
return resolver.get(ref);
|
|
2540
|
+
} catch (e) {
|
|
2541
|
+
consola.default.debug(e);
|
|
2542
|
+
}
|
|
2543
|
+
return null;
|
|
2544
|
+
}
|
|
2545
|
+
readExternalSchema(filePath) {
|
|
2546
|
+
if (this.externalSchemaCache.has(filePath)) return this.externalSchemaCache.get(filePath) || null;
|
|
2547
|
+
if (!node_fs.existsSync(filePath)) return null;
|
|
2548
|
+
try {
|
|
2549
|
+
const content = node_fs.readFileSync(filePath, "utf8");
|
|
2550
|
+
const parsed = JSON.parse(content);
|
|
2551
|
+
this.externalSchemaCache.set(filePath, parsed);
|
|
2552
|
+
return parsed;
|
|
2553
|
+
} catch {
|
|
2554
|
+
try {
|
|
2555
|
+
const content = node_fs.readFileSync(filePath, "utf8");
|
|
2556
|
+
const parsed = yaml.parse(content);
|
|
2557
|
+
if (parsed && typeof parsed === "object") {
|
|
2558
|
+
this.externalSchemaCache.set(filePath, parsed);
|
|
2559
|
+
return parsed;
|
|
2560
|
+
}
|
|
2561
|
+
} catch (e) {
|
|
2562
|
+
consola.default.debug(e);
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
return null;
|
|
2566
|
+
}
|
|
2567
|
+
resolveJsonPointer(source, pointer) {
|
|
2568
|
+
if (!source || typeof source !== "object") return null;
|
|
2569
|
+
if (!pointer || pointer === "/") return source;
|
|
2570
|
+
const tokens = pointer.replace(/^\/+/, "").split("/").filter(Boolean).map((part) => decodeURIComponent(part.replace(/~1/g, "/").replace(/~0/g, "~")));
|
|
2571
|
+
let current = source;
|
|
2572
|
+
for (const token of tokens) {
|
|
2573
|
+
if (!current || typeof current !== "object") return null;
|
|
2574
|
+
current = current[token];
|
|
2575
|
+
}
|
|
2576
|
+
return current ?? null;
|
|
2577
|
+
}
|
|
2578
|
+
absolutizeLocalRefs(value, externalPath) {
|
|
2579
|
+
if (value == null || typeof value !== "object") return value;
|
|
2580
|
+
const cloneValue = structuredClone(value);
|
|
2581
|
+
const walk = (node) => {
|
|
2582
|
+
if (!node || typeof node !== "object") return;
|
|
2583
|
+
if (Array.isArray(node)) {
|
|
2584
|
+
for (const item of node) walk(item);
|
|
2585
|
+
return;
|
|
2586
|
+
}
|
|
2587
|
+
const recordNode = node;
|
|
2588
|
+
if (typeof recordNode.$ref === "string" && recordNode.$ref.startsWith("#")) recordNode.$ref = `${externalPath}${this.normalizeRef(recordNode.$ref)}`;
|
|
2589
|
+
for (const nested of Object.values(recordNode)) walk(nested);
|
|
2590
|
+
};
|
|
2591
|
+
walk(cloneValue);
|
|
2592
|
+
return cloneValue;
|
|
2593
|
+
}
|
|
2594
|
+
normalizeResolvedExternalSchemaRef(ref, resolved) {
|
|
2595
|
+
const normalizedRef = this.normalizeRef(ref);
|
|
2596
|
+
if (normalizedRef.startsWith("#")) return resolved;
|
|
2597
|
+
const externalPath = normalizedRef.split("#")[0] || "";
|
|
2598
|
+
if (!externalPath) return resolved;
|
|
2599
|
+
return this.absolutizeLocalRefs(resolved, externalPath);
|
|
2600
|
+
}
|
|
2601
|
+
collectExternalRefCandidates(externalPath) {
|
|
2602
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
2603
|
+
if (/^https?:\/\//i.test(externalPath)) return [];
|
|
2604
|
+
if (node_path.default.isAbsolute(externalPath)) candidates.add(externalPath);
|
|
2605
|
+
const inputPath = this.config.input;
|
|
2606
|
+
if (typeof inputPath === "string" && inputPath) candidates.add(node_path.default.resolve(node_path.default.dirname(inputPath), externalPath));
|
|
2607
|
+
for (const resolver of this.resolvers) try {
|
|
2608
|
+
const resolverPaths = typeof resolver.paths === "function" ? resolver.paths() : [];
|
|
2609
|
+
for (const resolverPath of resolverPaths) {
|
|
2610
|
+
if (typeof resolverPath !== "string") continue;
|
|
2611
|
+
if (/^https?:\/\//i.test(resolverPath)) continue;
|
|
2612
|
+
candidates.add(node_path.default.resolve(node_path.default.dirname(resolverPath), externalPath));
|
|
2613
|
+
}
|
|
2614
|
+
} catch (e) {
|
|
2615
|
+
consola.default.debug(e);
|
|
2616
|
+
}
|
|
2617
|
+
return [...candidates];
|
|
2618
|
+
}
|
|
2619
|
+
tryToResolveRefFromFile(ref) {
|
|
2620
|
+
if (!ref || ref.startsWith("#")) return null;
|
|
2621
|
+
const [externalPath = "", rawPointer = ""] = ref.split("#");
|
|
2622
|
+
if (!externalPath) return null;
|
|
2623
|
+
const pointer = rawPointer ? rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}` : "/";
|
|
2624
|
+
const candidates = this.collectExternalRefCandidates(externalPath);
|
|
2625
|
+
for (const candidate of candidates) {
|
|
2626
|
+
const schema = this.readExternalSchema(candidate);
|
|
2627
|
+
const resolved = this.resolveJsonPointer(schema, pointer);
|
|
2628
|
+
if (resolved != null) return this.absolutizeLocalRefs(resolved, externalPath);
|
|
2629
|
+
}
|
|
2630
|
+
return null;
|
|
2631
|
+
}
|
|
2632
|
+
static async create(config, usageSchema, originalSchema) {
|
|
2633
|
+
const resolvers = [];
|
|
2634
|
+
const options = {
|
|
2635
|
+
continueOnError: true,
|
|
2636
|
+
mutateInputSchema: true,
|
|
2637
|
+
dereference: {},
|
|
2638
|
+
validate: {
|
|
2639
|
+
schema: false,
|
|
2640
|
+
spec: false
|
|
2641
|
+
},
|
|
2642
|
+
resolve: {
|
|
2643
|
+
external: true,
|
|
2644
|
+
http: {
|
|
2645
|
+
...config.requestOptions,
|
|
2646
|
+
headers: Object.assign({}, config.authorizationToken ? { Authorization: config.authorizationToken } : {}, config.requestOptions?.headers ?? {})
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
};
|
|
2650
|
+
try {
|
|
2651
|
+
resolvers.push(await _apidevtools_swagger_parser.default.resolve(originalSchema, options));
|
|
2652
|
+
} catch (e) {
|
|
2653
|
+
consola.default.debug(e);
|
|
2654
|
+
}
|
|
2655
|
+
try {
|
|
2656
|
+
resolvers.push(await _apidevtools_swagger_parser.default.resolve(usageSchema, options));
|
|
2657
|
+
} catch (e) {
|
|
2658
|
+
consola.default.debug(e);
|
|
2659
|
+
}
|
|
2660
|
+
try {
|
|
2661
|
+
resolvers.push(await _apidevtools_swagger_parser.default.resolve(config.url || config.input || config.spec, options));
|
|
2662
|
+
} catch (e) {
|
|
2663
|
+
consola.default.debug(e);
|
|
2664
|
+
}
|
|
2665
|
+
const resolvedSwaggerSchema = new ResolvedSwaggerSchema(config, usageSchema, originalSchema, resolvers);
|
|
2666
|
+
await resolvedSwaggerSchema.warmUpRemoteSchemasCache();
|
|
2667
|
+
return resolvedSwaggerSchema;
|
|
2265
2668
|
}
|
|
2266
|
-
addSchema = (name, schema) => {
|
|
2267
|
-
this.schemas.set(name, structuredClone(schema));
|
|
2268
|
-
};
|
|
2269
|
-
_isLocalRef = (ref) => {
|
|
2270
|
-
return ref.startsWith("#");
|
|
2271
|
-
};
|
|
2272
|
-
_isRemoteRef = (ref) => {
|
|
2273
|
-
return ref.startsWith("http://") || ref.startsWith("https://");
|
|
2274
|
-
};
|
|
2275
|
-
_getRefDataFromSchema = (schema, ref) => {
|
|
2276
|
-
const refData = (0, es_toolkit_compat.get)(schema, ref.replace("#", "").split("/"));
|
|
2277
|
-
if (refData) this.caches.set(ref, refData);
|
|
2278
|
-
return refData;
|
|
2279
|
-
};
|
|
2280
2669
|
};
|
|
2281
2670
|
|
|
2282
2671
|
//#endregion
|
|
@@ -2313,10 +2702,15 @@ var SwaggerSchemaResolver = class {
|
|
|
2313
2702
|
}
|
|
2314
2703
|
async create() {
|
|
2315
2704
|
const { spec, patch, input, url, authorizationToken } = this.config;
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2705
|
+
let swaggerSchemas;
|
|
2706
|
+
if (spec) swaggerSchemas = await this.convertSwaggerObject(spec, { patch });
|
|
2707
|
+
else {
|
|
2708
|
+
const swaggerSchemaFile = await this.fetchSwaggerSchemaFile(input, url, authorizationToken);
|
|
2709
|
+
const swaggerSchemaObject = this.processSwaggerSchemaFile(swaggerSchemaFile);
|
|
2710
|
+
swaggerSchemas = await this.convertSwaggerObject(swaggerSchemaObject, { patch });
|
|
2711
|
+
}
|
|
2712
|
+
this.fixSwaggerSchemas(swaggerSchemas);
|
|
2713
|
+
return ResolvedSwaggerSchema.create(this.config, swaggerSchemas.usageSchema, swaggerSchemas.originalSchema);
|
|
2320
2714
|
}
|
|
2321
2715
|
convertSwaggerObject(swaggerSchema, converterOptions) {
|
|
2322
2716
|
return new Promise((resolve) => {
|
|
@@ -2368,7 +2762,26 @@ var SwaggerSchemaResolver = class {
|
|
|
2368
2762
|
return yaml.parse(file);
|
|
2369
2763
|
}
|
|
2370
2764
|
}
|
|
2371
|
-
|
|
2765
|
+
normalizeRefValue(ref) {
|
|
2766
|
+
const refWithoutSlashBeforeHash = ref.split("/#/").join("#/");
|
|
2767
|
+
const hashIndex = refWithoutSlashBeforeHash.indexOf("#");
|
|
2768
|
+
if (hashIndex === -1) return refWithoutSlashBeforeHash;
|
|
2769
|
+
if (refWithoutSlashBeforeHash[hashIndex + 1] === "/") return refWithoutSlashBeforeHash;
|
|
2770
|
+
return `${refWithoutSlashBeforeHash.slice(0, hashIndex + 1)}/${refWithoutSlashBeforeHash.slice(hashIndex + 1)}`;
|
|
2771
|
+
}
|
|
2772
|
+
normalizeRefsInSchema(schema) {
|
|
2773
|
+
if (!schema || typeof schema !== "object") return;
|
|
2774
|
+
if (Array.isArray(schema)) {
|
|
2775
|
+
for (const value of schema) this.normalizeRefsInSchema(value);
|
|
2776
|
+
return;
|
|
2777
|
+
}
|
|
2778
|
+
const objectSchema = schema;
|
|
2779
|
+
if (typeof objectSchema.$ref === "string") objectSchema.$ref = this.normalizeRefValue(objectSchema.$ref);
|
|
2780
|
+
for (const value of Object.values(objectSchema)) this.normalizeRefsInSchema(value);
|
|
2781
|
+
}
|
|
2782
|
+
fixSwaggerSchemas({ usageSchema, originalSchema }) {
|
|
2783
|
+
this.normalizeRefsInSchema(usageSchema);
|
|
2784
|
+
this.normalizeRefsInSchema(originalSchema);
|
|
2372
2785
|
const usagePaths = (0, es_toolkit_compat.get)(usageSchema, "paths") || {};
|
|
2373
2786
|
const originalPaths = (0, es_toolkit_compat.get)(originalSchema, "paths") || {};
|
|
2374
2787
|
for (const [route, usagePathObject] of Object.entries(usagePaths)) {
|
|
@@ -2377,9 +2790,10 @@ var SwaggerSchemaResolver = class {
|
|
|
2377
2790
|
const originalRouteInfo = (0, es_toolkit_compat.get)(originalPathObject, methodName) || {};
|
|
2378
2791
|
const usageRouteParams = (0, es_toolkit_compat.get)(usageRouteInfo, "parameters") || [];
|
|
2379
2792
|
const originalRouteParams = (0, es_toolkit_compat.get)(originalRouteInfo, "parameters") || [];
|
|
2793
|
+
const usageAsOpenapiv2 = usageRouteInfo;
|
|
2380
2794
|
if (typeof usageRouteInfo === "object") {
|
|
2381
|
-
|
|
2382
|
-
|
|
2795
|
+
usageAsOpenapiv2.consumes = (0, es_toolkit.uniq)((0, es_toolkit.compact)([...usageAsOpenapiv2.consumes || [], ...originalRouteInfo.consumes || []]));
|
|
2796
|
+
usageAsOpenapiv2.produces = (0, es_toolkit.uniq)((0, es_toolkit.compact)([...usageAsOpenapiv2.produces || [], ...originalRouteInfo.produces || []]));
|
|
2383
2797
|
}
|
|
2384
2798
|
for (const originalRouteParam of originalRouteParams) if (!usageRouteParams.find((param) => originalRouteParam.in === param.in && originalRouteParam.name === param.name)) usageRouteParams.push(originalRouteParam);
|
|
2385
2799
|
}
|
|
@@ -2554,7 +2968,7 @@ var TypeNameFormatter = class {
|
|
|
2554
2968
|
]).join("_");
|
|
2555
2969
|
if (this.formattedModelNamesMap.has(hashKey)) return this.formattedModelNamesMap.get(hashKey);
|
|
2556
2970
|
const formattedName = (0, es_toolkit_compat.startCase)(`${typePrefix}_${this.fixModelName(name, { type: schemaType })}_${typeSuffix}`).replace(/\s/g, "");
|
|
2557
|
-
const formattedResultName = this.config.hooks.onFormatTypeName(formattedName, name, schemaType) || formattedName;
|
|
2971
|
+
const formattedResultName = this.config.hooks.onFormatTypeName?.(formattedName, name, schemaType) || formattedName;
|
|
2558
2972
|
this.formattedModelNamesMap.set(hashKey, formattedResultName);
|
|
2559
2973
|
return formattedResultName;
|
|
2560
2974
|
};
|
|
@@ -2653,38 +3067,35 @@ var CodeGenProcess = class {
|
|
|
2653
3067
|
fileSystem;
|
|
2654
3068
|
codeFormatter;
|
|
2655
3069
|
templatesWorker;
|
|
2656
|
-
schemaWalker;
|
|
2657
3070
|
javascriptTranslator;
|
|
3071
|
+
swaggerRefs;
|
|
2658
3072
|
constructor(config) {
|
|
2659
3073
|
this.config = new CodeGenConfig(config);
|
|
2660
3074
|
this.fileSystem = new FileSystem();
|
|
2661
3075
|
this.swaggerSchemaResolver = new SwaggerSchemaResolver(this.config, this.fileSystem);
|
|
2662
|
-
this.schemaWalker = new SchemaWalker(this.config, this.swaggerSchemaResolver);
|
|
2663
3076
|
this.schemaComponentsMap = new SchemaComponentsMap(this.config);
|
|
2664
3077
|
this.typeNameFormatter = new TypeNameFormatter(this.config);
|
|
2665
3078
|
this.templatesWorker = new TemplatesWorker(this.config, this.fileSystem, this.getRenderTemplateData);
|
|
2666
3079
|
this.codeFormatter = new CodeFormatter(this.config);
|
|
2667
|
-
this.schemaParserFabric = new SchemaParserFabric(this.config, this.templatesWorker, this.schemaComponentsMap, this.typeNameFormatter
|
|
3080
|
+
this.schemaParserFabric = new SchemaParserFabric(this.config, this.templatesWorker, this.schemaComponentsMap, this.typeNameFormatter);
|
|
2668
3081
|
this.schemaRoutes = new SchemaRoutes(this.config, this.schemaParserFabric, this.schemaComponentsMap, this.templatesWorker, this.typeNameFormatter);
|
|
2669
3082
|
this.javascriptTranslator = new JavascriptTranslator(this.config, this.codeFormatter);
|
|
2670
3083
|
}
|
|
2671
3084
|
async start() {
|
|
2672
3085
|
this.config.update({ templatePaths: this.templatesWorker.getTemplatePaths(this.config) });
|
|
2673
3086
|
this.config.update({ templatesToRender: this.templatesWorker.getTemplates(this.config) });
|
|
2674
|
-
const
|
|
2675
|
-
this.swaggerSchemaResolver.fixSwaggerSchema(swagger);
|
|
3087
|
+
const resolvedSwaggerSchema = await this.swaggerSchemaResolver.create();
|
|
2676
3088
|
this.config.update({
|
|
2677
|
-
|
|
2678
|
-
|
|
3089
|
+
resolvedSwaggerSchema,
|
|
3090
|
+
swaggerSchema: resolvedSwaggerSchema.usageSchema,
|
|
3091
|
+
originalSchema: resolvedSwaggerSchema.originalSchema
|
|
2679
3092
|
});
|
|
2680
|
-
this.schemaWalker.addSchema("$usage", swagger.usageSchema);
|
|
2681
|
-
this.schemaWalker.addSchema("$original", swagger.originalSchema);
|
|
2682
3093
|
consola.consola.info("start generating your typescript api");
|
|
2683
|
-
this.config.update(this.config.hooks.onInit(this.config, this) || this.config);
|
|
2684
|
-
if (this.config.swaggerSchema)
|
|
2685
|
-
if (this.config.originalSchema)
|
|
3094
|
+
this.config.update(this.config.hooks.onInit?.(this.config, this) || this.config);
|
|
3095
|
+
if (this.config.swaggerSchema) resolvedSwaggerSchema.usageSchema = this.config.swaggerSchema;
|
|
3096
|
+
if (this.config.originalSchema) resolvedSwaggerSchema.originalSchema = this.config.originalSchema;
|
|
2686
3097
|
this.schemaComponentsMap.clear();
|
|
2687
|
-
for (const [componentName, component] of Object.entries(
|
|
3098
|
+
for (const [componentName, component] of Object.entries(resolvedSwaggerSchema.usageSchema.components || {})) for (const [typeName, rawTypeData] of Object.entries(component)) this.schemaComponentsMap.createComponent(this.schemaComponentsMap.createRef([
|
|
2688
3099
|
"components",
|
|
2689
3100
|
componentName,
|
|
2690
3101
|
typeName
|
|
@@ -2696,12 +3107,9 @@ var CodeGenProcess = class {
|
|
|
2696
3107
|
schemaComponent.typeData = parsed;
|
|
2697
3108
|
return parsed;
|
|
2698
3109
|
});
|
|
2699
|
-
this.schemaRoutes.attachSchema(
|
|
2700
|
-
usageSchema: swagger.usageSchema,
|
|
2701
|
-
parsedSchemas
|
|
2702
|
-
});
|
|
3110
|
+
this.schemaRoutes.attachSchema(resolvedSwaggerSchema, parsedSchemas);
|
|
2703
3111
|
const rawConfiguration = {
|
|
2704
|
-
apiConfig: this.createApiConfig(
|
|
3112
|
+
apiConfig: this.createApiConfig(resolvedSwaggerSchema.usageSchema),
|
|
2705
3113
|
config: this.config,
|
|
2706
3114
|
modelTypes: this.collectModelTypes(),
|
|
2707
3115
|
hasSecurityRoutes: this.schemaRoutes.hasSecurityRoutes,
|
|
@@ -2715,7 +3123,7 @@ var CodeGenProcess = class {
|
|
|
2715
3123
|
customTranslator: this.config.customTranslator ? new this.config.customTranslator() : null,
|
|
2716
3124
|
utils: this.getRenderTemplateData().utils
|
|
2717
3125
|
};
|
|
2718
|
-
const configuration = this.config.hooks.onPrepareConfig(rawConfiguration) || rawConfiguration;
|
|
3126
|
+
const configuration = this.config.hooks.onPrepareConfig?.(rawConfiguration) || rawConfiguration;
|
|
2719
3127
|
if (this.fileSystem.pathIsExist(this.config.output)) {
|
|
2720
3128
|
if (this.config.cleanOutput) {
|
|
2721
3129
|
consola.consola.debug("cleaning dir", this.config.output);
|
|
@@ -2749,6 +3157,7 @@ var CodeGenProcess = class {
|
|
|
2749
3157
|
utils: {
|
|
2750
3158
|
Ts: this.config.Ts,
|
|
2751
3159
|
formatDescription: this.schemaParserFabric.schemaFormatters.formatDescription,
|
|
3160
|
+
escapeJSDocContent: this.schemaParserFabric.schemaFormatters.escapeJSDocContent,
|
|
2752
3161
|
internalCase: es_toolkit_compat.camelCase,
|
|
2753
3162
|
classNameCase: pascalCase,
|
|
2754
3163
|
pascalCase,
|
|
@@ -2966,7 +3375,7 @@ var TemplatesGenConfig = class {
|
|
|
2966
3375
|
this.update(config);
|
|
2967
3376
|
}
|
|
2968
3377
|
update = (update) => {
|
|
2969
|
-
|
|
3378
|
+
objectAssign(this, update);
|
|
2970
3379
|
};
|
|
2971
3380
|
};
|
|
2972
3381
|
|
|
@@ -3153,4 +3562,4 @@ Object.defineProperty(exports, 'version', {
|
|
|
3153
3562
|
return version;
|
|
3154
3563
|
}
|
|
3155
3564
|
});
|
|
3156
|
-
//# sourceMappingURL=generate-templates-
|
|
3565
|
+
//# sourceMappingURL=generate-templates-BlSkwa8l.cjs.map
|