swagger-typescript-api 13.2.18 → 13.3.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/dist/cli.cjs +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/{generate-templates-C4JBmSNw.cjs → generate-templates-CAvEodGO.cjs} +495 -102
- package/dist/generate-templates-CAvEodGO.cjs.map +1 -0
- package/dist/{generate-templates-DGQlyLhe.mjs → generate-templates-P84KxC-K.mjs} +530 -139
- package/dist/generate-templates-P84KxC-K.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +136 -113
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +136 -113
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -8
- package/templates/base/route-docs.ejs +6 -0
- package/dist/generate-templates-C4JBmSNw.cjs.map +0 -1
- package/dist/generate-templates-DGQlyLhe.mjs.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.1";
|
|
227
231
|
var description = "Generate the API client for Fetch or Axios from an OpenAPI Specification";
|
|
228
232
|
|
|
229
233
|
//#endregion
|
|
@@ -384,6 +388,7 @@ var CodeGenConfig = class {
|
|
|
384
388
|
onFormatTypeName: (_typeName, _rawTypeName, _schemaType) => {},
|
|
385
389
|
onFormatRouteName: (_routeInfo, _templateRouteName) => {}
|
|
386
390
|
};
|
|
391
|
+
resolvedSwaggerSchema;
|
|
387
392
|
defaultResponseType;
|
|
388
393
|
singleHttpClient = false;
|
|
389
394
|
httpClientType = HTTP_CLIENT.FETCH;
|
|
@@ -639,11 +644,16 @@ var CodeGenConfig = class {
|
|
|
639
644
|
};
|
|
640
645
|
};
|
|
641
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
|
+
|
|
642
653
|
//#endregion
|
|
643
654
|
//#region src/schema-components-map.ts
|
|
644
655
|
var SchemaComponentsMap = class {
|
|
645
656
|
_data = [];
|
|
646
|
-
config;
|
|
647
657
|
constructor(config) {
|
|
648
658
|
this.config = config;
|
|
649
659
|
}
|
|
@@ -656,18 +666,27 @@ var SchemaComponentsMap = class {
|
|
|
656
666
|
parseRef = (ref) => {
|
|
657
667
|
return ref.split("/");
|
|
658
668
|
};
|
|
659
|
-
|
|
669
|
+
createComponentDraft($ref, rawTypeData) {
|
|
670
|
+
if (yummies_type_guard.typeGuard.isObject(rawTypeData) && rawTypeData.typeName && rawTypeData.rawTypeData && rawTypeData.$ref) return rawTypeData;
|
|
660
671
|
const parsed = this.parseRef($ref);
|
|
661
|
-
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 {
|
|
662
677
|
$ref,
|
|
663
|
-
typeName
|
|
678
|
+
typeName,
|
|
664
679
|
rawTypeData,
|
|
665
|
-
componentName:
|
|
680
|
+
componentName: rawComponentName === "definitions" ? "schemas" : rawComponentName,
|
|
666
681
|
typeData: null
|
|
667
682
|
};
|
|
683
|
+
}
|
|
684
|
+
createComponent($ref, rawTypeData, addAtStart) {
|
|
685
|
+
const componentSchema = this.createComponentDraft($ref, rawTypeData);
|
|
668
686
|
const usageComponent = this.config.hooks.onCreateComponent(componentSchema) || componentSchema;
|
|
669
687
|
const refIndex = this._data.findIndex((c) => c.$ref === $ref);
|
|
670
|
-
if (refIndex === -1) this._data.
|
|
688
|
+
if (refIndex === -1) if (addAtStart) this._data.unshift(usageComponent);
|
|
689
|
+
else this._data.push(usageComponent);
|
|
671
690
|
else this._data[refIndex] = usageComponent;
|
|
672
691
|
return usageComponent;
|
|
673
692
|
}
|
|
@@ -678,7 +697,19 @@ var SchemaComponentsMap = class {
|
|
|
678
697
|
return this._data.filter((it) => componentNames.some((componentName) => it.$ref.startsWith(`#/components/${componentName}`)));
|
|
679
698
|
}
|
|
680
699
|
get = ($ref) => {
|
|
681
|
-
|
|
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;
|
|
682
713
|
};
|
|
683
714
|
enumsFirst() {
|
|
684
715
|
this._data.sort((a, b) => {
|
|
@@ -964,7 +995,7 @@ var DiscriminatorSchemaParser = class extends MonoSchemaParser {
|
|
|
964
995
|
const mappingUsageKey = mappingPropertySchemaEnumKeysMap[mappingKey] || ts.StringValue(mappingKey);
|
|
965
996
|
if (ableToCreateMappingType) return ts.TypeWithGeneric(mappingTypeName, [mappingUsageKey, content]);
|
|
966
997
|
return ts.ExpressionGroup(ts.IntersectionType([ts.ObjectWrapper(ts.TypeField({
|
|
967
|
-
key: discriminator.propertyName,
|
|
998
|
+
key: ts.StringValue(discriminator.propertyName),
|
|
968
999
|
value: mappingUsageKey
|
|
969
1000
|
})), content]));
|
|
970
1001
|
};
|
|
@@ -1262,7 +1293,12 @@ var PrimitiveSchemaParser = class extends MonoSchemaParser {
|
|
|
1262
1293
|
}
|
|
1263
1294
|
if (Array.isArray(type) && type.length) contentType = this.schemaParser._complexSchemaParsers.oneOf({
|
|
1264
1295
|
...typeof this.schema === "object" ? this.schema : {},
|
|
1265
|
-
oneOf: type.map((
|
|
1296
|
+
oneOf: type.map((t) => {
|
|
1297
|
+
const branch = { type: t };
|
|
1298
|
+
Object.assign(branch, this.schema);
|
|
1299
|
+
branch.type = t;
|
|
1300
|
+
return branch;
|
|
1301
|
+
})
|
|
1266
1302
|
});
|
|
1267
1303
|
if (Array.isArray(items) && type === SCHEMA_TYPES$1.ARRAY) contentType = this.config.Ts.Tuple(items.map((item) => this.schemaParserFabric.createSchemaParser({
|
|
1268
1304
|
schema: item,
|
|
@@ -1336,7 +1372,6 @@ var SchemaParser = class {
|
|
|
1336
1372
|
schemaFormatters;
|
|
1337
1373
|
schemaUtils;
|
|
1338
1374
|
templatesWorker;
|
|
1339
|
-
schemaWalker;
|
|
1340
1375
|
typeName;
|
|
1341
1376
|
schema;
|
|
1342
1377
|
schemaPath;
|
|
@@ -1346,7 +1381,6 @@ var SchemaParser = class {
|
|
|
1346
1381
|
this.templatesWorker = schemaParserFabric.templatesWorker;
|
|
1347
1382
|
this.schemaComponentsMap = schemaParserFabric.schemaComponentsMap;
|
|
1348
1383
|
this.typeNameFormatter = schemaParserFabric.typeNameFormatter;
|
|
1349
|
-
this.schemaWalker = schemaParserFabric.schemaWalker;
|
|
1350
1384
|
this.schemaFormatters = schemaParserFabric.schemaFormatters;
|
|
1351
1385
|
this.schemaUtils = schemaParserFabric.schemaUtils;
|
|
1352
1386
|
this.typeName = typeName || null;
|
|
@@ -1441,24 +1475,13 @@ var SchemaParser = class {
|
|
|
1441
1475
|
};
|
|
1442
1476
|
};
|
|
1443
1477
|
|
|
1444
|
-
//#endregion
|
|
1445
|
-
//#region src/util/pascal-case.ts
|
|
1446
|
-
function pascalCase(value) {
|
|
1447
|
-
return (0, es_toolkit_compat.upperFirst)((0, es_toolkit_compat.camelCase)(value));
|
|
1448
|
-
}
|
|
1449
|
-
|
|
1450
1478
|
//#endregion
|
|
1451
1479
|
//#region src/schema-parser/schema-utils.ts
|
|
1452
1480
|
var SchemaUtils = class {
|
|
1453
|
-
config
|
|
1454
|
-
schemaComponentsMap;
|
|
1455
|
-
typeNameFormatter;
|
|
1456
|
-
schemaWalker;
|
|
1457
|
-
constructor({ config, schemaComponentsMap, typeNameFormatter, schemaWalker }) {
|
|
1481
|
+
constructor(config, schemaComponentsMap, typeNameFormatter) {
|
|
1458
1482
|
this.config = config;
|
|
1459
1483
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
1460
1484
|
this.typeNameFormatter = typeNameFormatter;
|
|
1461
|
-
this.schemaWalker = schemaWalker;
|
|
1462
1485
|
}
|
|
1463
1486
|
getRequiredProperties = (schema) => {
|
|
1464
1487
|
return (0, es_toolkit.uniq)(schema && Array.isArray(schema.required) && schema.required || []);
|
|
@@ -1604,14 +1627,12 @@ var SchemaParserFabric = class {
|
|
|
1604
1627
|
schemaFormatters;
|
|
1605
1628
|
templatesWorker;
|
|
1606
1629
|
schemaUtils;
|
|
1607
|
-
|
|
1608
|
-
constructor(config, templatesWorker, schemaComponentsMap, typeNameFormatter, schemaWalker) {
|
|
1630
|
+
constructor(config, templatesWorker, schemaComponentsMap, typeNameFormatter) {
|
|
1609
1631
|
this.config = config;
|
|
1610
1632
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
1611
1633
|
this.typeNameFormatter = typeNameFormatter;
|
|
1612
1634
|
this.templatesWorker = templatesWorker;
|
|
1613
|
-
this.
|
|
1614
|
-
this.schemaUtils = new SchemaUtils(this);
|
|
1635
|
+
this.schemaUtils = new SchemaUtils(this.config, this.schemaComponentsMap, this.typeNameFormatter);
|
|
1615
1636
|
this.schemaFormatters = new SchemaFormatters(this);
|
|
1616
1637
|
}
|
|
1617
1638
|
createSchemaParser = ({ schema, typeName, schemaPath }) => {
|
|
@@ -1696,12 +1717,7 @@ const CONTENT_KIND = {
|
|
|
1696
1717
|
TEXT: "TEXT"
|
|
1697
1718
|
};
|
|
1698
1719
|
var SchemaRoutes = class {
|
|
1699
|
-
config;
|
|
1700
|
-
schemaParserFabric;
|
|
1701
1720
|
schemaUtils;
|
|
1702
|
-
typeNameFormatter;
|
|
1703
|
-
schemaComponentsMap;
|
|
1704
|
-
templatesWorker;
|
|
1705
1721
|
FORM_DATA_TYPES = [];
|
|
1706
1722
|
routes = [];
|
|
1707
1723
|
hasSecurityRoutes = false;
|
|
@@ -1710,10 +1726,10 @@ var SchemaRoutes = class {
|
|
|
1710
1726
|
constructor(config, schemaParserFabric, schemaComponentsMap, templatesWorker, typeNameFormatter) {
|
|
1711
1727
|
this.config = config;
|
|
1712
1728
|
this.schemaParserFabric = schemaParserFabric;
|
|
1713
|
-
this.schemaUtils = this.schemaParserFabric.schemaUtils;
|
|
1714
|
-
this.typeNameFormatter = typeNameFormatter;
|
|
1715
1729
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
1716
1730
|
this.templatesWorker = templatesWorker;
|
|
1731
|
+
this.typeNameFormatter = typeNameFormatter;
|
|
1732
|
+
this.schemaUtils = this.schemaParserFabric.schemaUtils;
|
|
1717
1733
|
this.FORM_DATA_TYPES = (0, es_toolkit.uniq)([this.schemaUtils.getSchemaType({
|
|
1718
1734
|
type: "string",
|
|
1719
1735
|
format: "file"
|
|
@@ -1722,11 +1738,16 @@ var SchemaRoutes = class {
|
|
|
1722
1738
|
format: "binary"
|
|
1723
1739
|
})]);
|
|
1724
1740
|
}
|
|
1725
|
-
createRequestsMap = (routesByMethod) => {
|
|
1741
|
+
createRequestsMap = (resolvedSwaggerSchema, routesByMethod) => {
|
|
1726
1742
|
const parameters = (0, es_toolkit_compat.get)(routesByMethod, "parameters");
|
|
1727
1743
|
const result = {};
|
|
1728
1744
|
for (const [method, requestInfo] of Object.entries(routesByMethod)) {
|
|
1729
|
-
if (method.startsWith("x-") || ["parameters"
|
|
1745
|
+
if (method.startsWith("x-") || ["parameters"].includes(method)) continue;
|
|
1746
|
+
if (method === "$ref") {
|
|
1747
|
+
const refData = resolvedSwaggerSchema.getRef(requestInfo);
|
|
1748
|
+
if (yummies_type_guard.typeGuard.isObject(refData)) Object.assign(result, this.createRequestsMap(resolvedSwaggerSchema, refData));
|
|
1749
|
+
continue;
|
|
1750
|
+
}
|
|
1730
1751
|
result[method] = {
|
|
1731
1752
|
...requestInfo,
|
|
1732
1753
|
parameters: (0, es_toolkit.compact)([...parameters || [], ...requestInfo.parameters || []])
|
|
@@ -1795,7 +1816,7 @@ var SchemaRoutes = class {
|
|
|
1795
1816
|
for (const parameter of parameters || []) {
|
|
1796
1817
|
const refTypeInfo = this.schemaParserFabric.schemaUtils.getSchemaRefType(parameter);
|
|
1797
1818
|
let routeParam = null;
|
|
1798
|
-
if (refTypeInfo?.rawTypeData
|
|
1819
|
+
if (!!refTypeInfo?.rawTypeData && typeof refTypeInfo === "object" && refTypeInfo?.rawTypeData.in) {
|
|
1799
1820
|
if (!routeParams[refTypeInfo.rawTypeData.in]) routeParams[refTypeInfo.rawTypeData.in] = [];
|
|
1800
1821
|
routeParam = {
|
|
1801
1822
|
...refTypeInfo.rawTypeData,
|
|
@@ -1865,10 +1886,11 @@ var SchemaRoutes = class {
|
|
|
1865
1886
|
}
|
|
1866
1887
|
return defaultType || this.config.Ts.Keyword.Any;
|
|
1867
1888
|
};
|
|
1868
|
-
getRequestInfoTypes = ({ requestInfos, parsedSchemas, operationId, defaultType }) => {
|
|
1889
|
+
getRequestInfoTypes = ({ requestInfos, parsedSchemas, operationId, defaultType, resolvedSwaggerSchema }) => {
|
|
1869
1890
|
const result = [];
|
|
1870
1891
|
for (const [status, requestInfo] of Object.entries(requestInfos || {})) {
|
|
1871
1892
|
const contentTypes = this.getContentTypes([requestInfo], operationId);
|
|
1893
|
+
const links = this.getRouteLinksFromResponse(resolvedSwaggerSchema, requestInfo, status);
|
|
1872
1894
|
result.push({
|
|
1873
1895
|
...requestInfo || {},
|
|
1874
1896
|
contentTypes,
|
|
@@ -1880,21 +1902,48 @@ var SchemaRoutes = class {
|
|
|
1880
1902
|
defaultType
|
|
1881
1903
|
})),
|
|
1882
1904
|
description: this.schemaParserFabric.schemaFormatters.formatDescription(requestInfo.description || "", true),
|
|
1905
|
+
links,
|
|
1883
1906
|
status: Number.isNaN(+status) ? status : +status,
|
|
1884
1907
|
isSuccess: this.isSuccessStatus(status)
|
|
1885
1908
|
});
|
|
1886
1909
|
}
|
|
1887
1910
|
return result;
|
|
1888
1911
|
};
|
|
1889
|
-
|
|
1912
|
+
getRouteLinksFromResponse = (resolvedSwaggerSchema, responseInfo, status) => {
|
|
1913
|
+
const links = (0, es_toolkit_compat.get)(responseInfo, "links");
|
|
1914
|
+
if (!yummies_type_guard.typeGuard.isObject(links)) return [];
|
|
1915
|
+
return (0, es_toolkit_compat.reduce)(links, (acc, linkInfo, linkName) => {
|
|
1916
|
+
if (!yummies_type_guard.typeGuard.isObject(linkInfo)) return acc;
|
|
1917
|
+
let normalizedLinkInfo = linkInfo;
|
|
1918
|
+
if (typeof linkInfo.$ref === "string") {
|
|
1919
|
+
const refData = resolvedSwaggerSchema.getRef(linkInfo.$ref);
|
|
1920
|
+
if (yummies_type_guard.typeGuard.isObject(refData)) normalizedLinkInfo = refData;
|
|
1921
|
+
}
|
|
1922
|
+
const operationId = typeof normalizedLinkInfo.operationId === "string" ? normalizedLinkInfo.operationId : void 0;
|
|
1923
|
+
const operationRef = typeof normalizedLinkInfo.operationRef === "string" ? normalizedLinkInfo.operationRef : typeof linkInfo.$ref === "string" ? linkInfo.$ref : void 0;
|
|
1924
|
+
if (!operationId && !operationRef) return acc;
|
|
1925
|
+
const parameters = yummies_type_guard.typeGuard.isObject(normalizedLinkInfo.parameters) ? (0, es_toolkit.mapValues)(normalizedLinkInfo.parameters, (value) => String(value)) : void 0;
|
|
1926
|
+
acc.push({
|
|
1927
|
+
status: Number.isNaN(+status) ? status : +status,
|
|
1928
|
+
name: String(linkName),
|
|
1929
|
+
operationId,
|
|
1930
|
+
operationRef,
|
|
1931
|
+
parameters
|
|
1932
|
+
});
|
|
1933
|
+
return acc;
|
|
1934
|
+
}, []);
|
|
1935
|
+
};
|
|
1936
|
+
getResponseBodyInfo = (routeInfo, parsedSchemas, resolvedSwaggerSchema) => {
|
|
1890
1937
|
const { produces, operationId, responses } = routeInfo;
|
|
1891
1938
|
const contentTypes = this.getContentTypes(responses, [...produces || [], routeInfo["x-accepts"]]);
|
|
1892
1939
|
const responseInfos = this.getRequestInfoTypes({
|
|
1893
1940
|
requestInfos: responses,
|
|
1894
1941
|
parsedSchemas,
|
|
1895
1942
|
operationId,
|
|
1896
|
-
defaultType: this.config.defaultResponseType
|
|
1943
|
+
defaultType: this.config.defaultResponseType,
|
|
1944
|
+
resolvedSwaggerSchema
|
|
1897
1945
|
});
|
|
1946
|
+
const links = responseInfos.flatMap((responseInfo) => responseInfo.links || []);
|
|
1898
1947
|
const successResponse = responseInfos.find((response) => response.isSuccess);
|
|
1899
1948
|
const errorResponses = responseInfos.filter((response) => !response.isSuccess && response.type !== this.config.Ts.Keyword.Any);
|
|
1900
1949
|
const handleResponseHeaders = (src) => {
|
|
@@ -1907,6 +1956,7 @@ var SchemaRoutes = class {
|
|
|
1907
1956
|
return {
|
|
1908
1957
|
contentTypes,
|
|
1909
1958
|
responses: responseInfos,
|
|
1959
|
+
links,
|
|
1910
1960
|
success: {
|
|
1911
1961
|
schema: successResponse,
|
|
1912
1962
|
type: successResponse?.type || this.config.Ts.Keyword.Any
|
|
@@ -2077,7 +2127,7 @@ var SchemaRoutes = class {
|
|
|
2077
2127
|
const { routeNameDuplicatesMap, templatesToRender } = this.config;
|
|
2078
2128
|
const routeNameTemplate = templatesToRender.routeName;
|
|
2079
2129
|
const routeNameFromTemplate = this.templatesWorker.renderTemplate(routeNameTemplate, { routeInfo: rawRouteInfo });
|
|
2080
|
-
const routeName = this.config.hooks.onFormatRouteName(rawRouteInfo, routeNameFromTemplate) || routeNameFromTemplate;
|
|
2130
|
+
const routeName = this.config.hooks.onFormatRouteName?.(rawRouteInfo, routeNameFromTemplate) || routeNameFromTemplate;
|
|
2081
2131
|
const duplicateIdentifier = `${moduleName}|${routeName}`;
|
|
2082
2132
|
if (routeNameDuplicatesMap.has(duplicateIdentifier)) {
|
|
2083
2133
|
routeNameDuplicatesMap.set(duplicateIdentifier, routeNameDuplicatesMap.get(duplicateIdentifier) + 1);
|
|
@@ -2089,10 +2139,10 @@ var SchemaRoutes = class {
|
|
|
2089
2139
|
original: routeName,
|
|
2090
2140
|
duplicate: duplicates > 1
|
|
2091
2141
|
};
|
|
2092
|
-
return this.config.hooks.onCreateRouteName(routeNameInfo, rawRouteInfo) || routeNameInfo;
|
|
2142
|
+
return this.config.hooks.onCreateRouteName?.(routeNameInfo, rawRouteInfo) || routeNameInfo;
|
|
2093
2143
|
};
|
|
2094
|
-
parseRouteInfo = (rawRouteName, routeInfo, method,
|
|
2095
|
-
const { security: globalSecurity } = usageSchema;
|
|
2144
|
+
parseRouteInfo = (rawRouteName, routeInfo, method, resolvedSwaggerSchema, parsedSchemas) => {
|
|
2145
|
+
const { security: globalSecurity } = resolvedSwaggerSchema.usageSchema;
|
|
2096
2146
|
const { moduleNameIndex, moduleNameFirstTag, extractRequestParams } = this.config;
|
|
2097
2147
|
const { operationId, requestBody, security, parameters, summary, description, tags, responses, requestBodyName, produces, consumes, ...otherInfo } = routeInfo;
|
|
2098
2148
|
const { route, pathParams: pathParamsFromRouteName, queryParams: queryParamsFromRouteName } = this.parseRouteName(rawRouteName);
|
|
@@ -2109,7 +2159,7 @@ var SchemaRoutes = class {
|
|
|
2109
2159
|
description: pathArgSchema.description
|
|
2110
2160
|
}));
|
|
2111
2161
|
const pathArgsNames = pathArgs.map((arg) => arg.name);
|
|
2112
|
-
const responseBodyInfo = this.getResponseBodyInfo(routeInfo, parsedSchemas);
|
|
2162
|
+
const responseBodyInfo = this.getResponseBodyInfo(routeInfo, parsedSchemas, resolvedSwaggerSchema);
|
|
2113
2163
|
const rawRouteInfo = {
|
|
2114
2164
|
...otherInfo,
|
|
2115
2165
|
pathArgs,
|
|
@@ -2118,6 +2168,7 @@ var SchemaRoutes = class {
|
|
|
2118
2168
|
route: rawRouteName,
|
|
2119
2169
|
moduleName,
|
|
2120
2170
|
responsesTypes: responseBodyInfo.responses,
|
|
2171
|
+
links: responseBodyInfo.links,
|
|
2121
2172
|
description,
|
|
2122
2173
|
tags,
|
|
2123
2174
|
summary,
|
|
@@ -2213,13 +2264,13 @@ var SchemaRoutes = class {
|
|
|
2213
2264
|
raw: rawRouteInfo
|
|
2214
2265
|
};
|
|
2215
2266
|
};
|
|
2216
|
-
attachSchema = (
|
|
2267
|
+
attachSchema = (resolvedSwaggerSchema, parsedSchemas) => {
|
|
2217
2268
|
this.config.routeNameDuplicatesMap.clear();
|
|
2218
|
-
const pathsEntries = Object.entries(usageSchema.paths || {});
|
|
2269
|
+
const pathsEntries = Object.entries(resolvedSwaggerSchema.usageSchema.paths || {});
|
|
2219
2270
|
for (const [rawRouteName, routeInfoByMethodsMap] of pathsEntries) {
|
|
2220
|
-
const routeInfosMap = this.createRequestsMap(routeInfoByMethodsMap);
|
|
2271
|
+
const routeInfosMap = this.createRequestsMap(resolvedSwaggerSchema, routeInfoByMethodsMap);
|
|
2221
2272
|
for (const [method, routeInfo] of Object.entries(routeInfosMap)) {
|
|
2222
|
-
const parsedRouteInfo = this.parseRouteInfo(rawRouteName, routeInfo, method,
|
|
2273
|
+
const parsedRouteInfo = this.parseRouteInfo(rawRouteName, routeInfo, method, resolvedSwaggerSchema, parsedSchemas);
|
|
2223
2274
|
const processedRouteInfo = this.config.hooks.onCreateRoute(parsedRouteInfo);
|
|
2224
2275
|
if (processedRouteInfo !== false) {
|
|
2225
2276
|
const route = processedRouteInfo || parsedRouteInfo;
|
|
@@ -2273,30 +2324,353 @@ var SchemaRoutes = class {
|
|
|
2273
2324
|
};
|
|
2274
2325
|
|
|
2275
2326
|
//#endregion
|
|
2276
|
-
//#region src/schema
|
|
2277
|
-
var
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2327
|
+
//#region src/resolved-swagger-schema.ts
|
|
2328
|
+
var ResolvedSwaggerSchema = class ResolvedSwaggerSchema {
|
|
2329
|
+
parsedRefsCache = /* @__PURE__ */ new Map();
|
|
2330
|
+
externalSchemaCache = /* @__PURE__ */ new Map();
|
|
2331
|
+
httpMethodSegments = new Set([
|
|
2332
|
+
"get",
|
|
2333
|
+
"put",
|
|
2334
|
+
"post",
|
|
2335
|
+
"delete",
|
|
2336
|
+
"patch",
|
|
2337
|
+
"options",
|
|
2338
|
+
"head",
|
|
2339
|
+
"trace",
|
|
2340
|
+
"parameters"
|
|
2341
|
+
]);
|
|
2342
|
+
normalizeRef(ref) {
|
|
2343
|
+
let normalizedRef = ref;
|
|
2344
|
+
normalizedRef = normalizedRef.replace(/\/#(?=\/)/, "#");
|
|
2345
|
+
normalizedRef = normalizedRef.replace(/#(?!\/)/, "#/");
|
|
2346
|
+
return normalizedRef;
|
|
2347
|
+
}
|
|
2348
|
+
createEscapedPathsRefVariant(ref) {
|
|
2349
|
+
const [prefix = "", rawPointer = ""] = this.normalizeRef(ref).split("#");
|
|
2350
|
+
const pointer = rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}`;
|
|
2351
|
+
if (!pointer.startsWith("/paths/") || pointer.startsWith("/paths/~1")) return null;
|
|
2352
|
+
const rest = pointer.slice(7);
|
|
2353
|
+
if (!rest) return null;
|
|
2354
|
+
const parts = rest.split("/");
|
|
2355
|
+
const last = parts.at(-1)?.toLowerCase() || "";
|
|
2356
|
+
const hasTailSegment = this.httpMethodSegments.has(last);
|
|
2357
|
+
const pathParts = hasTailSegment ? parts.slice(0, -1) : parts;
|
|
2358
|
+
const tail = hasTailSegment ? `/${parts.at(-1)}` : "";
|
|
2359
|
+
if (!pathParts.length) return null;
|
|
2360
|
+
return `${prefix}#/paths/${`~1${pathParts.join("/").replace(/\//g, "~1")}`}${tail}`;
|
|
2361
|
+
}
|
|
2362
|
+
isHttpUrl(value) {
|
|
2363
|
+
return /^https?:\/\//i.test(value);
|
|
2364
|
+
}
|
|
2365
|
+
getRemoteRequestHeaders() {
|
|
2366
|
+
return Object.assign({}, this.config.authorizationToken ? { Authorization: this.config.authorizationToken } : {}, this.config.requestOptions?.headers || {});
|
|
2367
|
+
}
|
|
2368
|
+
stripHash(urlOrPath) {
|
|
2369
|
+
return urlOrPath.split("#")[0] || urlOrPath;
|
|
2370
|
+
}
|
|
2371
|
+
extractRefsFromSchema(schema) {
|
|
2372
|
+
const refs = /* @__PURE__ */ new Set();
|
|
2373
|
+
const walk = (node) => {
|
|
2374
|
+
if (!node || typeof node !== "object") return;
|
|
2375
|
+
if (Array.isArray(node)) {
|
|
2376
|
+
for (const item of node) walk(item);
|
|
2377
|
+
return;
|
|
2378
|
+
}
|
|
2379
|
+
const recordNode = node;
|
|
2380
|
+
if (typeof recordNode.$ref === "string") refs.add(recordNode.$ref);
|
|
2381
|
+
for (const value of Object.values(recordNode)) walk(value);
|
|
2382
|
+
};
|
|
2383
|
+
walk(schema);
|
|
2384
|
+
return [...refs];
|
|
2385
|
+
}
|
|
2386
|
+
async fetchRemoteSchemaDocument(url) {
|
|
2387
|
+
try {
|
|
2388
|
+
const response = await fetch(url, { headers: this.getRemoteRequestHeaders() });
|
|
2389
|
+
if (!response.ok) return null;
|
|
2390
|
+
const content = await response.text();
|
|
2391
|
+
try {
|
|
2392
|
+
const parsed = JSON.parse(content);
|
|
2393
|
+
if (parsed && typeof parsed === "object") return parsed;
|
|
2394
|
+
} catch {
|
|
2395
|
+
const parsed = yaml.parse(content);
|
|
2396
|
+
if (parsed && typeof parsed === "object") return parsed;
|
|
2397
|
+
}
|
|
2398
|
+
} catch (e) {
|
|
2399
|
+
consola.default.debug(e);
|
|
2400
|
+
}
|
|
2401
|
+
return null;
|
|
2402
|
+
}
|
|
2403
|
+
async warmUpRemoteSchemasCache() {
|
|
2404
|
+
if (typeof this.config.url !== "string" || !this.isHttpUrl(this.config.url)) return;
|
|
2405
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2406
|
+
const queue = [this.stripHash(this.config.url)];
|
|
2407
|
+
while (queue.length > 0) {
|
|
2408
|
+
const currentUrl = queue.shift();
|
|
2409
|
+
if (!currentUrl || visited.has(currentUrl)) continue;
|
|
2410
|
+
visited.add(currentUrl);
|
|
2411
|
+
if (this.externalSchemaCache.has(currentUrl)) continue;
|
|
2412
|
+
const schema = await this.fetchRemoteSchemaDocument(currentUrl);
|
|
2413
|
+
if (!schema) continue;
|
|
2414
|
+
this.externalSchemaCache.set(currentUrl, schema);
|
|
2415
|
+
for (const ref of this.extractRefsFromSchema(schema)) {
|
|
2416
|
+
const normalizedRef = this.normalizeRef(ref);
|
|
2417
|
+
if (normalizedRef.startsWith("#")) continue;
|
|
2418
|
+
const [externalPath = ""] = normalizedRef.split("#");
|
|
2419
|
+
if (!externalPath) continue;
|
|
2420
|
+
let absoluteUrl = "";
|
|
2421
|
+
try {
|
|
2422
|
+
absoluteUrl = this.isHttpUrl(externalPath) ? this.stripHash(externalPath) : this.stripHash(new URL(externalPath, currentUrl).toString());
|
|
2423
|
+
} catch (e) {
|
|
2424
|
+
consola.default.debug(e);
|
|
2425
|
+
}
|
|
2426
|
+
if (absoluteUrl && !visited.has(absoluteUrl)) queue.push(absoluteUrl);
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
collectRemoteAbsoluteRefCandidates(ref) {
|
|
2431
|
+
if (!ref || this.isHttpUrl(ref) || ref.startsWith("#")) return [];
|
|
2432
|
+
const [relativePath = "", rawPointer = ""] = this.normalizeRef(ref).split("#");
|
|
2433
|
+
if (!relativePath) return [];
|
|
2434
|
+
const pointer = rawPointer ? rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}` : "";
|
|
2435
|
+
const bases = /* @__PURE__ */ new Set();
|
|
2436
|
+
if (typeof this.config.url === "string" && this.isHttpUrl(this.config.url)) bases.add(this.config.url);
|
|
2437
|
+
for (const cachedUrl of this.externalSchemaCache.keys()) if (this.isHttpUrl(cachedUrl)) bases.add(cachedUrl);
|
|
2438
|
+
for (const resolver of this.resolvers) try {
|
|
2439
|
+
const resolverPaths = typeof resolver.paths === "function" ? resolver.paths() : [];
|
|
2440
|
+
for (const resolverPath of resolverPaths) if (typeof resolverPath === "string" && this.isHttpUrl(resolverPath)) bases.add(resolverPath);
|
|
2441
|
+
} catch (e) {
|
|
2442
|
+
consola.default.debug(e);
|
|
2443
|
+
}
|
|
2444
|
+
const results = /* @__PURE__ */ new Set();
|
|
2445
|
+
for (const base of bases) try {
|
|
2446
|
+
const absolutePath = new URL(relativePath, base).toString();
|
|
2447
|
+
results.add(pointer ? `${absolutePath}#${pointer}` : absolutePath);
|
|
2448
|
+
} catch (e) {
|
|
2449
|
+
consola.default.debug(e);
|
|
2450
|
+
}
|
|
2451
|
+
return [...results];
|
|
2452
|
+
}
|
|
2453
|
+
resolveFromRemoteSchemaCache(absoluteRef) {
|
|
2454
|
+
const [externalPath = "", rawPointer = ""] = this.normalizeRef(absoluteRef).split("#");
|
|
2455
|
+
if (!externalPath || !this.isHttpUrl(externalPath)) return null;
|
|
2456
|
+
const schema = this.externalSchemaCache.get(this.stripHash(externalPath));
|
|
2457
|
+
if (!schema) return null;
|
|
2458
|
+
const pointer = rawPointer ? rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}` : "/";
|
|
2459
|
+
const resolved = this.resolveJsonPointer(schema, pointer);
|
|
2460
|
+
if (resolved == null) return null;
|
|
2461
|
+
return this.absolutizeLocalRefs(resolved, this.stripHash(externalPath));
|
|
2462
|
+
}
|
|
2463
|
+
constructor(config, usageSchema, originalSchema, resolvers) {
|
|
2283
2464
|
this.config = config;
|
|
2284
|
-
this.
|
|
2465
|
+
this.usageSchema = usageSchema;
|
|
2466
|
+
this.originalSchema = originalSchema;
|
|
2467
|
+
this.resolvers = resolvers;
|
|
2468
|
+
this.usageSchema = usageSchema;
|
|
2469
|
+
this.originalSchema = originalSchema;
|
|
2470
|
+
}
|
|
2471
|
+
getRefDetails(ref) {
|
|
2472
|
+
const normalizedRef = this.normalizeRef(ref);
|
|
2473
|
+
if (!this.parsedRefsCache.has(ref)) {
|
|
2474
|
+
const isLocal = normalizedRef.startsWith("#");
|
|
2475
|
+
if (isLocal) this.parsedRefsCache.set(ref, {
|
|
2476
|
+
ref: normalizedRef,
|
|
2477
|
+
isLocal,
|
|
2478
|
+
externalUrlOrPath: null
|
|
2479
|
+
});
|
|
2480
|
+
else {
|
|
2481
|
+
const externalUrlOrPath = normalizedRef.split("#")[0] || "";
|
|
2482
|
+
let externalOpenapiFileName = externalUrlOrPath.replace(/\/$/, "").split("/").at(-1) || "";
|
|
2483
|
+
if (externalOpenapiFileName.endsWith(".json") || externalOpenapiFileName.endsWith(".yaml")) externalOpenapiFileName = externalOpenapiFileName.slice(0, -5);
|
|
2484
|
+
else if (externalOpenapiFileName.endsWith(".yml")) externalOpenapiFileName = externalOpenapiFileName.slice(0, -4);
|
|
2485
|
+
this.parsedRefsCache.set(ref, {
|
|
2486
|
+
ref: normalizedRef,
|
|
2487
|
+
isLocal,
|
|
2488
|
+
externalUrlOrPath,
|
|
2489
|
+
externalOpenapiFileName
|
|
2490
|
+
});
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
const cachedRef = this.parsedRefsCache.get(ref);
|
|
2494
|
+
if (cachedRef) return cachedRef;
|
|
2495
|
+
if (normalizedRef.startsWith("#")) return {
|
|
2496
|
+
ref: normalizedRef,
|
|
2497
|
+
isLocal: true,
|
|
2498
|
+
externalUrlOrPath: null
|
|
2499
|
+
};
|
|
2500
|
+
return {
|
|
2501
|
+
ref: normalizedRef,
|
|
2502
|
+
isLocal: false,
|
|
2503
|
+
externalUrlOrPath: normalizedRef.split("#")[0] || null,
|
|
2504
|
+
externalOpenapiFileName: ""
|
|
2505
|
+
};
|
|
2506
|
+
}
|
|
2507
|
+
isLocalRef(ref) {
|
|
2508
|
+
return this.getRefDetails(ref).isLocal;
|
|
2509
|
+
}
|
|
2510
|
+
getRef(ref) {
|
|
2511
|
+
if (!ref) return null;
|
|
2512
|
+
const normalizedRef = this.normalizeRef(ref);
|
|
2513
|
+
const escapedPathsRefVariant = this.createEscapedPathsRefVariant(ref);
|
|
2514
|
+
if (normalizedRef !== ref) {
|
|
2515
|
+
const resolvedByNormalizedRef = this.tryToResolveRef(normalizedRef);
|
|
2516
|
+
if (resolvedByNormalizedRef) return this.normalizeResolvedExternalSchemaRef(normalizedRef, resolvedByNormalizedRef);
|
|
2517
|
+
}
|
|
2518
|
+
if (escapedPathsRefVariant) {
|
|
2519
|
+
const resolvedByEscapedPathsRef = this.tryToResolveRef(escapedPathsRefVariant);
|
|
2520
|
+
if (resolvedByEscapedPathsRef) return this.normalizeResolvedExternalSchemaRef(escapedPathsRefVariant, resolvedByEscapedPathsRef);
|
|
2521
|
+
}
|
|
2522
|
+
const remoteAbsoluteCandidates = this.collectRemoteAbsoluteRefCandidates(ref);
|
|
2523
|
+
for (const remoteAbsoluteRef of remoteAbsoluteCandidates) {
|
|
2524
|
+
const resolvedFromRemoteCache = this.resolveFromRemoteSchemaCache(remoteAbsoluteRef);
|
|
2525
|
+
if (resolvedFromRemoteCache) return resolvedFromRemoteCache;
|
|
2526
|
+
const resolvedByRemoteAbsoluteRef = this.tryToResolveRef(remoteAbsoluteRef);
|
|
2527
|
+
if (resolvedByRemoteAbsoluteRef) return this.normalizeResolvedExternalSchemaRef(remoteAbsoluteRef, resolvedByRemoteAbsoluteRef);
|
|
2528
|
+
}
|
|
2529
|
+
const resolvedByOrigRef = this.tryToResolveRef(ref);
|
|
2530
|
+
if (resolvedByOrigRef) return this.normalizeResolvedExternalSchemaRef(ref, resolvedByOrigRef);
|
|
2531
|
+
if (/#[a-z]/.test(ref)) {
|
|
2532
|
+
const fixedRef = ref.replace(/#[a-z]/, (match) => {
|
|
2533
|
+
const [hashtag, char] = match.split("");
|
|
2534
|
+
return `${hashtag}/${char}`;
|
|
2535
|
+
});
|
|
2536
|
+
const resolvedByFixedRef = this.tryToResolveRef(fixedRef);
|
|
2537
|
+
if (resolvedByFixedRef) return this.normalizeResolvedExternalSchemaRef(fixedRef, resolvedByFixedRef);
|
|
2538
|
+
}
|
|
2539
|
+
return this.tryToResolveRefFromFile(normalizedRef);
|
|
2540
|
+
}
|
|
2541
|
+
tryToResolveRef(ref) {
|
|
2542
|
+
if (!this.resolvers || !ref) return null;
|
|
2543
|
+
for (const resolver of this.resolvers) try {
|
|
2544
|
+
return resolver.get(ref);
|
|
2545
|
+
} catch (e) {
|
|
2546
|
+
consola.default.debug(e);
|
|
2547
|
+
}
|
|
2548
|
+
return null;
|
|
2549
|
+
}
|
|
2550
|
+
readExternalSchema(filePath) {
|
|
2551
|
+
if (this.externalSchemaCache.has(filePath)) return this.externalSchemaCache.get(filePath) || null;
|
|
2552
|
+
if (!node_fs.existsSync(filePath)) return null;
|
|
2553
|
+
try {
|
|
2554
|
+
const content = node_fs.readFileSync(filePath, "utf8");
|
|
2555
|
+
const parsed = JSON.parse(content);
|
|
2556
|
+
this.externalSchemaCache.set(filePath, parsed);
|
|
2557
|
+
return parsed;
|
|
2558
|
+
} catch {
|
|
2559
|
+
try {
|
|
2560
|
+
const content = node_fs.readFileSync(filePath, "utf8");
|
|
2561
|
+
const parsed = yaml.parse(content);
|
|
2562
|
+
if (parsed && typeof parsed === "object") {
|
|
2563
|
+
this.externalSchemaCache.set(filePath, parsed);
|
|
2564
|
+
return parsed;
|
|
2565
|
+
}
|
|
2566
|
+
} catch (e) {
|
|
2567
|
+
consola.default.debug(e);
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
return null;
|
|
2571
|
+
}
|
|
2572
|
+
resolveJsonPointer(source, pointer) {
|
|
2573
|
+
if (!source || typeof source !== "object") return null;
|
|
2574
|
+
if (!pointer || pointer === "/") return source;
|
|
2575
|
+
const tokens = pointer.replace(/^\/+/, "").split("/").filter(Boolean).map((part) => decodeURIComponent(part.replace(/~1/g, "/").replace(/~0/g, "~")));
|
|
2576
|
+
let current = source;
|
|
2577
|
+
for (const token of tokens) {
|
|
2578
|
+
if (!current || typeof current !== "object") return null;
|
|
2579
|
+
current = current[token];
|
|
2580
|
+
}
|
|
2581
|
+
return current ?? null;
|
|
2582
|
+
}
|
|
2583
|
+
absolutizeLocalRefs(value, externalPath) {
|
|
2584
|
+
if (value == null || typeof value !== "object") return value;
|
|
2585
|
+
const cloneValue = structuredClone(value);
|
|
2586
|
+
const walk = (node) => {
|
|
2587
|
+
if (!node || typeof node !== "object") return;
|
|
2588
|
+
if (Array.isArray(node)) {
|
|
2589
|
+
for (const item of node) walk(item);
|
|
2590
|
+
return;
|
|
2591
|
+
}
|
|
2592
|
+
const recordNode = node;
|
|
2593
|
+
if (typeof recordNode.$ref === "string" && recordNode.$ref.startsWith("#")) recordNode.$ref = `${externalPath}${this.normalizeRef(recordNode.$ref)}`;
|
|
2594
|
+
for (const nested of Object.values(recordNode)) walk(nested);
|
|
2595
|
+
};
|
|
2596
|
+
walk(cloneValue);
|
|
2597
|
+
return cloneValue;
|
|
2598
|
+
}
|
|
2599
|
+
normalizeResolvedExternalSchemaRef(ref, resolved) {
|
|
2600
|
+
const normalizedRef = this.normalizeRef(ref);
|
|
2601
|
+
if (normalizedRef.startsWith("#")) return resolved;
|
|
2602
|
+
const externalPath = normalizedRef.split("#")[0] || "";
|
|
2603
|
+
if (!externalPath) return resolved;
|
|
2604
|
+
return this.absolutizeLocalRefs(resolved, externalPath);
|
|
2605
|
+
}
|
|
2606
|
+
collectExternalRefCandidates(externalPath) {
|
|
2607
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
2608
|
+
if (/^https?:\/\//i.test(externalPath)) return [];
|
|
2609
|
+
if (node_path.default.isAbsolute(externalPath)) candidates.add(externalPath);
|
|
2610
|
+
const inputPath = this.config.input;
|
|
2611
|
+
if (typeof inputPath === "string" && inputPath) candidates.add(node_path.default.resolve(node_path.default.dirname(inputPath), externalPath));
|
|
2612
|
+
for (const resolver of this.resolvers) try {
|
|
2613
|
+
const resolverPaths = typeof resolver.paths === "function" ? resolver.paths() : [];
|
|
2614
|
+
for (const resolverPath of resolverPaths) {
|
|
2615
|
+
if (typeof resolverPath !== "string") continue;
|
|
2616
|
+
if (/^https?:\/\//i.test(resolverPath)) continue;
|
|
2617
|
+
candidates.add(node_path.default.resolve(node_path.default.dirname(resolverPath), externalPath));
|
|
2618
|
+
}
|
|
2619
|
+
} catch (e) {
|
|
2620
|
+
consola.default.debug(e);
|
|
2621
|
+
}
|
|
2622
|
+
return [...candidates];
|
|
2623
|
+
}
|
|
2624
|
+
tryToResolveRefFromFile(ref) {
|
|
2625
|
+
if (!ref || ref.startsWith("#")) return null;
|
|
2626
|
+
const [externalPath = "", rawPointer = ""] = ref.split("#");
|
|
2627
|
+
if (!externalPath) return null;
|
|
2628
|
+
const pointer = rawPointer ? rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}` : "/";
|
|
2629
|
+
const candidates = this.collectExternalRefCandidates(externalPath);
|
|
2630
|
+
for (const candidate of candidates) {
|
|
2631
|
+
const schema = this.readExternalSchema(candidate);
|
|
2632
|
+
const resolved = this.resolveJsonPointer(schema, pointer);
|
|
2633
|
+
if (resolved != null) return this.absolutizeLocalRefs(resolved, externalPath);
|
|
2634
|
+
}
|
|
2635
|
+
return null;
|
|
2636
|
+
}
|
|
2637
|
+
static async create(config, usageSchema, originalSchema) {
|
|
2638
|
+
const resolvers = [];
|
|
2639
|
+
const options = {
|
|
2640
|
+
continueOnError: true,
|
|
2641
|
+
mutateInputSchema: true,
|
|
2642
|
+
dereference: {},
|
|
2643
|
+
validate: {
|
|
2644
|
+
schema: false,
|
|
2645
|
+
spec: false
|
|
2646
|
+
},
|
|
2647
|
+
resolve: {
|
|
2648
|
+
external: true,
|
|
2649
|
+
http: {
|
|
2650
|
+
...config.requestOptions,
|
|
2651
|
+
headers: Object.assign({}, config.authorizationToken ? { Authorization: config.authorizationToken } : {}, config.requestOptions?.headers ?? {})
|
|
2652
|
+
}
|
|
2653
|
+
}
|
|
2654
|
+
};
|
|
2655
|
+
try {
|
|
2656
|
+
resolvers.push(await _apidevtools_swagger_parser.default.resolve(originalSchema, options));
|
|
2657
|
+
} catch (e) {
|
|
2658
|
+
consola.default.debug(e);
|
|
2659
|
+
}
|
|
2660
|
+
try {
|
|
2661
|
+
resolvers.push(await _apidevtools_swagger_parser.default.resolve(usageSchema, options));
|
|
2662
|
+
} catch (e) {
|
|
2663
|
+
consola.default.debug(e);
|
|
2664
|
+
}
|
|
2665
|
+
try {
|
|
2666
|
+
resolvers.push(await _apidevtools_swagger_parser.default.resolve(config.url || config.input || config.spec, options));
|
|
2667
|
+
} catch (e) {
|
|
2668
|
+
consola.default.debug(e);
|
|
2669
|
+
}
|
|
2670
|
+
const resolvedSwaggerSchema = new ResolvedSwaggerSchema(config, usageSchema, originalSchema, resolvers);
|
|
2671
|
+
await resolvedSwaggerSchema.warmUpRemoteSchemasCache();
|
|
2672
|
+
return resolvedSwaggerSchema;
|
|
2285
2673
|
}
|
|
2286
|
-
addSchema = (name, schema) => {
|
|
2287
|
-
this.schemas.set(name, structuredClone(schema));
|
|
2288
|
-
};
|
|
2289
|
-
_isLocalRef = (ref) => {
|
|
2290
|
-
return ref.startsWith("#");
|
|
2291
|
-
};
|
|
2292
|
-
_isRemoteRef = (ref) => {
|
|
2293
|
-
return ref.startsWith("http://") || ref.startsWith("https://");
|
|
2294
|
-
};
|
|
2295
|
-
_getRefDataFromSchema = (schema, ref) => {
|
|
2296
|
-
const refData = (0, es_toolkit_compat.get)(schema, ref.replace("#", "").split("/"));
|
|
2297
|
-
if (refData) this.caches.set(ref, refData);
|
|
2298
|
-
return refData;
|
|
2299
|
-
};
|
|
2300
2674
|
};
|
|
2301
2675
|
|
|
2302
2676
|
//#endregion
|
|
@@ -2333,10 +2707,15 @@ var SwaggerSchemaResolver = class {
|
|
|
2333
2707
|
}
|
|
2334
2708
|
async create() {
|
|
2335
2709
|
const { spec, patch, input, url, authorizationToken } = this.config;
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2710
|
+
let swaggerSchemas;
|
|
2711
|
+
if (spec) swaggerSchemas = await this.convertSwaggerObject(spec, { patch });
|
|
2712
|
+
else {
|
|
2713
|
+
const swaggerSchemaFile = await this.fetchSwaggerSchemaFile(input, url, authorizationToken);
|
|
2714
|
+
const swaggerSchemaObject = this.processSwaggerSchemaFile(swaggerSchemaFile);
|
|
2715
|
+
swaggerSchemas = await this.convertSwaggerObject(swaggerSchemaObject, { patch });
|
|
2716
|
+
}
|
|
2717
|
+
this.fixSwaggerSchemas(swaggerSchemas);
|
|
2718
|
+
return ResolvedSwaggerSchema.create(this.config, swaggerSchemas.usageSchema, swaggerSchemas.originalSchema);
|
|
2340
2719
|
}
|
|
2341
2720
|
convertSwaggerObject(swaggerSchema, converterOptions) {
|
|
2342
2721
|
return new Promise((resolve) => {
|
|
@@ -2388,7 +2767,26 @@ var SwaggerSchemaResolver = class {
|
|
|
2388
2767
|
return yaml.parse(file);
|
|
2389
2768
|
}
|
|
2390
2769
|
}
|
|
2391
|
-
|
|
2770
|
+
normalizeRefValue(ref) {
|
|
2771
|
+
const refWithoutSlashBeforeHash = ref.split("/#/").join("#/");
|
|
2772
|
+
const hashIndex = refWithoutSlashBeforeHash.indexOf("#");
|
|
2773
|
+
if (hashIndex === -1) return refWithoutSlashBeforeHash;
|
|
2774
|
+
if (refWithoutSlashBeforeHash[hashIndex + 1] === "/") return refWithoutSlashBeforeHash;
|
|
2775
|
+
return `${refWithoutSlashBeforeHash.slice(0, hashIndex + 1)}/${refWithoutSlashBeforeHash.slice(hashIndex + 1)}`;
|
|
2776
|
+
}
|
|
2777
|
+
normalizeRefsInSchema(schema) {
|
|
2778
|
+
if (!schema || typeof schema !== "object") return;
|
|
2779
|
+
if (Array.isArray(schema)) {
|
|
2780
|
+
for (const value of schema) this.normalizeRefsInSchema(value);
|
|
2781
|
+
return;
|
|
2782
|
+
}
|
|
2783
|
+
const objectSchema = schema;
|
|
2784
|
+
if (typeof objectSchema.$ref === "string") objectSchema.$ref = this.normalizeRefValue(objectSchema.$ref);
|
|
2785
|
+
for (const value of Object.values(objectSchema)) this.normalizeRefsInSchema(value);
|
|
2786
|
+
}
|
|
2787
|
+
fixSwaggerSchemas({ usageSchema, originalSchema }) {
|
|
2788
|
+
this.normalizeRefsInSchema(usageSchema);
|
|
2789
|
+
this.normalizeRefsInSchema(originalSchema);
|
|
2392
2790
|
const usagePaths = (0, es_toolkit_compat.get)(usageSchema, "paths") || {};
|
|
2393
2791
|
const originalPaths = (0, es_toolkit_compat.get)(originalSchema, "paths") || {};
|
|
2394
2792
|
for (const [route, usagePathObject] of Object.entries(usagePaths)) {
|
|
@@ -2397,9 +2795,10 @@ var SwaggerSchemaResolver = class {
|
|
|
2397
2795
|
const originalRouteInfo = (0, es_toolkit_compat.get)(originalPathObject, methodName) || {};
|
|
2398
2796
|
const usageRouteParams = (0, es_toolkit_compat.get)(usageRouteInfo, "parameters") || [];
|
|
2399
2797
|
const originalRouteParams = (0, es_toolkit_compat.get)(originalRouteInfo, "parameters") || [];
|
|
2798
|
+
const usageAsOpenapiv2 = usageRouteInfo;
|
|
2400
2799
|
if (typeof usageRouteInfo === "object") {
|
|
2401
|
-
|
|
2402
|
-
|
|
2800
|
+
usageAsOpenapiv2.consumes = (0, es_toolkit.uniq)((0, es_toolkit.compact)([...usageAsOpenapiv2.consumes || [], ...originalRouteInfo.consumes || []]));
|
|
2801
|
+
usageAsOpenapiv2.produces = (0, es_toolkit.uniq)((0, es_toolkit.compact)([...usageAsOpenapiv2.produces || [], ...originalRouteInfo.produces || []]));
|
|
2403
2802
|
}
|
|
2404
2803
|
for (const originalRouteParam of originalRouteParams) if (!usageRouteParams.find((param) => originalRouteParam.in === param.in && originalRouteParam.name === param.name)) usageRouteParams.push(originalRouteParam);
|
|
2405
2804
|
}
|
|
@@ -2574,7 +2973,7 @@ var TypeNameFormatter = class {
|
|
|
2574
2973
|
]).join("_");
|
|
2575
2974
|
if (this.formattedModelNamesMap.has(hashKey)) return this.formattedModelNamesMap.get(hashKey);
|
|
2576
2975
|
const formattedName = (0, es_toolkit_compat.startCase)(`${typePrefix}_${this.fixModelName(name, { type: schemaType })}_${typeSuffix}`).replace(/\s/g, "");
|
|
2577
|
-
const formattedResultName = this.config.hooks.onFormatTypeName(formattedName, name, schemaType) || formattedName;
|
|
2976
|
+
const formattedResultName = this.config.hooks.onFormatTypeName?.(formattedName, name, schemaType) || formattedName;
|
|
2578
2977
|
this.formattedModelNamesMap.set(hashKey, formattedResultName);
|
|
2579
2978
|
return formattedResultName;
|
|
2580
2979
|
};
|
|
@@ -2673,38 +3072,35 @@ var CodeGenProcess = class {
|
|
|
2673
3072
|
fileSystem;
|
|
2674
3073
|
codeFormatter;
|
|
2675
3074
|
templatesWorker;
|
|
2676
|
-
schemaWalker;
|
|
2677
3075
|
javascriptTranslator;
|
|
3076
|
+
swaggerRefs;
|
|
2678
3077
|
constructor(config) {
|
|
2679
3078
|
this.config = new CodeGenConfig(config);
|
|
2680
3079
|
this.fileSystem = new FileSystem();
|
|
2681
3080
|
this.swaggerSchemaResolver = new SwaggerSchemaResolver(this.config, this.fileSystem);
|
|
2682
|
-
this.schemaWalker = new SchemaWalker(this.config, this.swaggerSchemaResolver);
|
|
2683
3081
|
this.schemaComponentsMap = new SchemaComponentsMap(this.config);
|
|
2684
3082
|
this.typeNameFormatter = new TypeNameFormatter(this.config);
|
|
2685
3083
|
this.templatesWorker = new TemplatesWorker(this.config, this.fileSystem, this.getRenderTemplateData);
|
|
2686
3084
|
this.codeFormatter = new CodeFormatter(this.config);
|
|
2687
|
-
this.schemaParserFabric = new SchemaParserFabric(this.config, this.templatesWorker, this.schemaComponentsMap, this.typeNameFormatter
|
|
3085
|
+
this.schemaParserFabric = new SchemaParserFabric(this.config, this.templatesWorker, this.schemaComponentsMap, this.typeNameFormatter);
|
|
2688
3086
|
this.schemaRoutes = new SchemaRoutes(this.config, this.schemaParserFabric, this.schemaComponentsMap, this.templatesWorker, this.typeNameFormatter);
|
|
2689
3087
|
this.javascriptTranslator = new JavascriptTranslator(this.config, this.codeFormatter);
|
|
2690
3088
|
}
|
|
2691
3089
|
async start() {
|
|
2692
3090
|
this.config.update({ templatePaths: this.templatesWorker.getTemplatePaths(this.config) });
|
|
2693
3091
|
this.config.update({ templatesToRender: this.templatesWorker.getTemplates(this.config) });
|
|
2694
|
-
const
|
|
2695
|
-
this.swaggerSchemaResolver.fixSwaggerSchema(swagger);
|
|
3092
|
+
const resolvedSwaggerSchema = await this.swaggerSchemaResolver.create();
|
|
2696
3093
|
this.config.update({
|
|
2697
|
-
|
|
2698
|
-
|
|
3094
|
+
resolvedSwaggerSchema,
|
|
3095
|
+
swaggerSchema: resolvedSwaggerSchema.usageSchema,
|
|
3096
|
+
originalSchema: resolvedSwaggerSchema.originalSchema
|
|
2699
3097
|
});
|
|
2700
|
-
this.schemaWalker.addSchema("$usage", swagger.usageSchema);
|
|
2701
|
-
this.schemaWalker.addSchema("$original", swagger.originalSchema);
|
|
2702
3098
|
consola.consola.info("start generating your typescript api");
|
|
2703
|
-
this.config.update(this.config.hooks.onInit(this.config, this) || this.config);
|
|
2704
|
-
if (this.config.swaggerSchema)
|
|
2705
|
-
if (this.config.originalSchema)
|
|
3099
|
+
this.config.update(this.config.hooks.onInit?.(this.config, this) || this.config);
|
|
3100
|
+
if (this.config.swaggerSchema) resolvedSwaggerSchema.usageSchema = this.config.swaggerSchema;
|
|
3101
|
+
if (this.config.originalSchema) resolvedSwaggerSchema.originalSchema = this.config.originalSchema;
|
|
2706
3102
|
this.schemaComponentsMap.clear();
|
|
2707
|
-
for (const [componentName, component] of Object.entries(
|
|
3103
|
+
for (const [componentName, component] of Object.entries(resolvedSwaggerSchema.usageSchema.components || {})) for (const [typeName, rawTypeData] of Object.entries(component)) this.schemaComponentsMap.createComponent(this.schemaComponentsMap.createRef([
|
|
2708
3104
|
"components",
|
|
2709
3105
|
componentName,
|
|
2710
3106
|
typeName
|
|
@@ -2716,12 +3112,9 @@ var CodeGenProcess = class {
|
|
|
2716
3112
|
schemaComponent.typeData = parsed;
|
|
2717
3113
|
return parsed;
|
|
2718
3114
|
});
|
|
2719
|
-
this.schemaRoutes.attachSchema(
|
|
2720
|
-
usageSchema: swagger.usageSchema,
|
|
2721
|
-
parsedSchemas
|
|
2722
|
-
});
|
|
3115
|
+
this.schemaRoutes.attachSchema(resolvedSwaggerSchema, parsedSchemas);
|
|
2723
3116
|
const rawConfiguration = {
|
|
2724
|
-
apiConfig: this.createApiConfig(
|
|
3117
|
+
apiConfig: this.createApiConfig(resolvedSwaggerSchema.usageSchema),
|
|
2725
3118
|
config: this.config,
|
|
2726
3119
|
modelTypes: this.collectModelTypes(),
|
|
2727
3120
|
hasSecurityRoutes: this.schemaRoutes.hasSecurityRoutes,
|
|
@@ -2735,7 +3128,7 @@ var CodeGenProcess = class {
|
|
|
2735
3128
|
customTranslator: this.config.customTranslator ? new this.config.customTranslator() : null,
|
|
2736
3129
|
utils: this.getRenderTemplateData().utils
|
|
2737
3130
|
};
|
|
2738
|
-
const configuration = this.config.hooks.onPrepareConfig(rawConfiguration) || rawConfiguration;
|
|
3131
|
+
const configuration = this.config.hooks.onPrepareConfig?.(rawConfiguration) || rawConfiguration;
|
|
2739
3132
|
if (this.fileSystem.pathIsExist(this.config.output)) {
|
|
2740
3133
|
if (this.config.cleanOutput) {
|
|
2741
3134
|
consola.consola.debug("cleaning dir", this.config.output);
|
|
@@ -3174,4 +3567,4 @@ Object.defineProperty(exports, 'version', {
|
|
|
3174
3567
|
return version;
|
|
3175
3568
|
}
|
|
3176
3569
|
});
|
|
3177
|
-
//# sourceMappingURL=generate-templates-
|
|
3570
|
+
//# sourceMappingURL=generate-templates-CAvEodGO.cjs.map
|