swagger-typescript-api 13.2.18 → 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-DGQlyLhe.mjs → generate-templates-BaT2BiRR.mjs} +523 -137
- package/dist/generate-templates-BaT2BiRR.mjs.map +1 -0
- package/dist/{generate-templates-C4JBmSNw.cjs → generate-templates-BlSkwa8l.cjs} +488 -100
- package/dist/generate-templates-BlSkwa8l.cjs.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 +10 -7
- 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.0";
|
|
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) => {
|
|
@@ -1336,7 +1367,6 @@ var SchemaParser = class {
|
|
|
1336
1367
|
schemaFormatters;
|
|
1337
1368
|
schemaUtils;
|
|
1338
1369
|
templatesWorker;
|
|
1339
|
-
schemaWalker;
|
|
1340
1370
|
typeName;
|
|
1341
1371
|
schema;
|
|
1342
1372
|
schemaPath;
|
|
@@ -1346,7 +1376,6 @@ var SchemaParser = class {
|
|
|
1346
1376
|
this.templatesWorker = schemaParserFabric.templatesWorker;
|
|
1347
1377
|
this.schemaComponentsMap = schemaParserFabric.schemaComponentsMap;
|
|
1348
1378
|
this.typeNameFormatter = schemaParserFabric.typeNameFormatter;
|
|
1349
|
-
this.schemaWalker = schemaParserFabric.schemaWalker;
|
|
1350
1379
|
this.schemaFormatters = schemaParserFabric.schemaFormatters;
|
|
1351
1380
|
this.schemaUtils = schemaParserFabric.schemaUtils;
|
|
1352
1381
|
this.typeName = typeName || null;
|
|
@@ -1441,24 +1470,13 @@ var SchemaParser = class {
|
|
|
1441
1470
|
};
|
|
1442
1471
|
};
|
|
1443
1472
|
|
|
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
1473
|
//#endregion
|
|
1451
1474
|
//#region src/schema-parser/schema-utils.ts
|
|
1452
1475
|
var SchemaUtils = class {
|
|
1453
|
-
config
|
|
1454
|
-
schemaComponentsMap;
|
|
1455
|
-
typeNameFormatter;
|
|
1456
|
-
schemaWalker;
|
|
1457
|
-
constructor({ config, schemaComponentsMap, typeNameFormatter, schemaWalker }) {
|
|
1476
|
+
constructor(config, schemaComponentsMap, typeNameFormatter) {
|
|
1458
1477
|
this.config = config;
|
|
1459
1478
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
1460
1479
|
this.typeNameFormatter = typeNameFormatter;
|
|
1461
|
-
this.schemaWalker = schemaWalker;
|
|
1462
1480
|
}
|
|
1463
1481
|
getRequiredProperties = (schema) => {
|
|
1464
1482
|
return (0, es_toolkit.uniq)(schema && Array.isArray(schema.required) && schema.required || []);
|
|
@@ -1604,14 +1622,12 @@ var SchemaParserFabric = class {
|
|
|
1604
1622
|
schemaFormatters;
|
|
1605
1623
|
templatesWorker;
|
|
1606
1624
|
schemaUtils;
|
|
1607
|
-
|
|
1608
|
-
constructor(config, templatesWorker, schemaComponentsMap, typeNameFormatter, schemaWalker) {
|
|
1625
|
+
constructor(config, templatesWorker, schemaComponentsMap, typeNameFormatter) {
|
|
1609
1626
|
this.config = config;
|
|
1610
1627
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
1611
1628
|
this.typeNameFormatter = typeNameFormatter;
|
|
1612
1629
|
this.templatesWorker = templatesWorker;
|
|
1613
|
-
this.
|
|
1614
|
-
this.schemaUtils = new SchemaUtils(this);
|
|
1630
|
+
this.schemaUtils = new SchemaUtils(this.config, this.schemaComponentsMap, this.typeNameFormatter);
|
|
1615
1631
|
this.schemaFormatters = new SchemaFormatters(this);
|
|
1616
1632
|
}
|
|
1617
1633
|
createSchemaParser = ({ schema, typeName, schemaPath }) => {
|
|
@@ -1696,12 +1712,7 @@ const CONTENT_KIND = {
|
|
|
1696
1712
|
TEXT: "TEXT"
|
|
1697
1713
|
};
|
|
1698
1714
|
var SchemaRoutes = class {
|
|
1699
|
-
config;
|
|
1700
|
-
schemaParserFabric;
|
|
1701
1715
|
schemaUtils;
|
|
1702
|
-
typeNameFormatter;
|
|
1703
|
-
schemaComponentsMap;
|
|
1704
|
-
templatesWorker;
|
|
1705
1716
|
FORM_DATA_TYPES = [];
|
|
1706
1717
|
routes = [];
|
|
1707
1718
|
hasSecurityRoutes = false;
|
|
@@ -1710,10 +1721,10 @@ var SchemaRoutes = class {
|
|
|
1710
1721
|
constructor(config, schemaParserFabric, schemaComponentsMap, templatesWorker, typeNameFormatter) {
|
|
1711
1722
|
this.config = config;
|
|
1712
1723
|
this.schemaParserFabric = schemaParserFabric;
|
|
1713
|
-
this.schemaUtils = this.schemaParserFabric.schemaUtils;
|
|
1714
|
-
this.typeNameFormatter = typeNameFormatter;
|
|
1715
1724
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
1716
1725
|
this.templatesWorker = templatesWorker;
|
|
1726
|
+
this.typeNameFormatter = typeNameFormatter;
|
|
1727
|
+
this.schemaUtils = this.schemaParserFabric.schemaUtils;
|
|
1717
1728
|
this.FORM_DATA_TYPES = (0, es_toolkit.uniq)([this.schemaUtils.getSchemaType({
|
|
1718
1729
|
type: "string",
|
|
1719
1730
|
format: "file"
|
|
@@ -1722,11 +1733,16 @@ var SchemaRoutes = class {
|
|
|
1722
1733
|
format: "binary"
|
|
1723
1734
|
})]);
|
|
1724
1735
|
}
|
|
1725
|
-
createRequestsMap = (routesByMethod) => {
|
|
1736
|
+
createRequestsMap = (resolvedSwaggerSchema, routesByMethod) => {
|
|
1726
1737
|
const parameters = (0, es_toolkit_compat.get)(routesByMethod, "parameters");
|
|
1727
1738
|
const result = {};
|
|
1728
1739
|
for (const [method, requestInfo] of Object.entries(routesByMethod)) {
|
|
1729
|
-
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
|
+
}
|
|
1730
1746
|
result[method] = {
|
|
1731
1747
|
...requestInfo,
|
|
1732
1748
|
parameters: (0, es_toolkit.compact)([...parameters || [], ...requestInfo.parameters || []])
|
|
@@ -1795,7 +1811,7 @@ var SchemaRoutes = class {
|
|
|
1795
1811
|
for (const parameter of parameters || []) {
|
|
1796
1812
|
const refTypeInfo = this.schemaParserFabric.schemaUtils.getSchemaRefType(parameter);
|
|
1797
1813
|
let routeParam = null;
|
|
1798
|
-
if (refTypeInfo?.rawTypeData
|
|
1814
|
+
if (!!refTypeInfo?.rawTypeData && typeof refTypeInfo === "object" && refTypeInfo?.rawTypeData.in) {
|
|
1799
1815
|
if (!routeParams[refTypeInfo.rawTypeData.in]) routeParams[refTypeInfo.rawTypeData.in] = [];
|
|
1800
1816
|
routeParam = {
|
|
1801
1817
|
...refTypeInfo.rawTypeData,
|
|
@@ -1865,10 +1881,11 @@ var SchemaRoutes = class {
|
|
|
1865
1881
|
}
|
|
1866
1882
|
return defaultType || this.config.Ts.Keyword.Any;
|
|
1867
1883
|
};
|
|
1868
|
-
getRequestInfoTypes = ({ requestInfos, parsedSchemas, operationId, defaultType }) => {
|
|
1884
|
+
getRequestInfoTypes = ({ requestInfos, parsedSchemas, operationId, defaultType, resolvedSwaggerSchema }) => {
|
|
1869
1885
|
const result = [];
|
|
1870
1886
|
for (const [status, requestInfo] of Object.entries(requestInfos || {})) {
|
|
1871
1887
|
const contentTypes = this.getContentTypes([requestInfo], operationId);
|
|
1888
|
+
const links = this.getRouteLinksFromResponse(resolvedSwaggerSchema, requestInfo, status);
|
|
1872
1889
|
result.push({
|
|
1873
1890
|
...requestInfo || {},
|
|
1874
1891
|
contentTypes,
|
|
@@ -1880,21 +1897,48 @@ var SchemaRoutes = class {
|
|
|
1880
1897
|
defaultType
|
|
1881
1898
|
})),
|
|
1882
1899
|
description: this.schemaParserFabric.schemaFormatters.formatDescription(requestInfo.description || "", true),
|
|
1900
|
+
links,
|
|
1883
1901
|
status: Number.isNaN(+status) ? status : +status,
|
|
1884
1902
|
isSuccess: this.isSuccessStatus(status)
|
|
1885
1903
|
});
|
|
1886
1904
|
}
|
|
1887
1905
|
return result;
|
|
1888
1906
|
};
|
|
1889
|
-
|
|
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) => {
|
|
1890
1932
|
const { produces, operationId, responses } = routeInfo;
|
|
1891
1933
|
const contentTypes = this.getContentTypes(responses, [...produces || [], routeInfo["x-accepts"]]);
|
|
1892
1934
|
const responseInfos = this.getRequestInfoTypes({
|
|
1893
1935
|
requestInfos: responses,
|
|
1894
1936
|
parsedSchemas,
|
|
1895
1937
|
operationId,
|
|
1896
|
-
defaultType: this.config.defaultResponseType
|
|
1938
|
+
defaultType: this.config.defaultResponseType,
|
|
1939
|
+
resolvedSwaggerSchema
|
|
1897
1940
|
});
|
|
1941
|
+
const links = responseInfos.flatMap((responseInfo) => responseInfo.links || []);
|
|
1898
1942
|
const successResponse = responseInfos.find((response) => response.isSuccess);
|
|
1899
1943
|
const errorResponses = responseInfos.filter((response) => !response.isSuccess && response.type !== this.config.Ts.Keyword.Any);
|
|
1900
1944
|
const handleResponseHeaders = (src) => {
|
|
@@ -1907,6 +1951,7 @@ var SchemaRoutes = class {
|
|
|
1907
1951
|
return {
|
|
1908
1952
|
contentTypes,
|
|
1909
1953
|
responses: responseInfos,
|
|
1954
|
+
links,
|
|
1910
1955
|
success: {
|
|
1911
1956
|
schema: successResponse,
|
|
1912
1957
|
type: successResponse?.type || this.config.Ts.Keyword.Any
|
|
@@ -2077,7 +2122,7 @@ var SchemaRoutes = class {
|
|
|
2077
2122
|
const { routeNameDuplicatesMap, templatesToRender } = this.config;
|
|
2078
2123
|
const routeNameTemplate = templatesToRender.routeName;
|
|
2079
2124
|
const routeNameFromTemplate = this.templatesWorker.renderTemplate(routeNameTemplate, { routeInfo: rawRouteInfo });
|
|
2080
|
-
const routeName = this.config.hooks.onFormatRouteName(rawRouteInfo, routeNameFromTemplate) || routeNameFromTemplate;
|
|
2125
|
+
const routeName = this.config.hooks.onFormatRouteName?.(rawRouteInfo, routeNameFromTemplate) || routeNameFromTemplate;
|
|
2081
2126
|
const duplicateIdentifier = `${moduleName}|${routeName}`;
|
|
2082
2127
|
if (routeNameDuplicatesMap.has(duplicateIdentifier)) {
|
|
2083
2128
|
routeNameDuplicatesMap.set(duplicateIdentifier, routeNameDuplicatesMap.get(duplicateIdentifier) + 1);
|
|
@@ -2089,10 +2134,10 @@ var SchemaRoutes = class {
|
|
|
2089
2134
|
original: routeName,
|
|
2090
2135
|
duplicate: duplicates > 1
|
|
2091
2136
|
};
|
|
2092
|
-
return this.config.hooks.onCreateRouteName(routeNameInfo, rawRouteInfo) || routeNameInfo;
|
|
2137
|
+
return this.config.hooks.onCreateRouteName?.(routeNameInfo, rawRouteInfo) || routeNameInfo;
|
|
2093
2138
|
};
|
|
2094
|
-
parseRouteInfo = (rawRouteName, routeInfo, method,
|
|
2095
|
-
const { security: globalSecurity } = usageSchema;
|
|
2139
|
+
parseRouteInfo = (rawRouteName, routeInfo, method, resolvedSwaggerSchema, parsedSchemas) => {
|
|
2140
|
+
const { security: globalSecurity } = resolvedSwaggerSchema.usageSchema;
|
|
2096
2141
|
const { moduleNameIndex, moduleNameFirstTag, extractRequestParams } = this.config;
|
|
2097
2142
|
const { operationId, requestBody, security, parameters, summary, description, tags, responses, requestBodyName, produces, consumes, ...otherInfo } = routeInfo;
|
|
2098
2143
|
const { route, pathParams: pathParamsFromRouteName, queryParams: queryParamsFromRouteName } = this.parseRouteName(rawRouteName);
|
|
@@ -2109,7 +2154,7 @@ var SchemaRoutes = class {
|
|
|
2109
2154
|
description: pathArgSchema.description
|
|
2110
2155
|
}));
|
|
2111
2156
|
const pathArgsNames = pathArgs.map((arg) => arg.name);
|
|
2112
|
-
const responseBodyInfo = this.getResponseBodyInfo(routeInfo, parsedSchemas);
|
|
2157
|
+
const responseBodyInfo = this.getResponseBodyInfo(routeInfo, parsedSchemas, resolvedSwaggerSchema);
|
|
2113
2158
|
const rawRouteInfo = {
|
|
2114
2159
|
...otherInfo,
|
|
2115
2160
|
pathArgs,
|
|
@@ -2118,6 +2163,7 @@ var SchemaRoutes = class {
|
|
|
2118
2163
|
route: rawRouteName,
|
|
2119
2164
|
moduleName,
|
|
2120
2165
|
responsesTypes: responseBodyInfo.responses,
|
|
2166
|
+
links: responseBodyInfo.links,
|
|
2121
2167
|
description,
|
|
2122
2168
|
tags,
|
|
2123
2169
|
summary,
|
|
@@ -2213,13 +2259,13 @@ var SchemaRoutes = class {
|
|
|
2213
2259
|
raw: rawRouteInfo
|
|
2214
2260
|
};
|
|
2215
2261
|
};
|
|
2216
|
-
attachSchema = (
|
|
2262
|
+
attachSchema = (resolvedSwaggerSchema, parsedSchemas) => {
|
|
2217
2263
|
this.config.routeNameDuplicatesMap.clear();
|
|
2218
|
-
const pathsEntries = Object.entries(usageSchema.paths || {});
|
|
2264
|
+
const pathsEntries = Object.entries(resolvedSwaggerSchema.usageSchema.paths || {});
|
|
2219
2265
|
for (const [rawRouteName, routeInfoByMethodsMap] of pathsEntries) {
|
|
2220
|
-
const routeInfosMap = this.createRequestsMap(routeInfoByMethodsMap);
|
|
2266
|
+
const routeInfosMap = this.createRequestsMap(resolvedSwaggerSchema, routeInfoByMethodsMap);
|
|
2221
2267
|
for (const [method, routeInfo] of Object.entries(routeInfosMap)) {
|
|
2222
|
-
const parsedRouteInfo = this.parseRouteInfo(rawRouteName, routeInfo, method,
|
|
2268
|
+
const parsedRouteInfo = this.parseRouteInfo(rawRouteName, routeInfo, method, resolvedSwaggerSchema, parsedSchemas);
|
|
2223
2269
|
const processedRouteInfo = this.config.hooks.onCreateRoute(parsedRouteInfo);
|
|
2224
2270
|
if (processedRouteInfo !== false) {
|
|
2225
2271
|
const route = processedRouteInfo || parsedRouteInfo;
|
|
@@ -2273,30 +2319,353 @@ var SchemaRoutes = class {
|
|
|
2273
2319
|
};
|
|
2274
2320
|
|
|
2275
2321
|
//#endregion
|
|
2276
|
-
//#region src/schema
|
|
2277
|
-
var
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
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) {
|
|
2283
2459
|
this.config = config;
|
|
2284
|
-
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;
|
|
2285
2668
|
}
|
|
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
2669
|
};
|
|
2301
2670
|
|
|
2302
2671
|
//#endregion
|
|
@@ -2333,10 +2702,15 @@ var SwaggerSchemaResolver = class {
|
|
|
2333
2702
|
}
|
|
2334
2703
|
async create() {
|
|
2335
2704
|
const { spec, patch, input, url, authorizationToken } = this.config;
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
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);
|
|
2340
2714
|
}
|
|
2341
2715
|
convertSwaggerObject(swaggerSchema, converterOptions) {
|
|
2342
2716
|
return new Promise((resolve) => {
|
|
@@ -2388,7 +2762,26 @@ var SwaggerSchemaResolver = class {
|
|
|
2388
2762
|
return yaml.parse(file);
|
|
2389
2763
|
}
|
|
2390
2764
|
}
|
|
2391
|
-
|
|
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);
|
|
2392
2785
|
const usagePaths = (0, es_toolkit_compat.get)(usageSchema, "paths") || {};
|
|
2393
2786
|
const originalPaths = (0, es_toolkit_compat.get)(originalSchema, "paths") || {};
|
|
2394
2787
|
for (const [route, usagePathObject] of Object.entries(usagePaths)) {
|
|
@@ -2397,9 +2790,10 @@ var SwaggerSchemaResolver = class {
|
|
|
2397
2790
|
const originalRouteInfo = (0, es_toolkit_compat.get)(originalPathObject, methodName) || {};
|
|
2398
2791
|
const usageRouteParams = (0, es_toolkit_compat.get)(usageRouteInfo, "parameters") || [];
|
|
2399
2792
|
const originalRouteParams = (0, es_toolkit_compat.get)(originalRouteInfo, "parameters") || [];
|
|
2793
|
+
const usageAsOpenapiv2 = usageRouteInfo;
|
|
2400
2794
|
if (typeof usageRouteInfo === "object") {
|
|
2401
|
-
|
|
2402
|
-
|
|
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 || []]));
|
|
2403
2797
|
}
|
|
2404
2798
|
for (const originalRouteParam of originalRouteParams) if (!usageRouteParams.find((param) => originalRouteParam.in === param.in && originalRouteParam.name === param.name)) usageRouteParams.push(originalRouteParam);
|
|
2405
2799
|
}
|
|
@@ -2574,7 +2968,7 @@ var TypeNameFormatter = class {
|
|
|
2574
2968
|
]).join("_");
|
|
2575
2969
|
if (this.formattedModelNamesMap.has(hashKey)) return this.formattedModelNamesMap.get(hashKey);
|
|
2576
2970
|
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;
|
|
2971
|
+
const formattedResultName = this.config.hooks.onFormatTypeName?.(formattedName, name, schemaType) || formattedName;
|
|
2578
2972
|
this.formattedModelNamesMap.set(hashKey, formattedResultName);
|
|
2579
2973
|
return formattedResultName;
|
|
2580
2974
|
};
|
|
@@ -2673,38 +3067,35 @@ var CodeGenProcess = class {
|
|
|
2673
3067
|
fileSystem;
|
|
2674
3068
|
codeFormatter;
|
|
2675
3069
|
templatesWorker;
|
|
2676
|
-
schemaWalker;
|
|
2677
3070
|
javascriptTranslator;
|
|
3071
|
+
swaggerRefs;
|
|
2678
3072
|
constructor(config) {
|
|
2679
3073
|
this.config = new CodeGenConfig(config);
|
|
2680
3074
|
this.fileSystem = new FileSystem();
|
|
2681
3075
|
this.swaggerSchemaResolver = new SwaggerSchemaResolver(this.config, this.fileSystem);
|
|
2682
|
-
this.schemaWalker = new SchemaWalker(this.config, this.swaggerSchemaResolver);
|
|
2683
3076
|
this.schemaComponentsMap = new SchemaComponentsMap(this.config);
|
|
2684
3077
|
this.typeNameFormatter = new TypeNameFormatter(this.config);
|
|
2685
3078
|
this.templatesWorker = new TemplatesWorker(this.config, this.fileSystem, this.getRenderTemplateData);
|
|
2686
3079
|
this.codeFormatter = new CodeFormatter(this.config);
|
|
2687
|
-
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);
|
|
2688
3081
|
this.schemaRoutes = new SchemaRoutes(this.config, this.schemaParserFabric, this.schemaComponentsMap, this.templatesWorker, this.typeNameFormatter);
|
|
2689
3082
|
this.javascriptTranslator = new JavascriptTranslator(this.config, this.codeFormatter);
|
|
2690
3083
|
}
|
|
2691
3084
|
async start() {
|
|
2692
3085
|
this.config.update({ templatePaths: this.templatesWorker.getTemplatePaths(this.config) });
|
|
2693
3086
|
this.config.update({ templatesToRender: this.templatesWorker.getTemplates(this.config) });
|
|
2694
|
-
const
|
|
2695
|
-
this.swaggerSchemaResolver.fixSwaggerSchema(swagger);
|
|
3087
|
+
const resolvedSwaggerSchema = await this.swaggerSchemaResolver.create();
|
|
2696
3088
|
this.config.update({
|
|
2697
|
-
|
|
2698
|
-
|
|
3089
|
+
resolvedSwaggerSchema,
|
|
3090
|
+
swaggerSchema: resolvedSwaggerSchema.usageSchema,
|
|
3091
|
+
originalSchema: resolvedSwaggerSchema.originalSchema
|
|
2699
3092
|
});
|
|
2700
|
-
this.schemaWalker.addSchema("$usage", swagger.usageSchema);
|
|
2701
|
-
this.schemaWalker.addSchema("$original", swagger.originalSchema);
|
|
2702
3093
|
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)
|
|
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;
|
|
2706
3097
|
this.schemaComponentsMap.clear();
|
|
2707
|
-
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([
|
|
2708
3099
|
"components",
|
|
2709
3100
|
componentName,
|
|
2710
3101
|
typeName
|
|
@@ -2716,12 +3107,9 @@ var CodeGenProcess = class {
|
|
|
2716
3107
|
schemaComponent.typeData = parsed;
|
|
2717
3108
|
return parsed;
|
|
2718
3109
|
});
|
|
2719
|
-
this.schemaRoutes.attachSchema(
|
|
2720
|
-
usageSchema: swagger.usageSchema,
|
|
2721
|
-
parsedSchemas
|
|
2722
|
-
});
|
|
3110
|
+
this.schemaRoutes.attachSchema(resolvedSwaggerSchema, parsedSchemas);
|
|
2723
3111
|
const rawConfiguration = {
|
|
2724
|
-
apiConfig: this.createApiConfig(
|
|
3112
|
+
apiConfig: this.createApiConfig(resolvedSwaggerSchema.usageSchema),
|
|
2725
3113
|
config: this.config,
|
|
2726
3114
|
modelTypes: this.collectModelTypes(),
|
|
2727
3115
|
hasSecurityRoutes: this.schemaRoutes.hasSecurityRoutes,
|
|
@@ -2735,7 +3123,7 @@ var CodeGenProcess = class {
|
|
|
2735
3123
|
customTranslator: this.config.customTranslator ? new this.config.customTranslator() : null,
|
|
2736
3124
|
utils: this.getRenderTemplateData().utils
|
|
2737
3125
|
};
|
|
2738
|
-
const configuration = this.config.hooks.onPrepareConfig(rawConfiguration) || rawConfiguration;
|
|
3126
|
+
const configuration = this.config.hooks.onPrepareConfig?.(rawConfiguration) || rawConfiguration;
|
|
2739
3127
|
if (this.fileSystem.pathIsExist(this.config.output)) {
|
|
2740
3128
|
if (this.config.cleanOutput) {
|
|
2741
3129
|
consola.consola.debug("cleaning dir", this.config.output);
|
|
@@ -3174,4 +3562,4 @@ Object.defineProperty(exports, 'version', {
|
|
|
3174
3562
|
return version;
|
|
3175
3563
|
}
|
|
3176
3564
|
});
|
|
3177
|
-
//# sourceMappingURL=generate-templates-
|
|
3565
|
+
//# sourceMappingURL=generate-templates-BlSkwa8l.cjs.map
|