swagger-typescript-api 13.2.17 → 13.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/{generate-templates-BO-5CKCm.mjs → generate-templates-BaT2BiRR.mjs} +553 -146
- package/dist/generate-templates-BaT2BiRR.mjs.map +1 -0
- package/dist/{generate-templates-wjE78AWV.cjs → generate-templates-BlSkwa8l.cjs} +518 -109
- package/dist/generate-templates-BlSkwa8l.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +213 -182
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +213 -182
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -10
- package/templates/base/data-contract-jsdoc.ejs +16 -16
- package/templates/base/object-field-jsdoc.ejs +8 -8
- package/templates/base/route-docs.ejs +13 -7
- package/templates/default/api.ejs +11 -11
- package/dist/generate-templates-BO-5CKCm.mjs.map +0 -1
- package/dist/generate-templates-wjE78AWV.cjs.map +0 -1
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-DQk6qfdC.mjs";
|
|
2
2
|
import * as module from "node:module";
|
|
3
|
-
import { consola } from "consola";
|
|
3
|
+
import consola, { consola as consola$1 } from "consola";
|
|
4
4
|
import * as esToolkit from "es-toolkit";
|
|
5
|
-
import { compact, flattenDeep, isEqual, merge, omit, uniq } from "es-toolkit";
|
|
5
|
+
import { compact, flattenDeep, isEqual, mapValues, merge, omit, uniq } from "es-toolkit";
|
|
6
6
|
import * as esToolkitCompat from "es-toolkit/compat";
|
|
7
|
-
import { camelCase, get, startCase, upperFirst } from "es-toolkit/compat";
|
|
7
|
+
import { camelCase, get, reduce, startCase, upperFirst } from "es-toolkit/compat";
|
|
8
8
|
import * as typescript from "typescript";
|
|
9
9
|
import * as path$1 from "node:path";
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import { Biome, Distribution } from "@biomejs/js-api";
|
|
12
12
|
import * as nanoid from "nanoid";
|
|
13
|
+
import { typeGuard } from "yummies/type-guard";
|
|
13
14
|
import * as crypto from "node:crypto";
|
|
14
15
|
import * as swagger2openapi from "swagger2openapi";
|
|
15
16
|
import * as YAML from "yaml";
|
|
17
|
+
import * as fs from "node:fs";
|
|
18
|
+
import SwaggerParser from "@apidevtools/swagger-parser";
|
|
16
19
|
import * as url$1 from "node:url";
|
|
17
20
|
import url from "node:url";
|
|
18
21
|
import { Eta } from "eta";
|
|
19
|
-
import * as fs from "node:fs";
|
|
20
22
|
|
|
21
23
|
//#region src/code-formatter.ts
|
|
22
24
|
var CodeFormatter = class {
|
|
@@ -119,7 +121,7 @@ var NameResolver = class {
|
|
|
119
121
|
while (usageName === null) {
|
|
120
122
|
const variant = resolver(variants, extras);
|
|
121
123
|
if (variant === void 0) {
|
|
122
|
-
consola.warn("unable to resolve name. current reserved names: ", ...this.reservedNames);
|
|
124
|
+
consola$1.warn("unable to resolve name. current reserved names: ", ...this.reservedNames);
|
|
123
125
|
return null;
|
|
124
126
|
}
|
|
125
127
|
if (!shouldReserve || !this.isReserved(variant)) usageName = variant;
|
|
@@ -135,10 +137,10 @@ var NameResolver = class {
|
|
|
135
137
|
shouldReserve && this.reserve([usageName]);
|
|
136
138
|
return usageName;
|
|
137
139
|
}
|
|
138
|
-
consola.debug("trying to resolve name with using fallback name generator using variants", ...variants);
|
|
140
|
+
consola$1.debug("trying to resolve name with using fallback name generator using variants", ...variants);
|
|
139
141
|
return this.resolve(variants, this.getFallbackName, extras);
|
|
140
142
|
}
|
|
141
|
-
consola.debug("problem with reserving names. current reserved names: ", ...this.reservedNames);
|
|
143
|
+
consola$1.debug("problem with reserving names. current reserved names: ", ...this.reservedNames);
|
|
142
144
|
return null;
|
|
143
145
|
}
|
|
144
146
|
};
|
|
@@ -164,11 +166,11 @@ var ComponentTypeNameResolver = class extends NameResolver {
|
|
|
164
166
|
const variantCounter = this.countersByVariant.get(randomVariant) + 1;
|
|
165
167
|
this.countersByVariant.set(randomVariant, variantCounter);
|
|
166
168
|
const dirtyResolvedName = `${randomVariant}${variantCounter}`;
|
|
167
|
-
consola.debug("generated dirty resolved type name for component - ", dirtyResolvedName);
|
|
169
|
+
consola$1.debug("generated dirty resolved type name for component - ", dirtyResolvedName);
|
|
168
170
|
return dirtyResolvedName;
|
|
169
171
|
}
|
|
170
172
|
const fallbackName = `${this.config.componentTypeNameResolver}${this.fallbackNameCounter++}`;
|
|
171
|
-
consola.debug("generated fallback type name for component - ", fallbackName);
|
|
173
|
+
consola$1.debug("generated fallback type name for component - ", fallbackName);
|
|
172
174
|
return fallbackName;
|
|
173
175
|
});
|
|
174
176
|
}
|
|
@@ -177,7 +179,7 @@ var ComponentTypeNameResolver = class extends NameResolver {
|
|
|
177
179
|
//#endregion
|
|
178
180
|
//#region package.json
|
|
179
181
|
var name = "swagger-typescript-api";
|
|
180
|
-
var version = "13.
|
|
182
|
+
var version = "13.3.0";
|
|
181
183
|
var description = "Generate the API client for Fetch or Axios from an OpenAPI Specification";
|
|
182
184
|
|
|
183
185
|
//#endregion
|
|
@@ -246,6 +248,17 @@ const SCHEMA_TYPES$1 = {
|
|
|
246
248
|
COMPLEX_UNKNOWN: "__unknown"
|
|
247
249
|
};
|
|
248
250
|
|
|
251
|
+
//#endregion
|
|
252
|
+
//#region src/util/object-assign.ts
|
|
253
|
+
const objectAssign = (target, updater) => {
|
|
254
|
+
if (!updater) return;
|
|
255
|
+
const update = typeof updater === "function" ? updater(target) : updater;
|
|
256
|
+
if (!update) return;
|
|
257
|
+
const undefinedKeys = Object.entries(update).filter(([, value]) => value === void 0).map(([key]) => key);
|
|
258
|
+
merge(target, update);
|
|
259
|
+
for (const key of undefinedKeys) target[key] = void 0;
|
|
260
|
+
};
|
|
261
|
+
|
|
249
262
|
//#endregion
|
|
250
263
|
//#region src/configuration.ts
|
|
251
264
|
const TsKeyword = {
|
|
@@ -327,6 +340,7 @@ var CodeGenConfig = class {
|
|
|
327
340
|
onFormatTypeName: (_typeName, _rawTypeName, _schemaType) => {},
|
|
328
341
|
onFormatRouteName: (_routeInfo, _templateRouteName) => {}
|
|
329
342
|
};
|
|
343
|
+
resolvedSwaggerSchema;
|
|
330
344
|
defaultResponseType;
|
|
331
345
|
singleHttpClient = false;
|
|
332
346
|
httpClientType = HTTP_CLIENT.FETCH;
|
|
@@ -556,8 +570,8 @@ var CodeGenConfig = class {
|
|
|
556
570
|
];
|
|
557
571
|
templateExtensions = [".eta", ".ejs"];
|
|
558
572
|
constructor({ codeGenConstructs, primitiveTypeConstructs, constants, templateInfos, hooks, ...otherConfig }) {
|
|
559
|
-
|
|
560
|
-
|
|
573
|
+
objectAssign(this.Ts, codeGenConstructs);
|
|
574
|
+
objectAssign(this.primitiveTypes, primitiveTypeConstructs);
|
|
561
575
|
this.defaultResponseType = this.Ts.Keyword.Void;
|
|
562
576
|
this.update({
|
|
563
577
|
...otherConfig,
|
|
@@ -577,16 +591,21 @@ var CodeGenConfig = class {
|
|
|
577
591
|
this.componentTypeNameResolver = new ComponentTypeNameResolver(this, []);
|
|
578
592
|
}
|
|
579
593
|
update = (update) => {
|
|
580
|
-
|
|
594
|
+
objectAssign(this, update);
|
|
581
595
|
if (this.enumNamesAsValues) this.extractEnums = true;
|
|
582
596
|
};
|
|
583
597
|
};
|
|
584
598
|
|
|
599
|
+
//#endregion
|
|
600
|
+
//#region src/util/pascal-case.ts
|
|
601
|
+
function pascalCase(value) {
|
|
602
|
+
return upperFirst(camelCase(value));
|
|
603
|
+
}
|
|
604
|
+
|
|
585
605
|
//#endregion
|
|
586
606
|
//#region src/schema-components-map.ts
|
|
587
607
|
var SchemaComponentsMap = class {
|
|
588
608
|
_data = [];
|
|
589
|
-
config;
|
|
590
609
|
constructor(config) {
|
|
591
610
|
this.config = config;
|
|
592
611
|
}
|
|
@@ -599,18 +618,27 @@ var SchemaComponentsMap = class {
|
|
|
599
618
|
parseRef = (ref) => {
|
|
600
619
|
return ref.split("/");
|
|
601
620
|
};
|
|
602
|
-
|
|
621
|
+
createComponentDraft($ref, rawTypeData) {
|
|
622
|
+
if (typeGuard.isObject(rawTypeData) && rawTypeData.typeName && rawTypeData.rawTypeData && rawTypeData.$ref) return rawTypeData;
|
|
603
623
|
const parsed = this.parseRef($ref);
|
|
604
|
-
const
|
|
624
|
+
const [, rawPointer = ""] = $ref.split("#");
|
|
625
|
+
const pointerParts = (rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}`).split("/").filter(Boolean);
|
|
626
|
+
const typeName = pointerParts.at(-1) || parsed.at(-1) || "Unknown";
|
|
627
|
+
const rawComponentName = pointerParts.at(-2) || parsed[parsed.length - 2] || "schemas";
|
|
628
|
+
return {
|
|
605
629
|
$ref,
|
|
606
|
-
typeName
|
|
630
|
+
typeName,
|
|
607
631
|
rawTypeData,
|
|
608
|
-
componentName:
|
|
632
|
+
componentName: rawComponentName === "definitions" ? "schemas" : rawComponentName,
|
|
609
633
|
typeData: null
|
|
610
634
|
};
|
|
635
|
+
}
|
|
636
|
+
createComponent($ref, rawTypeData, addAtStart) {
|
|
637
|
+
const componentSchema = this.createComponentDraft($ref, rawTypeData);
|
|
611
638
|
const usageComponent = this.config.hooks.onCreateComponent(componentSchema) || componentSchema;
|
|
612
639
|
const refIndex = this._data.findIndex((c) => c.$ref === $ref);
|
|
613
|
-
if (refIndex === -1) this._data.
|
|
640
|
+
if (refIndex === -1) if (addAtStart) this._data.unshift(usageComponent);
|
|
641
|
+
else this._data.push(usageComponent);
|
|
614
642
|
else this._data[refIndex] = usageComponent;
|
|
615
643
|
return usageComponent;
|
|
616
644
|
}
|
|
@@ -621,7 +649,19 @@ var SchemaComponentsMap = class {
|
|
|
621
649
|
return this._data.filter((it) => componentNames.some((componentName) => it.$ref.startsWith(`#/components/${componentName}`)));
|
|
622
650
|
}
|
|
623
651
|
get = ($ref) => {
|
|
624
|
-
|
|
652
|
+
const localFound = this._data.find((c) => c.$ref === $ref) || null;
|
|
653
|
+
if (localFound != null) return localFound;
|
|
654
|
+
const { resolvedSwaggerSchema } = this.config;
|
|
655
|
+
if (resolvedSwaggerSchema.isLocalRef($ref)) return null;
|
|
656
|
+
const foundByRef = resolvedSwaggerSchema.getRef($ref);
|
|
657
|
+
const refDetails = resolvedSwaggerSchema.getRefDetails($ref);
|
|
658
|
+
if (foundByRef != null) {
|
|
659
|
+
const componentDraft = this.createComponentDraft($ref, foundByRef);
|
|
660
|
+
componentDraft.typeName = this.config.hooks.onFormatExternalTypeName?.(componentDraft.typeName, refDetails) || componentDraft.typeName;
|
|
661
|
+
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}`;
|
|
662
|
+
return this.createComponent($ref, componentDraft);
|
|
663
|
+
}
|
|
664
|
+
return null;
|
|
625
665
|
};
|
|
626
666
|
enumsFirst() {
|
|
627
667
|
this._data.sort((a, b) => {
|
|
@@ -657,10 +697,14 @@ var SchemaFormatters = class {
|
|
|
657
697
|
$content: parsedSchema.content,
|
|
658
698
|
content: this.config.Ts.UnionType(parsedSchema.content.map(({ value }) => value))
|
|
659
699
|
};
|
|
700
|
+
const escapedContent = parsedSchema.content.map((item) => ({
|
|
701
|
+
...item,
|
|
702
|
+
description: item.description ? this.escapeJSDocContent(item.description) : ""
|
|
703
|
+
}));
|
|
660
704
|
return {
|
|
661
705
|
...parsedSchema,
|
|
662
706
|
$content: parsedSchema.content,
|
|
663
|
-
content: this.config.Ts.EnumFieldsWrapper(
|
|
707
|
+
content: this.config.Ts.EnumFieldsWrapper(escapedContent)
|
|
664
708
|
};
|
|
665
709
|
},
|
|
666
710
|
[SCHEMA_TYPES$1.OBJECT]: (parsedSchema) => {
|
|
@@ -702,11 +746,16 @@ var SchemaFormatters = class {
|
|
|
702
746
|
const schemaType = get(parsedSchema, ["schemaType"]) || get(parsedSchema, ["$parsed", "schemaType"]);
|
|
703
747
|
return get(this, [formatType, schemaType])?.(parsedSchema) || parsedSchema;
|
|
704
748
|
};
|
|
749
|
+
escapeJSDocContent = (content) => {
|
|
750
|
+
if (content === void 0) return "";
|
|
751
|
+
return (typeof content === "string" ? content : String(content)).replace(/\*\//g, "*\\/");
|
|
752
|
+
};
|
|
705
753
|
formatDescription = (description, inline) => {
|
|
706
754
|
if (!description) return "";
|
|
707
|
-
|
|
708
|
-
if (
|
|
709
|
-
return
|
|
755
|
+
const escapedDescription = this.escapeJSDocContent(description);
|
|
756
|
+
if (!escapedDescription.includes("\n")) return escapedDescription;
|
|
757
|
+
if (inline) return compact(escapedDescription.split(/\n/g).map((part) => part.trim())).join(" ");
|
|
758
|
+
return escapedDescription.replace(/\n$/g, "");
|
|
710
759
|
};
|
|
711
760
|
formatObjectContent = (content) => {
|
|
712
761
|
const fields = [];
|
|
@@ -995,7 +1044,7 @@ var EnumKeyResolver = class extends NameResolver {
|
|
|
995
1044
|
constructor(config, reservedNames) {
|
|
996
1045
|
super(config, reservedNames, (variants) => {
|
|
997
1046
|
const generatedVariant = variants[0] && `${variants[0]}${this.counter++}` || `${this.config.enumKeyResolverName}${this.counter++}`;
|
|
998
|
-
consola.debug("generated fallback type name for enum key - ", generatedVariant);
|
|
1047
|
+
consola$1.debug("generated fallback type name for enum key - ", generatedVariant);
|
|
999
1048
|
return generatedVariant;
|
|
1000
1049
|
});
|
|
1001
1050
|
}
|
|
@@ -1270,17 +1319,15 @@ var SchemaParser = class {
|
|
|
1270
1319
|
schemaFormatters;
|
|
1271
1320
|
schemaUtils;
|
|
1272
1321
|
templatesWorker;
|
|
1273
|
-
schemaWalker;
|
|
1274
1322
|
typeName;
|
|
1275
1323
|
schema;
|
|
1276
|
-
schemaPath
|
|
1324
|
+
schemaPath;
|
|
1277
1325
|
constructor(schemaParserFabric, { typeName, schema, schemaPath } = {}) {
|
|
1278
1326
|
this.schemaParserFabric = schemaParserFabric;
|
|
1279
1327
|
this.config = schemaParserFabric.config;
|
|
1280
1328
|
this.templatesWorker = schemaParserFabric.templatesWorker;
|
|
1281
1329
|
this.schemaComponentsMap = schemaParserFabric.schemaComponentsMap;
|
|
1282
1330
|
this.typeNameFormatter = schemaParserFabric.typeNameFormatter;
|
|
1283
|
-
this.schemaWalker = schemaParserFabric.schemaWalker;
|
|
1284
1331
|
this.schemaFormatters = schemaParserFabric.schemaFormatters;
|
|
1285
1332
|
this.schemaUtils = schemaParserFabric.schemaUtils;
|
|
1286
1333
|
this.typeName = typeName || null;
|
|
@@ -1330,7 +1377,7 @@ var SchemaParser = class {
|
|
|
1330
1377
|
if (!this.typeName && this.schemaUtils.isRefSchema(this.schema)) this.typeName = this.schemaUtils.getSchemaType(this.schema);
|
|
1331
1378
|
if (this.schema.items && !Array.isArray(this.schema.items) && !this.schema.type) this.schema.type = SCHEMA_TYPES$1.ARRAY;
|
|
1332
1379
|
if (Array.isArray(this.schema.enum) && this.schema.enum.length === 1 && this.schema.enum[0] == null) {
|
|
1333
|
-
consola.debug("invalid enum schema", this.schema);
|
|
1380
|
+
consola$1.debug("invalid enum schema", this.schema);
|
|
1334
1381
|
this.schema = { type: this.config.Ts.Keyword.Null };
|
|
1335
1382
|
}
|
|
1336
1383
|
if ("content" in this.schema && typeof this.schema.content === "object") {
|
|
@@ -1375,24 +1422,13 @@ var SchemaParser = class {
|
|
|
1375
1422
|
};
|
|
1376
1423
|
};
|
|
1377
1424
|
|
|
1378
|
-
//#endregion
|
|
1379
|
-
//#region src/util/pascal-case.ts
|
|
1380
|
-
function pascalCase(value) {
|
|
1381
|
-
return upperFirst(camelCase(value));
|
|
1382
|
-
}
|
|
1383
|
-
|
|
1384
1425
|
//#endregion
|
|
1385
1426
|
//#region src/schema-parser/schema-utils.ts
|
|
1386
1427
|
var SchemaUtils = class {
|
|
1387
|
-
config
|
|
1388
|
-
schemaComponentsMap;
|
|
1389
|
-
typeNameFormatter;
|
|
1390
|
-
schemaWalker;
|
|
1391
|
-
constructor({ config, schemaComponentsMap, typeNameFormatter, schemaWalker }) {
|
|
1428
|
+
constructor(config, schemaComponentsMap, typeNameFormatter) {
|
|
1392
1429
|
this.config = config;
|
|
1393
1430
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
1394
1431
|
this.typeNameFormatter = typeNameFormatter;
|
|
1395
|
-
this.schemaWalker = schemaWalker;
|
|
1396
1432
|
}
|
|
1397
1433
|
getRequiredProperties = (schema) => {
|
|
1398
1434
|
return uniq(schema && Array.isArray(schema.required) && schema.required || []);
|
|
@@ -1538,14 +1574,12 @@ var SchemaParserFabric = class {
|
|
|
1538
1574
|
schemaFormatters;
|
|
1539
1575
|
templatesWorker;
|
|
1540
1576
|
schemaUtils;
|
|
1541
|
-
|
|
1542
|
-
constructor(config, templatesWorker, schemaComponentsMap, typeNameFormatter, schemaWalker) {
|
|
1577
|
+
constructor(config, templatesWorker, schemaComponentsMap, typeNameFormatter) {
|
|
1543
1578
|
this.config = config;
|
|
1544
1579
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
1545
1580
|
this.typeNameFormatter = typeNameFormatter;
|
|
1546
1581
|
this.templatesWorker = templatesWorker;
|
|
1547
|
-
this.
|
|
1548
|
-
this.schemaUtils = new SchemaUtils(this);
|
|
1582
|
+
this.schemaUtils = new SchemaUtils(this.config, this.schemaComponentsMap, this.typeNameFormatter);
|
|
1549
1583
|
this.schemaFormatters = new SchemaFormatters(this);
|
|
1550
1584
|
}
|
|
1551
1585
|
createSchemaParser = ({ schema, typeName, schemaPath }) => {
|
|
@@ -1612,7 +1646,7 @@ var SpecificArgNameResolver = class extends NameResolver {
|
|
|
1612
1646
|
constructor(config, reservedNames) {
|
|
1613
1647
|
super(config, reservedNames, (variants) => {
|
|
1614
1648
|
const generatedVariant = variants[0] && `${variants[0]}${this.counter++}` || `${this.config.specificArgNameResolverName}${this.counter++}`;
|
|
1615
|
-
consola.debug("generated fallback type name for specific arg - ", generatedVariant);
|
|
1649
|
+
consola$1.debug("generated fallback type name for specific arg - ", generatedVariant);
|
|
1616
1650
|
return generatedVariant;
|
|
1617
1651
|
});
|
|
1618
1652
|
}
|
|
@@ -1630,12 +1664,7 @@ const CONTENT_KIND = {
|
|
|
1630
1664
|
TEXT: "TEXT"
|
|
1631
1665
|
};
|
|
1632
1666
|
var SchemaRoutes = class {
|
|
1633
|
-
config;
|
|
1634
|
-
schemaParserFabric;
|
|
1635
1667
|
schemaUtils;
|
|
1636
|
-
typeNameFormatter;
|
|
1637
|
-
schemaComponentsMap;
|
|
1638
|
-
templatesWorker;
|
|
1639
1668
|
FORM_DATA_TYPES = [];
|
|
1640
1669
|
routes = [];
|
|
1641
1670
|
hasSecurityRoutes = false;
|
|
@@ -1644,10 +1673,10 @@ var SchemaRoutes = class {
|
|
|
1644
1673
|
constructor(config, schemaParserFabric, schemaComponentsMap, templatesWorker, typeNameFormatter) {
|
|
1645
1674
|
this.config = config;
|
|
1646
1675
|
this.schemaParserFabric = schemaParserFabric;
|
|
1647
|
-
this.schemaUtils = this.schemaParserFabric.schemaUtils;
|
|
1648
|
-
this.typeNameFormatter = typeNameFormatter;
|
|
1649
1676
|
this.schemaComponentsMap = schemaComponentsMap;
|
|
1650
1677
|
this.templatesWorker = templatesWorker;
|
|
1678
|
+
this.typeNameFormatter = typeNameFormatter;
|
|
1679
|
+
this.schemaUtils = this.schemaParserFabric.schemaUtils;
|
|
1651
1680
|
this.FORM_DATA_TYPES = uniq([this.schemaUtils.getSchemaType({
|
|
1652
1681
|
type: "string",
|
|
1653
1682
|
format: "file"
|
|
@@ -1656,11 +1685,16 @@ var SchemaRoutes = class {
|
|
|
1656
1685
|
format: "binary"
|
|
1657
1686
|
})]);
|
|
1658
1687
|
}
|
|
1659
|
-
createRequestsMap = (routesByMethod) => {
|
|
1688
|
+
createRequestsMap = (resolvedSwaggerSchema, routesByMethod) => {
|
|
1660
1689
|
const parameters = get(routesByMethod, "parameters");
|
|
1661
1690
|
const result = {};
|
|
1662
1691
|
for (const [method, requestInfo] of Object.entries(routesByMethod)) {
|
|
1663
|
-
if (method.startsWith("x-") || ["parameters"
|
|
1692
|
+
if (method.startsWith("x-") || ["parameters"].includes(method)) continue;
|
|
1693
|
+
if (method === "$ref") {
|
|
1694
|
+
const refData = resolvedSwaggerSchema.getRef(requestInfo);
|
|
1695
|
+
if (typeGuard.isObject(refData)) Object.assign(result, this.createRequestsMap(resolvedSwaggerSchema, refData));
|
|
1696
|
+
continue;
|
|
1697
|
+
}
|
|
1664
1698
|
result[method] = {
|
|
1665
1699
|
...requestInfo,
|
|
1666
1700
|
parameters: compact([...parameters || [], ...requestInfo.parameters || []])
|
|
@@ -1675,7 +1709,7 @@ var SchemaRoutes = class {
|
|
|
1675
1709
|
for (const match of pathParamMatches || []) {
|
|
1676
1710
|
const paramName = match.replace(/\{|\}|:/g, "");
|
|
1677
1711
|
if (!paramName) continue;
|
|
1678
|
-
if (paramName.includes("-")) consola.warn("wrong path param name", paramName);
|
|
1712
|
+
if (paramName.includes("-")) consola$1.warn("wrong path param name", paramName);
|
|
1679
1713
|
pathParams.push({
|
|
1680
1714
|
$match: match,
|
|
1681
1715
|
name: camelCase(paramName),
|
|
@@ -1696,7 +1730,7 @@ var SchemaRoutes = class {
|
|
|
1696
1730
|
for (const match of queryParamMatches) fixedRoute = fixedRoute.replace(match, "");
|
|
1697
1731
|
const paramNames = uniq(queryParamMatches.join(",").replace(/(\{\?)|(\})|\s/g, "").split(","));
|
|
1698
1732
|
for (const paramName of paramNames) {
|
|
1699
|
-
if (typeof paramName === "string" && paramName.includes("-")) consola.warn("wrong query param name", paramName);
|
|
1733
|
+
if (typeof paramName === "string" && paramName.includes("-")) consola$1.warn("wrong query param name", paramName);
|
|
1700
1734
|
queryParams.push({
|
|
1701
1735
|
$match: paramName,
|
|
1702
1736
|
name: typeof paramName === "string" ? camelCase(paramName) : camelCase(String(paramName)),
|
|
@@ -1729,7 +1763,7 @@ var SchemaRoutes = class {
|
|
|
1729
1763
|
for (const parameter of parameters || []) {
|
|
1730
1764
|
const refTypeInfo = this.schemaParserFabric.schemaUtils.getSchemaRefType(parameter);
|
|
1731
1765
|
let routeParam = null;
|
|
1732
|
-
if (refTypeInfo?.rawTypeData
|
|
1766
|
+
if (!!refTypeInfo?.rawTypeData && typeof refTypeInfo === "object" && refTypeInfo?.rawTypeData.in) {
|
|
1733
1767
|
if (!routeParams[refTypeInfo.rawTypeData.in]) routeParams[refTypeInfo.rawTypeData.in] = [];
|
|
1734
1768
|
routeParam = {
|
|
1735
1769
|
...refTypeInfo.rawTypeData,
|
|
@@ -1799,10 +1833,11 @@ var SchemaRoutes = class {
|
|
|
1799
1833
|
}
|
|
1800
1834
|
return defaultType || this.config.Ts.Keyword.Any;
|
|
1801
1835
|
};
|
|
1802
|
-
getRequestInfoTypes = ({ requestInfos, parsedSchemas, operationId, defaultType }) => {
|
|
1836
|
+
getRequestInfoTypes = ({ requestInfos, parsedSchemas, operationId, defaultType, resolvedSwaggerSchema }) => {
|
|
1803
1837
|
const result = [];
|
|
1804
1838
|
for (const [status, requestInfo] of Object.entries(requestInfos || {})) {
|
|
1805
1839
|
const contentTypes = this.getContentTypes([requestInfo], operationId);
|
|
1840
|
+
const links = this.getRouteLinksFromResponse(resolvedSwaggerSchema, requestInfo, status);
|
|
1806
1841
|
result.push({
|
|
1807
1842
|
...requestInfo || {},
|
|
1808
1843
|
contentTypes,
|
|
@@ -1814,21 +1849,48 @@ var SchemaRoutes = class {
|
|
|
1814
1849
|
defaultType
|
|
1815
1850
|
})),
|
|
1816
1851
|
description: this.schemaParserFabric.schemaFormatters.formatDescription(requestInfo.description || "", true),
|
|
1852
|
+
links,
|
|
1817
1853
|
status: Number.isNaN(+status) ? status : +status,
|
|
1818
1854
|
isSuccess: this.isSuccessStatus(status)
|
|
1819
1855
|
});
|
|
1820
1856
|
}
|
|
1821
1857
|
return result;
|
|
1822
1858
|
};
|
|
1823
|
-
|
|
1859
|
+
getRouteLinksFromResponse = (resolvedSwaggerSchema, responseInfo, status) => {
|
|
1860
|
+
const links = get(responseInfo, "links");
|
|
1861
|
+
if (!typeGuard.isObject(links)) return [];
|
|
1862
|
+
return reduce(links, (acc, linkInfo, linkName) => {
|
|
1863
|
+
if (!typeGuard.isObject(linkInfo)) return acc;
|
|
1864
|
+
let normalizedLinkInfo = linkInfo;
|
|
1865
|
+
if (typeof linkInfo.$ref === "string") {
|
|
1866
|
+
const refData = resolvedSwaggerSchema.getRef(linkInfo.$ref);
|
|
1867
|
+
if (typeGuard.isObject(refData)) normalizedLinkInfo = refData;
|
|
1868
|
+
}
|
|
1869
|
+
const operationId = typeof normalizedLinkInfo.operationId === "string" ? normalizedLinkInfo.operationId : void 0;
|
|
1870
|
+
const operationRef = typeof normalizedLinkInfo.operationRef === "string" ? normalizedLinkInfo.operationRef : typeof linkInfo.$ref === "string" ? linkInfo.$ref : void 0;
|
|
1871
|
+
if (!operationId && !operationRef) return acc;
|
|
1872
|
+
const parameters = typeGuard.isObject(normalizedLinkInfo.parameters) ? mapValues(normalizedLinkInfo.parameters, (value) => String(value)) : void 0;
|
|
1873
|
+
acc.push({
|
|
1874
|
+
status: Number.isNaN(+status) ? status : +status,
|
|
1875
|
+
name: String(linkName),
|
|
1876
|
+
operationId,
|
|
1877
|
+
operationRef,
|
|
1878
|
+
parameters
|
|
1879
|
+
});
|
|
1880
|
+
return acc;
|
|
1881
|
+
}, []);
|
|
1882
|
+
};
|
|
1883
|
+
getResponseBodyInfo = (routeInfo, parsedSchemas, resolvedSwaggerSchema) => {
|
|
1824
1884
|
const { produces, operationId, responses } = routeInfo;
|
|
1825
1885
|
const contentTypes = this.getContentTypes(responses, [...produces || [], routeInfo["x-accepts"]]);
|
|
1826
1886
|
const responseInfos = this.getRequestInfoTypes({
|
|
1827
1887
|
requestInfos: responses,
|
|
1828
1888
|
parsedSchemas,
|
|
1829
1889
|
operationId,
|
|
1830
|
-
defaultType: this.config.defaultResponseType
|
|
1890
|
+
defaultType: this.config.defaultResponseType,
|
|
1891
|
+
resolvedSwaggerSchema
|
|
1831
1892
|
});
|
|
1893
|
+
const links = responseInfos.flatMap((responseInfo) => responseInfo.links || []);
|
|
1832
1894
|
const successResponse = responseInfos.find((response) => response.isSuccess);
|
|
1833
1895
|
const errorResponses = responseInfos.filter((response) => !response.isSuccess && response.type !== this.config.Ts.Keyword.Any);
|
|
1834
1896
|
const handleResponseHeaders = (src) => {
|
|
@@ -1841,6 +1903,7 @@ var SchemaRoutes = class {
|
|
|
1841
1903
|
return {
|
|
1842
1904
|
contentTypes,
|
|
1843
1905
|
responses: responseInfos,
|
|
1906
|
+
links,
|
|
1844
1907
|
success: {
|
|
1845
1908
|
schema: successResponse,
|
|
1846
1909
|
type: successResponse?.type || this.config.Ts.Keyword.Any
|
|
@@ -2011,11 +2074,11 @@ var SchemaRoutes = class {
|
|
|
2011
2074
|
const { routeNameDuplicatesMap, templatesToRender } = this.config;
|
|
2012
2075
|
const routeNameTemplate = templatesToRender.routeName;
|
|
2013
2076
|
const routeNameFromTemplate = this.templatesWorker.renderTemplate(routeNameTemplate, { routeInfo: rawRouteInfo });
|
|
2014
|
-
const routeName = this.config.hooks.onFormatRouteName(rawRouteInfo, routeNameFromTemplate) || routeNameFromTemplate;
|
|
2077
|
+
const routeName = this.config.hooks.onFormatRouteName?.(rawRouteInfo, routeNameFromTemplate) || routeNameFromTemplate;
|
|
2015
2078
|
const duplicateIdentifier = `${moduleName}|${routeName}`;
|
|
2016
2079
|
if (routeNameDuplicatesMap.has(duplicateIdentifier)) {
|
|
2017
2080
|
routeNameDuplicatesMap.set(duplicateIdentifier, routeNameDuplicatesMap.get(duplicateIdentifier) + 1);
|
|
2018
|
-
consola.warn(`Module "${moduleName}" already has method "${routeName}()".`, `This method has been renamed to "${routeName + routeNameDuplicatesMap.get(duplicateIdentifier)}()" to solve conflict names.`);
|
|
2081
|
+
consola$1.warn(`Module "${moduleName}" already has method "${routeName}()".`, `This method has been renamed to "${routeName + routeNameDuplicatesMap.get(duplicateIdentifier)}()" to solve conflict names.`);
|
|
2019
2082
|
} else routeNameDuplicatesMap.set(duplicateIdentifier, 1);
|
|
2020
2083
|
const duplicates = routeNameDuplicatesMap.get(duplicateIdentifier);
|
|
2021
2084
|
const routeNameInfo = {
|
|
@@ -2023,10 +2086,10 @@ var SchemaRoutes = class {
|
|
|
2023
2086
|
original: routeName,
|
|
2024
2087
|
duplicate: duplicates > 1
|
|
2025
2088
|
};
|
|
2026
|
-
return this.config.hooks.onCreateRouteName(routeNameInfo, rawRouteInfo) || routeNameInfo;
|
|
2089
|
+
return this.config.hooks.onCreateRouteName?.(routeNameInfo, rawRouteInfo) || routeNameInfo;
|
|
2027
2090
|
};
|
|
2028
|
-
parseRouteInfo = (rawRouteName, routeInfo, method,
|
|
2029
|
-
const { security: globalSecurity } = usageSchema;
|
|
2091
|
+
parseRouteInfo = (rawRouteName, routeInfo, method, resolvedSwaggerSchema, parsedSchemas) => {
|
|
2092
|
+
const { security: globalSecurity } = resolvedSwaggerSchema.usageSchema;
|
|
2030
2093
|
const { moduleNameIndex, moduleNameFirstTag, extractRequestParams } = this.config;
|
|
2031
2094
|
const { operationId, requestBody, security, parameters, summary, description, tags, responses, requestBodyName, produces, consumes, ...otherInfo } = routeInfo;
|
|
2032
2095
|
const { route, pathParams: pathParamsFromRouteName, queryParams: queryParamsFromRouteName } = this.parseRouteName(rawRouteName);
|
|
@@ -2043,7 +2106,7 @@ var SchemaRoutes = class {
|
|
|
2043
2106
|
description: pathArgSchema.description
|
|
2044
2107
|
}));
|
|
2045
2108
|
const pathArgsNames = pathArgs.map((arg) => arg.name);
|
|
2046
|
-
const responseBodyInfo = this.getResponseBodyInfo(routeInfo, parsedSchemas);
|
|
2109
|
+
const responseBodyInfo = this.getResponseBodyInfo(routeInfo, parsedSchemas, resolvedSwaggerSchema);
|
|
2047
2110
|
const rawRouteInfo = {
|
|
2048
2111
|
...otherInfo,
|
|
2049
2112
|
pathArgs,
|
|
@@ -2052,6 +2115,7 @@ var SchemaRoutes = class {
|
|
|
2052
2115
|
route: rawRouteName,
|
|
2053
2116
|
moduleName,
|
|
2054
2117
|
responsesTypes: responseBodyInfo.responses,
|
|
2118
|
+
links: responseBodyInfo.links,
|
|
2055
2119
|
description,
|
|
2056
2120
|
tags,
|
|
2057
2121
|
summary,
|
|
@@ -2147,13 +2211,13 @@ var SchemaRoutes = class {
|
|
|
2147
2211
|
raw: rawRouteInfo
|
|
2148
2212
|
};
|
|
2149
2213
|
};
|
|
2150
|
-
attachSchema = (
|
|
2214
|
+
attachSchema = (resolvedSwaggerSchema, parsedSchemas) => {
|
|
2151
2215
|
this.config.routeNameDuplicatesMap.clear();
|
|
2152
|
-
const pathsEntries = Object.entries(usageSchema.paths || {});
|
|
2216
|
+
const pathsEntries = Object.entries(resolvedSwaggerSchema.usageSchema.paths || {});
|
|
2153
2217
|
for (const [rawRouteName, routeInfoByMethodsMap] of pathsEntries) {
|
|
2154
|
-
const routeInfosMap = this.createRequestsMap(routeInfoByMethodsMap);
|
|
2218
|
+
const routeInfosMap = this.createRequestsMap(resolvedSwaggerSchema, routeInfoByMethodsMap);
|
|
2155
2219
|
for (const [method, routeInfo] of Object.entries(routeInfosMap)) {
|
|
2156
|
-
const parsedRouteInfo = this.parseRouteInfo(rawRouteName, routeInfo, method,
|
|
2220
|
+
const parsedRouteInfo = this.parseRouteInfo(rawRouteName, routeInfo, method, resolvedSwaggerSchema, parsedSchemas);
|
|
2157
2221
|
const processedRouteInfo = this.config.hooks.onCreateRoute(parsedRouteInfo);
|
|
2158
2222
|
if (processedRouteInfo !== false) {
|
|
2159
2223
|
const route = processedRouteInfo || parsedRouteInfo;
|
|
@@ -2207,30 +2271,353 @@ var SchemaRoutes = class {
|
|
|
2207
2271
|
};
|
|
2208
2272
|
|
|
2209
2273
|
//#endregion
|
|
2210
|
-
//#region src/schema
|
|
2211
|
-
var
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2274
|
+
//#region src/resolved-swagger-schema.ts
|
|
2275
|
+
var ResolvedSwaggerSchema = class ResolvedSwaggerSchema {
|
|
2276
|
+
parsedRefsCache = /* @__PURE__ */ new Map();
|
|
2277
|
+
externalSchemaCache = /* @__PURE__ */ new Map();
|
|
2278
|
+
httpMethodSegments = new Set([
|
|
2279
|
+
"get",
|
|
2280
|
+
"put",
|
|
2281
|
+
"post",
|
|
2282
|
+
"delete",
|
|
2283
|
+
"patch",
|
|
2284
|
+
"options",
|
|
2285
|
+
"head",
|
|
2286
|
+
"trace",
|
|
2287
|
+
"parameters"
|
|
2288
|
+
]);
|
|
2289
|
+
normalizeRef(ref) {
|
|
2290
|
+
let normalizedRef = ref;
|
|
2291
|
+
normalizedRef = normalizedRef.replace(/\/#(?=\/)/, "#");
|
|
2292
|
+
normalizedRef = normalizedRef.replace(/#(?!\/)/, "#/");
|
|
2293
|
+
return normalizedRef;
|
|
2294
|
+
}
|
|
2295
|
+
createEscapedPathsRefVariant(ref) {
|
|
2296
|
+
const [prefix = "", rawPointer = ""] = this.normalizeRef(ref).split("#");
|
|
2297
|
+
const pointer = rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}`;
|
|
2298
|
+
if (!pointer.startsWith("/paths/") || pointer.startsWith("/paths/~1")) return null;
|
|
2299
|
+
const rest = pointer.slice(7);
|
|
2300
|
+
if (!rest) return null;
|
|
2301
|
+
const parts = rest.split("/");
|
|
2302
|
+
const last = parts.at(-1)?.toLowerCase() || "";
|
|
2303
|
+
const hasTailSegment = this.httpMethodSegments.has(last);
|
|
2304
|
+
const pathParts = hasTailSegment ? parts.slice(0, -1) : parts;
|
|
2305
|
+
const tail = hasTailSegment ? `/${parts.at(-1)}` : "";
|
|
2306
|
+
if (!pathParts.length) return null;
|
|
2307
|
+
return `${prefix}#/paths/${`~1${pathParts.join("/").replace(/\//g, "~1")}`}${tail}`;
|
|
2308
|
+
}
|
|
2309
|
+
isHttpUrl(value) {
|
|
2310
|
+
return /^https?:\/\//i.test(value);
|
|
2311
|
+
}
|
|
2312
|
+
getRemoteRequestHeaders() {
|
|
2313
|
+
return Object.assign({}, this.config.authorizationToken ? { Authorization: this.config.authorizationToken } : {}, this.config.requestOptions?.headers || {});
|
|
2314
|
+
}
|
|
2315
|
+
stripHash(urlOrPath) {
|
|
2316
|
+
return urlOrPath.split("#")[0] || urlOrPath;
|
|
2317
|
+
}
|
|
2318
|
+
extractRefsFromSchema(schema) {
|
|
2319
|
+
const refs = /* @__PURE__ */ new Set();
|
|
2320
|
+
const walk = (node) => {
|
|
2321
|
+
if (!node || typeof node !== "object") return;
|
|
2322
|
+
if (Array.isArray(node)) {
|
|
2323
|
+
for (const item of node) walk(item);
|
|
2324
|
+
return;
|
|
2325
|
+
}
|
|
2326
|
+
const recordNode = node;
|
|
2327
|
+
if (typeof recordNode.$ref === "string") refs.add(recordNode.$ref);
|
|
2328
|
+
for (const value of Object.values(recordNode)) walk(value);
|
|
2329
|
+
};
|
|
2330
|
+
walk(schema);
|
|
2331
|
+
return [...refs];
|
|
2332
|
+
}
|
|
2333
|
+
async fetchRemoteSchemaDocument(url) {
|
|
2334
|
+
try {
|
|
2335
|
+
const response = await fetch(url, { headers: this.getRemoteRequestHeaders() });
|
|
2336
|
+
if (!response.ok) return null;
|
|
2337
|
+
const content = await response.text();
|
|
2338
|
+
try {
|
|
2339
|
+
const parsed = JSON.parse(content);
|
|
2340
|
+
if (parsed && typeof parsed === "object") return parsed;
|
|
2341
|
+
} catch {
|
|
2342
|
+
const parsed = YAML.parse(content);
|
|
2343
|
+
if (parsed && typeof parsed === "object") return parsed;
|
|
2344
|
+
}
|
|
2345
|
+
} catch (e) {
|
|
2346
|
+
consola.debug(e);
|
|
2347
|
+
}
|
|
2348
|
+
return null;
|
|
2349
|
+
}
|
|
2350
|
+
async warmUpRemoteSchemasCache() {
|
|
2351
|
+
if (typeof this.config.url !== "string" || !this.isHttpUrl(this.config.url)) return;
|
|
2352
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2353
|
+
const queue = [this.stripHash(this.config.url)];
|
|
2354
|
+
while (queue.length > 0) {
|
|
2355
|
+
const currentUrl = queue.shift();
|
|
2356
|
+
if (!currentUrl || visited.has(currentUrl)) continue;
|
|
2357
|
+
visited.add(currentUrl);
|
|
2358
|
+
if (this.externalSchemaCache.has(currentUrl)) continue;
|
|
2359
|
+
const schema = await this.fetchRemoteSchemaDocument(currentUrl);
|
|
2360
|
+
if (!schema) continue;
|
|
2361
|
+
this.externalSchemaCache.set(currentUrl, schema);
|
|
2362
|
+
for (const ref of this.extractRefsFromSchema(schema)) {
|
|
2363
|
+
const normalizedRef = this.normalizeRef(ref);
|
|
2364
|
+
if (normalizedRef.startsWith("#")) continue;
|
|
2365
|
+
const [externalPath = ""] = normalizedRef.split("#");
|
|
2366
|
+
if (!externalPath) continue;
|
|
2367
|
+
let absoluteUrl = "";
|
|
2368
|
+
try {
|
|
2369
|
+
absoluteUrl = this.isHttpUrl(externalPath) ? this.stripHash(externalPath) : this.stripHash(new URL(externalPath, currentUrl).toString());
|
|
2370
|
+
} catch (e) {
|
|
2371
|
+
consola.debug(e);
|
|
2372
|
+
}
|
|
2373
|
+
if (absoluteUrl && !visited.has(absoluteUrl)) queue.push(absoluteUrl);
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
collectRemoteAbsoluteRefCandidates(ref) {
|
|
2378
|
+
if (!ref || this.isHttpUrl(ref) || ref.startsWith("#")) return [];
|
|
2379
|
+
const [relativePath = "", rawPointer = ""] = this.normalizeRef(ref).split("#");
|
|
2380
|
+
if (!relativePath) return [];
|
|
2381
|
+
const pointer = rawPointer ? rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}` : "";
|
|
2382
|
+
const bases = /* @__PURE__ */ new Set();
|
|
2383
|
+
if (typeof this.config.url === "string" && this.isHttpUrl(this.config.url)) bases.add(this.config.url);
|
|
2384
|
+
for (const cachedUrl of this.externalSchemaCache.keys()) if (this.isHttpUrl(cachedUrl)) bases.add(cachedUrl);
|
|
2385
|
+
for (const resolver of this.resolvers) try {
|
|
2386
|
+
const resolverPaths = typeof resolver.paths === "function" ? resolver.paths() : [];
|
|
2387
|
+
for (const resolverPath of resolverPaths) if (typeof resolverPath === "string" && this.isHttpUrl(resolverPath)) bases.add(resolverPath);
|
|
2388
|
+
} catch (e) {
|
|
2389
|
+
consola.debug(e);
|
|
2390
|
+
}
|
|
2391
|
+
const results = /* @__PURE__ */ new Set();
|
|
2392
|
+
for (const base of bases) try {
|
|
2393
|
+
const absolutePath = new URL(relativePath, base).toString();
|
|
2394
|
+
results.add(pointer ? `${absolutePath}#${pointer}` : absolutePath);
|
|
2395
|
+
} catch (e) {
|
|
2396
|
+
consola.debug(e);
|
|
2397
|
+
}
|
|
2398
|
+
return [...results];
|
|
2399
|
+
}
|
|
2400
|
+
resolveFromRemoteSchemaCache(absoluteRef) {
|
|
2401
|
+
const [externalPath = "", rawPointer = ""] = this.normalizeRef(absoluteRef).split("#");
|
|
2402
|
+
if (!externalPath || !this.isHttpUrl(externalPath)) return null;
|
|
2403
|
+
const schema = this.externalSchemaCache.get(this.stripHash(externalPath));
|
|
2404
|
+
if (!schema) return null;
|
|
2405
|
+
const pointer = rawPointer ? rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}` : "/";
|
|
2406
|
+
const resolved = this.resolveJsonPointer(schema, pointer);
|
|
2407
|
+
if (resolved == null) return null;
|
|
2408
|
+
return this.absolutizeLocalRefs(resolved, this.stripHash(externalPath));
|
|
2409
|
+
}
|
|
2410
|
+
constructor(config, usageSchema, originalSchema, resolvers) {
|
|
2217
2411
|
this.config = config;
|
|
2218
|
-
this.
|
|
2412
|
+
this.usageSchema = usageSchema;
|
|
2413
|
+
this.originalSchema = originalSchema;
|
|
2414
|
+
this.resolvers = resolvers;
|
|
2415
|
+
this.usageSchema = usageSchema;
|
|
2416
|
+
this.originalSchema = originalSchema;
|
|
2417
|
+
}
|
|
2418
|
+
getRefDetails(ref) {
|
|
2419
|
+
const normalizedRef = this.normalizeRef(ref);
|
|
2420
|
+
if (!this.parsedRefsCache.has(ref)) {
|
|
2421
|
+
const isLocal = normalizedRef.startsWith("#");
|
|
2422
|
+
if (isLocal) this.parsedRefsCache.set(ref, {
|
|
2423
|
+
ref: normalizedRef,
|
|
2424
|
+
isLocal,
|
|
2425
|
+
externalUrlOrPath: null
|
|
2426
|
+
});
|
|
2427
|
+
else {
|
|
2428
|
+
const externalUrlOrPath = normalizedRef.split("#")[0] || "";
|
|
2429
|
+
let externalOpenapiFileName = externalUrlOrPath.replace(/\/$/, "").split("/").at(-1) || "";
|
|
2430
|
+
if (externalOpenapiFileName.endsWith(".json") || externalOpenapiFileName.endsWith(".yaml")) externalOpenapiFileName = externalOpenapiFileName.slice(0, -5);
|
|
2431
|
+
else if (externalOpenapiFileName.endsWith(".yml")) externalOpenapiFileName = externalOpenapiFileName.slice(0, -4);
|
|
2432
|
+
this.parsedRefsCache.set(ref, {
|
|
2433
|
+
ref: normalizedRef,
|
|
2434
|
+
isLocal,
|
|
2435
|
+
externalUrlOrPath,
|
|
2436
|
+
externalOpenapiFileName
|
|
2437
|
+
});
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
const cachedRef = this.parsedRefsCache.get(ref);
|
|
2441
|
+
if (cachedRef) return cachedRef;
|
|
2442
|
+
if (normalizedRef.startsWith("#")) return {
|
|
2443
|
+
ref: normalizedRef,
|
|
2444
|
+
isLocal: true,
|
|
2445
|
+
externalUrlOrPath: null
|
|
2446
|
+
};
|
|
2447
|
+
return {
|
|
2448
|
+
ref: normalizedRef,
|
|
2449
|
+
isLocal: false,
|
|
2450
|
+
externalUrlOrPath: normalizedRef.split("#")[0] || null,
|
|
2451
|
+
externalOpenapiFileName: ""
|
|
2452
|
+
};
|
|
2453
|
+
}
|
|
2454
|
+
isLocalRef(ref) {
|
|
2455
|
+
return this.getRefDetails(ref).isLocal;
|
|
2456
|
+
}
|
|
2457
|
+
getRef(ref) {
|
|
2458
|
+
if (!ref) return null;
|
|
2459
|
+
const normalizedRef = this.normalizeRef(ref);
|
|
2460
|
+
const escapedPathsRefVariant = this.createEscapedPathsRefVariant(ref);
|
|
2461
|
+
if (normalizedRef !== ref) {
|
|
2462
|
+
const resolvedByNormalizedRef = this.tryToResolveRef(normalizedRef);
|
|
2463
|
+
if (resolvedByNormalizedRef) return this.normalizeResolvedExternalSchemaRef(normalizedRef, resolvedByNormalizedRef);
|
|
2464
|
+
}
|
|
2465
|
+
if (escapedPathsRefVariant) {
|
|
2466
|
+
const resolvedByEscapedPathsRef = this.tryToResolveRef(escapedPathsRefVariant);
|
|
2467
|
+
if (resolvedByEscapedPathsRef) return this.normalizeResolvedExternalSchemaRef(escapedPathsRefVariant, resolvedByEscapedPathsRef);
|
|
2468
|
+
}
|
|
2469
|
+
const remoteAbsoluteCandidates = this.collectRemoteAbsoluteRefCandidates(ref);
|
|
2470
|
+
for (const remoteAbsoluteRef of remoteAbsoluteCandidates) {
|
|
2471
|
+
const resolvedFromRemoteCache = this.resolveFromRemoteSchemaCache(remoteAbsoluteRef);
|
|
2472
|
+
if (resolvedFromRemoteCache) return resolvedFromRemoteCache;
|
|
2473
|
+
const resolvedByRemoteAbsoluteRef = this.tryToResolveRef(remoteAbsoluteRef);
|
|
2474
|
+
if (resolvedByRemoteAbsoluteRef) return this.normalizeResolvedExternalSchemaRef(remoteAbsoluteRef, resolvedByRemoteAbsoluteRef);
|
|
2475
|
+
}
|
|
2476
|
+
const resolvedByOrigRef = this.tryToResolveRef(ref);
|
|
2477
|
+
if (resolvedByOrigRef) return this.normalizeResolvedExternalSchemaRef(ref, resolvedByOrigRef);
|
|
2478
|
+
if (/#[a-z]/.test(ref)) {
|
|
2479
|
+
const fixedRef = ref.replace(/#[a-z]/, (match) => {
|
|
2480
|
+
const [hashtag, char] = match.split("");
|
|
2481
|
+
return `${hashtag}/${char}`;
|
|
2482
|
+
});
|
|
2483
|
+
const resolvedByFixedRef = this.tryToResolveRef(fixedRef);
|
|
2484
|
+
if (resolvedByFixedRef) return this.normalizeResolvedExternalSchemaRef(fixedRef, resolvedByFixedRef);
|
|
2485
|
+
}
|
|
2486
|
+
return this.tryToResolveRefFromFile(normalizedRef);
|
|
2487
|
+
}
|
|
2488
|
+
tryToResolveRef(ref) {
|
|
2489
|
+
if (!this.resolvers || !ref) return null;
|
|
2490
|
+
for (const resolver of this.resolvers) try {
|
|
2491
|
+
return resolver.get(ref);
|
|
2492
|
+
} catch (e) {
|
|
2493
|
+
consola.debug(e);
|
|
2494
|
+
}
|
|
2495
|
+
return null;
|
|
2496
|
+
}
|
|
2497
|
+
readExternalSchema(filePath) {
|
|
2498
|
+
if (this.externalSchemaCache.has(filePath)) return this.externalSchemaCache.get(filePath) || null;
|
|
2499
|
+
if (!fs.existsSync(filePath)) return null;
|
|
2500
|
+
try {
|
|
2501
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
2502
|
+
const parsed = JSON.parse(content);
|
|
2503
|
+
this.externalSchemaCache.set(filePath, parsed);
|
|
2504
|
+
return parsed;
|
|
2505
|
+
} catch {
|
|
2506
|
+
try {
|
|
2507
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
2508
|
+
const parsed = YAML.parse(content);
|
|
2509
|
+
if (parsed && typeof parsed === "object") {
|
|
2510
|
+
this.externalSchemaCache.set(filePath, parsed);
|
|
2511
|
+
return parsed;
|
|
2512
|
+
}
|
|
2513
|
+
} catch (e) {
|
|
2514
|
+
consola.debug(e);
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
return null;
|
|
2518
|
+
}
|
|
2519
|
+
resolveJsonPointer(source, pointer) {
|
|
2520
|
+
if (!source || typeof source !== "object") return null;
|
|
2521
|
+
if (!pointer || pointer === "/") return source;
|
|
2522
|
+
const tokens = pointer.replace(/^\/+/, "").split("/").filter(Boolean).map((part) => decodeURIComponent(part.replace(/~1/g, "/").replace(/~0/g, "~")));
|
|
2523
|
+
let current = source;
|
|
2524
|
+
for (const token of tokens) {
|
|
2525
|
+
if (!current || typeof current !== "object") return null;
|
|
2526
|
+
current = current[token];
|
|
2527
|
+
}
|
|
2528
|
+
return current ?? null;
|
|
2529
|
+
}
|
|
2530
|
+
absolutizeLocalRefs(value, externalPath) {
|
|
2531
|
+
if (value == null || typeof value !== "object") return value;
|
|
2532
|
+
const cloneValue = structuredClone(value);
|
|
2533
|
+
const walk = (node) => {
|
|
2534
|
+
if (!node || typeof node !== "object") return;
|
|
2535
|
+
if (Array.isArray(node)) {
|
|
2536
|
+
for (const item of node) walk(item);
|
|
2537
|
+
return;
|
|
2538
|
+
}
|
|
2539
|
+
const recordNode = node;
|
|
2540
|
+
if (typeof recordNode.$ref === "string" && recordNode.$ref.startsWith("#")) recordNode.$ref = `${externalPath}${this.normalizeRef(recordNode.$ref)}`;
|
|
2541
|
+
for (const nested of Object.values(recordNode)) walk(nested);
|
|
2542
|
+
};
|
|
2543
|
+
walk(cloneValue);
|
|
2544
|
+
return cloneValue;
|
|
2545
|
+
}
|
|
2546
|
+
normalizeResolvedExternalSchemaRef(ref, resolved) {
|
|
2547
|
+
const normalizedRef = this.normalizeRef(ref);
|
|
2548
|
+
if (normalizedRef.startsWith("#")) return resolved;
|
|
2549
|
+
const externalPath = normalizedRef.split("#")[0] || "";
|
|
2550
|
+
if (!externalPath) return resolved;
|
|
2551
|
+
return this.absolutizeLocalRefs(resolved, externalPath);
|
|
2552
|
+
}
|
|
2553
|
+
collectExternalRefCandidates(externalPath) {
|
|
2554
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
2555
|
+
if (/^https?:\/\//i.test(externalPath)) return [];
|
|
2556
|
+
if (path.isAbsolute(externalPath)) candidates.add(externalPath);
|
|
2557
|
+
const inputPath = this.config.input;
|
|
2558
|
+
if (typeof inputPath === "string" && inputPath) candidates.add(path.resolve(path.dirname(inputPath), externalPath));
|
|
2559
|
+
for (const resolver of this.resolvers) try {
|
|
2560
|
+
const resolverPaths = typeof resolver.paths === "function" ? resolver.paths() : [];
|
|
2561
|
+
for (const resolverPath of resolverPaths) {
|
|
2562
|
+
if (typeof resolverPath !== "string") continue;
|
|
2563
|
+
if (/^https?:\/\//i.test(resolverPath)) continue;
|
|
2564
|
+
candidates.add(path.resolve(path.dirname(resolverPath), externalPath));
|
|
2565
|
+
}
|
|
2566
|
+
} catch (e) {
|
|
2567
|
+
consola.debug(e);
|
|
2568
|
+
}
|
|
2569
|
+
return [...candidates];
|
|
2570
|
+
}
|
|
2571
|
+
tryToResolveRefFromFile(ref) {
|
|
2572
|
+
if (!ref || ref.startsWith("#")) return null;
|
|
2573
|
+
const [externalPath = "", rawPointer = ""] = ref.split("#");
|
|
2574
|
+
if (!externalPath) return null;
|
|
2575
|
+
const pointer = rawPointer ? rawPointer.startsWith("/") ? rawPointer : `/${rawPointer}` : "/";
|
|
2576
|
+
const candidates = this.collectExternalRefCandidates(externalPath);
|
|
2577
|
+
for (const candidate of candidates) {
|
|
2578
|
+
const schema = this.readExternalSchema(candidate);
|
|
2579
|
+
const resolved = this.resolveJsonPointer(schema, pointer);
|
|
2580
|
+
if (resolved != null) return this.absolutizeLocalRefs(resolved, externalPath);
|
|
2581
|
+
}
|
|
2582
|
+
return null;
|
|
2583
|
+
}
|
|
2584
|
+
static async create(config, usageSchema, originalSchema) {
|
|
2585
|
+
const resolvers = [];
|
|
2586
|
+
const options = {
|
|
2587
|
+
continueOnError: true,
|
|
2588
|
+
mutateInputSchema: true,
|
|
2589
|
+
dereference: {},
|
|
2590
|
+
validate: {
|
|
2591
|
+
schema: false,
|
|
2592
|
+
spec: false
|
|
2593
|
+
},
|
|
2594
|
+
resolve: {
|
|
2595
|
+
external: true,
|
|
2596
|
+
http: {
|
|
2597
|
+
...config.requestOptions,
|
|
2598
|
+
headers: Object.assign({}, config.authorizationToken ? { Authorization: config.authorizationToken } : {}, config.requestOptions?.headers ?? {})
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
};
|
|
2602
|
+
try {
|
|
2603
|
+
resolvers.push(await SwaggerParser.resolve(originalSchema, options));
|
|
2604
|
+
} catch (e) {
|
|
2605
|
+
consola.debug(e);
|
|
2606
|
+
}
|
|
2607
|
+
try {
|
|
2608
|
+
resolvers.push(await SwaggerParser.resolve(usageSchema, options));
|
|
2609
|
+
} catch (e) {
|
|
2610
|
+
consola.debug(e);
|
|
2611
|
+
}
|
|
2612
|
+
try {
|
|
2613
|
+
resolvers.push(await SwaggerParser.resolve(config.url || config.input || config.spec, options));
|
|
2614
|
+
} catch (e) {
|
|
2615
|
+
consola.debug(e);
|
|
2616
|
+
}
|
|
2617
|
+
const resolvedSwaggerSchema = new ResolvedSwaggerSchema(config, usageSchema, originalSchema, resolvers);
|
|
2618
|
+
await resolvedSwaggerSchema.warmUpRemoteSchemasCache();
|
|
2619
|
+
return resolvedSwaggerSchema;
|
|
2219
2620
|
}
|
|
2220
|
-
addSchema = (name, schema) => {
|
|
2221
|
-
this.schemas.set(name, structuredClone(schema));
|
|
2222
|
-
};
|
|
2223
|
-
_isLocalRef = (ref) => {
|
|
2224
|
-
return ref.startsWith("#");
|
|
2225
|
-
};
|
|
2226
|
-
_isRemoteRef = (ref) => {
|
|
2227
|
-
return ref.startsWith("http://") || ref.startsWith("https://");
|
|
2228
|
-
};
|
|
2229
|
-
_getRefDataFromSchema = (schema, ref) => {
|
|
2230
|
-
const refData = get(schema, ref.replace("#", "").split("/"));
|
|
2231
|
-
if (refData) this.caches.set(ref, refData);
|
|
2232
|
-
return refData;
|
|
2233
|
-
};
|
|
2234
2621
|
};
|
|
2235
2622
|
|
|
2236
2623
|
//#endregion
|
|
@@ -2248,7 +2635,7 @@ var Request = class {
|
|
|
2248
2635
|
return await (await fetch(url, requestOptions)).text();
|
|
2249
2636
|
} catch (error) {
|
|
2250
2637
|
const message = `error while fetching data from URL "${url}"`;
|
|
2251
|
-
consola.error(message, error);
|
|
2638
|
+
consola$1.error(message, error);
|
|
2252
2639
|
return message;
|
|
2253
2640
|
}
|
|
2254
2641
|
}
|
|
@@ -2267,10 +2654,15 @@ var SwaggerSchemaResolver = class {
|
|
|
2267
2654
|
}
|
|
2268
2655
|
async create() {
|
|
2269
2656
|
const { spec, patch, input, url, authorizationToken } = this.config;
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2657
|
+
let swaggerSchemas;
|
|
2658
|
+
if (spec) swaggerSchemas = await this.convertSwaggerObject(spec, { patch });
|
|
2659
|
+
else {
|
|
2660
|
+
const swaggerSchemaFile = await this.fetchSwaggerSchemaFile(input, url, authorizationToken);
|
|
2661
|
+
const swaggerSchemaObject = this.processSwaggerSchemaFile(swaggerSchemaFile);
|
|
2662
|
+
swaggerSchemas = await this.convertSwaggerObject(swaggerSchemaObject, { patch });
|
|
2663
|
+
}
|
|
2664
|
+
this.fixSwaggerSchemas(swaggerSchemas);
|
|
2665
|
+
return ResolvedSwaggerSchema.create(this.config, swaggerSchemas.usageSchema, swaggerSchemas.originalSchema);
|
|
2274
2666
|
}
|
|
2275
2667
|
convertSwaggerObject(swaggerSchema, converterOptions) {
|
|
2276
2668
|
return new Promise((resolve) => {
|
|
@@ -2303,12 +2695,12 @@ var SwaggerSchemaResolver = class {
|
|
|
2303
2695
|
});
|
|
2304
2696
|
}
|
|
2305
2697
|
getSwaggerSchemaByPath = (pathToSwagger) => {
|
|
2306
|
-
consola.info(`try to get swagger by path "${pathToSwagger}"`);
|
|
2698
|
+
consola$1.info(`try to get swagger by path "${pathToSwagger}"`);
|
|
2307
2699
|
return this.fileSystem.getFileContent(pathToSwagger);
|
|
2308
2700
|
};
|
|
2309
2701
|
async fetchSwaggerSchemaFile(pathToSwagger, urlToSwagger, authToken) {
|
|
2310
2702
|
if (this.fileSystem.pathIsExist(pathToSwagger)) return this.getSwaggerSchemaByPath(pathToSwagger);
|
|
2311
|
-
consola.info(`try to get swagger by URL "${urlToSwagger}"`);
|
|
2703
|
+
consola$1.info(`try to get swagger by URL "${urlToSwagger}"`);
|
|
2312
2704
|
return await this.request.download({
|
|
2313
2705
|
url: urlToSwagger,
|
|
2314
2706
|
authToken
|
|
@@ -2322,7 +2714,26 @@ var SwaggerSchemaResolver = class {
|
|
|
2322
2714
|
return YAML.parse(file);
|
|
2323
2715
|
}
|
|
2324
2716
|
}
|
|
2325
|
-
|
|
2717
|
+
normalizeRefValue(ref) {
|
|
2718
|
+
const refWithoutSlashBeforeHash = ref.split("/#/").join("#/");
|
|
2719
|
+
const hashIndex = refWithoutSlashBeforeHash.indexOf("#");
|
|
2720
|
+
if (hashIndex === -1) return refWithoutSlashBeforeHash;
|
|
2721
|
+
if (refWithoutSlashBeforeHash[hashIndex + 1] === "/") return refWithoutSlashBeforeHash;
|
|
2722
|
+
return `${refWithoutSlashBeforeHash.slice(0, hashIndex + 1)}/${refWithoutSlashBeforeHash.slice(hashIndex + 1)}`;
|
|
2723
|
+
}
|
|
2724
|
+
normalizeRefsInSchema(schema) {
|
|
2725
|
+
if (!schema || typeof schema !== "object") return;
|
|
2726
|
+
if (Array.isArray(schema)) {
|
|
2727
|
+
for (const value of schema) this.normalizeRefsInSchema(value);
|
|
2728
|
+
return;
|
|
2729
|
+
}
|
|
2730
|
+
const objectSchema = schema;
|
|
2731
|
+
if (typeof objectSchema.$ref === "string") objectSchema.$ref = this.normalizeRefValue(objectSchema.$ref);
|
|
2732
|
+
for (const value of Object.values(objectSchema)) this.normalizeRefsInSchema(value);
|
|
2733
|
+
}
|
|
2734
|
+
fixSwaggerSchemas({ usageSchema, originalSchema }) {
|
|
2735
|
+
this.normalizeRefsInSchema(usageSchema);
|
|
2736
|
+
this.normalizeRefsInSchema(originalSchema);
|
|
2326
2737
|
const usagePaths = get(usageSchema, "paths") || {};
|
|
2327
2738
|
const originalPaths = get(originalSchema, "paths") || {};
|
|
2328
2739
|
for (const [route, usagePathObject] of Object.entries(usagePaths)) {
|
|
@@ -2331,9 +2742,10 @@ var SwaggerSchemaResolver = class {
|
|
|
2331
2742
|
const originalRouteInfo = get(originalPathObject, methodName) || {};
|
|
2332
2743
|
const usageRouteParams = get(usageRouteInfo, "parameters") || [];
|
|
2333
2744
|
const originalRouteParams = get(originalRouteInfo, "parameters") || [];
|
|
2745
|
+
const usageAsOpenapiv2 = usageRouteInfo;
|
|
2334
2746
|
if (typeof usageRouteInfo === "object") {
|
|
2335
|
-
|
|
2336
|
-
|
|
2747
|
+
usageAsOpenapiv2.consumes = uniq(compact([...usageAsOpenapiv2.consumes || [], ...originalRouteInfo.consumes || []]));
|
|
2748
|
+
usageAsOpenapiv2.produces = uniq(compact([...usageAsOpenapiv2.produces || [], ...originalRouteInfo.produces || []]));
|
|
2337
2749
|
}
|
|
2338
2750
|
for (const originalRouteParam of originalRouteParams) if (!usageRouteParams.find((param) => originalRouteParam.in === param.in && originalRouteParam.name === param.name)) usageRouteParams.push(originalRouteParam);
|
|
2339
2751
|
}
|
|
@@ -2353,8 +2765,8 @@ var TemplatesWorker = class {
|
|
|
2353
2765
|
this.config = config;
|
|
2354
2766
|
this.fileSystem = fileSystem;
|
|
2355
2767
|
this.getRenderTemplateData = getRenderTemplateData;
|
|
2356
|
-
if (this.config.debug) consola.level = Number.MAX_SAFE_INTEGER;
|
|
2357
|
-
if (this.config.silent) consola.level = 0;
|
|
2768
|
+
if (this.config.debug) consola$1.level = Number.MAX_SAFE_INTEGER;
|
|
2769
|
+
if (this.config.silent) consola$1.level = 0;
|
|
2358
2770
|
}
|
|
2359
2771
|
getTemplatePaths = (config) => {
|
|
2360
2772
|
const __dirname = path$1.dirname(url$1.fileURLToPath(import.meta.url));
|
|
@@ -2385,19 +2797,19 @@ var TemplatesWorker = class {
|
|
|
2385
2797
|
const customFullPath = templatePaths.custom && this.getTemplateFullPath(templatePaths.custom, fileName);
|
|
2386
2798
|
let fileContent = customFullPath && this.fileSystem.getFileContent(customFullPath);
|
|
2387
2799
|
if (fileContent) {
|
|
2388
|
-
consola.info(`"${name.toLowerCase()}" template found in "${templatePaths.custom}"`);
|
|
2800
|
+
consola$1.info(`"${name.toLowerCase()}" template found in "${templatePaths.custom}"`);
|
|
2389
2801
|
return fileContent;
|
|
2390
2802
|
}
|
|
2391
2803
|
const baseFullPath = this.getTemplateFullPath(templatePaths.base, fileName);
|
|
2392
2804
|
if (baseFullPath) fileContent = this.fileSystem.getFileContent(baseFullPath);
|
|
2393
|
-
else if (templatePaths.custom) consola.warn("Code generator will use the default template:", `"${name.toLowerCase()}"`, "template not found in", `"${templatePaths.custom}"`);
|
|
2394
|
-
else consola.info(`Code generator will use the default template for "${name.toLowerCase()}"`);
|
|
2805
|
+
else if (templatePaths.custom) consola$1.warn("Code generator will use the default template:", `"${name.toLowerCase()}"`, "template not found in", `"${templatePaths.custom}"`);
|
|
2806
|
+
else consola$1.info(`Code generator will use the default template for "${name.toLowerCase()}"`);
|
|
2395
2807
|
const originalFullPath = this.getTemplateFullPath(templatePaths.original, fileName);
|
|
2396
2808
|
if (originalFullPath) fileContent = this.fileSystem.getFileContent(originalFullPath);
|
|
2397
2809
|
return fileContent;
|
|
2398
2810
|
};
|
|
2399
2811
|
getTemplates = ({ templatePaths }) => {
|
|
2400
|
-
if (templatePaths.custom) consola.info(`try to read templates from directory "${templatePaths.custom}"`);
|
|
2812
|
+
if (templatePaths.custom) consola$1.info(`try to read templates from directory "${templatePaths.custom}"`);
|
|
2401
2813
|
return this.config.templateInfos.reduce((acc, { name, fileName }) => ({
|
|
2402
2814
|
...acc,
|
|
2403
2815
|
[name]: this.getTemplate(name, fileName)
|
|
@@ -2498,7 +2910,7 @@ var TypeNameFormatter = class {
|
|
|
2498
2910
|
const typeSuffix = schemaType === "enum-key" ? this.config.enumKeySuffix : this.config.typeSuffix;
|
|
2499
2911
|
const hashKey = `${typePrefix}_${name}_${typeSuffix}`;
|
|
2500
2912
|
if (typeof name !== "string") {
|
|
2501
|
-
consola.warn("wrong model name", name);
|
|
2913
|
+
consola$1.warn("wrong model name", name);
|
|
2502
2914
|
return name;
|
|
2503
2915
|
}
|
|
2504
2916
|
if (/^(?!\d)([A-Z0-9_]{1,})$/g.test(name)) return compact([
|
|
@@ -2508,7 +2920,7 @@ var TypeNameFormatter = class {
|
|
|
2508
2920
|
]).join("_");
|
|
2509
2921
|
if (this.formattedModelNamesMap.has(hashKey)) return this.formattedModelNamesMap.get(hashKey);
|
|
2510
2922
|
const formattedName = startCase(`${typePrefix}_${this.fixModelName(name, { type: schemaType })}_${typeSuffix}`).replace(/\s/g, "");
|
|
2511
|
-
const formattedResultName = this.config.hooks.onFormatTypeName(formattedName, name, schemaType) || formattedName;
|
|
2923
|
+
const formattedResultName = this.config.hooks.onFormatTypeName?.(formattedName, name, schemaType) || formattedName;
|
|
2512
2924
|
this.formattedModelNamesMap.set(hashKey, formattedResultName);
|
|
2513
2925
|
return formattedResultName;
|
|
2514
2926
|
};
|
|
@@ -2550,14 +2962,14 @@ var FileSystem = class {
|
|
|
2550
2962
|
if (typeof fs.rmSync === "function") fs.rmSync(path, { recursive: true });
|
|
2551
2963
|
else fs.rmdirSync(path, { recursive: true });
|
|
2552
2964
|
} catch (e) {
|
|
2553
|
-
consola.debug("failed to remove dir", e);
|
|
2965
|
+
consola$1.debug("failed to remove dir", e);
|
|
2554
2966
|
}
|
|
2555
2967
|
};
|
|
2556
2968
|
createDir = (path) => {
|
|
2557
2969
|
try {
|
|
2558
2970
|
fs.mkdirSync(path, { recursive: true });
|
|
2559
2971
|
} catch (e) {
|
|
2560
|
-
consola.debug("failed to create dir", e);
|
|
2972
|
+
consola$1.debug("failed to create dir", e);
|
|
2561
2973
|
}
|
|
2562
2974
|
};
|
|
2563
2975
|
cleanDir = (path) => {
|
|
@@ -2607,38 +3019,35 @@ var CodeGenProcess = class {
|
|
|
2607
3019
|
fileSystem;
|
|
2608
3020
|
codeFormatter;
|
|
2609
3021
|
templatesWorker;
|
|
2610
|
-
schemaWalker;
|
|
2611
3022
|
javascriptTranslator;
|
|
3023
|
+
swaggerRefs;
|
|
2612
3024
|
constructor(config) {
|
|
2613
3025
|
this.config = new CodeGenConfig(config);
|
|
2614
3026
|
this.fileSystem = new FileSystem();
|
|
2615
3027
|
this.swaggerSchemaResolver = new SwaggerSchemaResolver(this.config, this.fileSystem);
|
|
2616
|
-
this.schemaWalker = new SchemaWalker(this.config, this.swaggerSchemaResolver);
|
|
2617
3028
|
this.schemaComponentsMap = new SchemaComponentsMap(this.config);
|
|
2618
3029
|
this.typeNameFormatter = new TypeNameFormatter(this.config);
|
|
2619
3030
|
this.templatesWorker = new TemplatesWorker(this.config, this.fileSystem, this.getRenderTemplateData);
|
|
2620
3031
|
this.codeFormatter = new CodeFormatter(this.config);
|
|
2621
|
-
this.schemaParserFabric = new SchemaParserFabric(this.config, this.templatesWorker, this.schemaComponentsMap, this.typeNameFormatter
|
|
3032
|
+
this.schemaParserFabric = new SchemaParserFabric(this.config, this.templatesWorker, this.schemaComponentsMap, this.typeNameFormatter);
|
|
2622
3033
|
this.schemaRoutes = new SchemaRoutes(this.config, this.schemaParserFabric, this.schemaComponentsMap, this.templatesWorker, this.typeNameFormatter);
|
|
2623
3034
|
this.javascriptTranslator = new JavascriptTranslator(this.config, this.codeFormatter);
|
|
2624
3035
|
}
|
|
2625
3036
|
async start() {
|
|
2626
3037
|
this.config.update({ templatePaths: this.templatesWorker.getTemplatePaths(this.config) });
|
|
2627
3038
|
this.config.update({ templatesToRender: this.templatesWorker.getTemplates(this.config) });
|
|
2628
|
-
const
|
|
2629
|
-
this.swaggerSchemaResolver.fixSwaggerSchema(swagger);
|
|
3039
|
+
const resolvedSwaggerSchema = await this.swaggerSchemaResolver.create();
|
|
2630
3040
|
this.config.update({
|
|
2631
|
-
|
|
2632
|
-
|
|
3041
|
+
resolvedSwaggerSchema,
|
|
3042
|
+
swaggerSchema: resolvedSwaggerSchema.usageSchema,
|
|
3043
|
+
originalSchema: resolvedSwaggerSchema.originalSchema
|
|
2633
3044
|
});
|
|
2634
|
-
|
|
2635
|
-
this.
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
if (this.config.swaggerSchema) swagger.usageSchema = this.config.swaggerSchema;
|
|
2639
|
-
if (this.config.originalSchema) swagger.originalSchema = this.config.originalSchema;
|
|
3045
|
+
consola$1.info("start generating your typescript api");
|
|
3046
|
+
this.config.update(this.config.hooks.onInit?.(this.config, this) || this.config);
|
|
3047
|
+
if (this.config.swaggerSchema) resolvedSwaggerSchema.usageSchema = this.config.swaggerSchema;
|
|
3048
|
+
if (this.config.originalSchema) resolvedSwaggerSchema.originalSchema = this.config.originalSchema;
|
|
2640
3049
|
this.schemaComponentsMap.clear();
|
|
2641
|
-
for (const [componentName, component] of Object.entries(
|
|
3050
|
+
for (const [componentName, component] of Object.entries(resolvedSwaggerSchema.usageSchema.components || {})) for (const [typeName, rawTypeData] of Object.entries(component)) this.schemaComponentsMap.createComponent(this.schemaComponentsMap.createRef([
|
|
2642
3051
|
"components",
|
|
2643
3052
|
componentName,
|
|
2644
3053
|
typeName
|
|
@@ -2650,12 +3059,9 @@ var CodeGenProcess = class {
|
|
|
2650
3059
|
schemaComponent.typeData = parsed;
|
|
2651
3060
|
return parsed;
|
|
2652
3061
|
});
|
|
2653
|
-
this.schemaRoutes.attachSchema(
|
|
2654
|
-
usageSchema: swagger.usageSchema,
|
|
2655
|
-
parsedSchemas
|
|
2656
|
-
});
|
|
3062
|
+
this.schemaRoutes.attachSchema(resolvedSwaggerSchema, parsedSchemas);
|
|
2657
3063
|
const rawConfiguration = {
|
|
2658
|
-
apiConfig: this.createApiConfig(
|
|
3064
|
+
apiConfig: this.createApiConfig(resolvedSwaggerSchema.usageSchema),
|
|
2659
3065
|
config: this.config,
|
|
2660
3066
|
modelTypes: this.collectModelTypes(),
|
|
2661
3067
|
hasSecurityRoutes: this.schemaRoutes.hasSecurityRoutes,
|
|
@@ -2669,14 +3075,14 @@ var CodeGenProcess = class {
|
|
|
2669
3075
|
customTranslator: this.config.customTranslator ? new this.config.customTranslator() : null,
|
|
2670
3076
|
utils: this.getRenderTemplateData().utils
|
|
2671
3077
|
};
|
|
2672
|
-
const configuration = this.config.hooks.onPrepareConfig(rawConfiguration) || rawConfiguration;
|
|
3078
|
+
const configuration = this.config.hooks.onPrepareConfig?.(rawConfiguration) || rawConfiguration;
|
|
2673
3079
|
if (this.fileSystem.pathIsExist(this.config.output)) {
|
|
2674
3080
|
if (this.config.cleanOutput) {
|
|
2675
|
-
consola.debug("cleaning dir", this.config.output);
|
|
3081
|
+
consola$1.debug("cleaning dir", this.config.output);
|
|
2676
3082
|
this.fileSystem.cleanDir(this.config.output);
|
|
2677
3083
|
}
|
|
2678
3084
|
} else {
|
|
2679
|
-
consola.debug(`path ${this.config.output} is not exist. creating dir by this path`);
|
|
3085
|
+
consola$1.debug(`path ${this.config.output} is not exist. creating dir by this path`);
|
|
2680
3086
|
this.fileSystem.createDir(this.config.output);
|
|
2681
3087
|
}
|
|
2682
3088
|
const files = await this.generateOutputFiles({ configuration });
|
|
@@ -2687,7 +3093,7 @@ var CodeGenProcess = class {
|
|
|
2687
3093
|
content: file.fileContent,
|
|
2688
3094
|
withPrefix: true
|
|
2689
3095
|
});
|
|
2690
|
-
consola.success("api file", `"${file.fileName}${file.fileExtension}"`, `created in ${this.config.output}`);
|
|
3096
|
+
consola$1.success("api file", `"${file.fileName}${file.fileExtension}"`, `created in ${this.config.output}`);
|
|
2691
3097
|
}
|
|
2692
3098
|
return {
|
|
2693
3099
|
files,
|
|
@@ -2703,6 +3109,7 @@ var CodeGenProcess = class {
|
|
|
2703
3109
|
utils: {
|
|
2704
3110
|
Ts: this.config.Ts,
|
|
2705
3111
|
formatDescription: this.schemaParserFabric.schemaFormatters.formatDescription,
|
|
3112
|
+
escapeJSDocContent: this.schemaParserFabric.schemaFormatters.escapeJSDocContent,
|
|
2706
3113
|
internalCase: camelCase,
|
|
2707
3114
|
classNameCase: pascalCase,
|
|
2708
3115
|
pascalCase,
|
|
@@ -2831,7 +3238,7 @@ var CodeGenProcess = class {
|
|
|
2831
3238
|
const fileName = this.fileSystem.cropExtension(fileNameFull);
|
|
2832
3239
|
const fileExtension = typescript.Extension.Ts;
|
|
2833
3240
|
if (configuration.translateToJavaScript) {
|
|
2834
|
-
consola.debug("using js translator for", fileName);
|
|
3241
|
+
consola$1.debug("using js translator for", fileName);
|
|
2835
3242
|
return await this.javascriptTranslator.translate({
|
|
2836
3243
|
fileName,
|
|
2837
3244
|
fileExtension,
|
|
@@ -2839,14 +3246,14 @@ var CodeGenProcess = class {
|
|
|
2839
3246
|
});
|
|
2840
3247
|
}
|
|
2841
3248
|
if (configuration.customTranslator) {
|
|
2842
|
-
consola.debug("using custom translator for", fileName);
|
|
3249
|
+
consola$1.debug("using custom translator for", fileName);
|
|
2843
3250
|
return await configuration.customTranslator.translate({
|
|
2844
3251
|
fileName,
|
|
2845
3252
|
fileExtension,
|
|
2846
3253
|
fileContent: content
|
|
2847
3254
|
});
|
|
2848
3255
|
}
|
|
2849
|
-
consola.debug("generating output for", `${fileName}${fileExtension}`);
|
|
3256
|
+
consola$1.debug("generating output for", `${fileName}${fileExtension}`);
|
|
2850
3257
|
return [{
|
|
2851
3258
|
fileName,
|
|
2852
3259
|
fileExtension,
|
|
@@ -2920,7 +3327,7 @@ var TemplatesGenConfig = class {
|
|
|
2920
3327
|
this.update(config);
|
|
2921
3328
|
}
|
|
2922
3329
|
update = (update) => {
|
|
2923
|
-
|
|
3330
|
+
objectAssign(this, update);
|
|
2924
3331
|
};
|
|
2925
3332
|
};
|
|
2926
3333
|
|
|
@@ -2947,10 +3354,10 @@ var TemplatesGenProcess = class {
|
|
|
2947
3354
|
this.fileSystem = new FileSystem();
|
|
2948
3355
|
}
|
|
2949
3356
|
async start() {
|
|
2950
|
-
consola.info("start generating source templates \".ejs\" for code generator");
|
|
3357
|
+
consola$1.info("start generating source templates \".ejs\" for code generator");
|
|
2951
3358
|
const templates = this.getTemplates();
|
|
2952
3359
|
if (this.config.output) {
|
|
2953
|
-
consola.info("preparing output directory for source templates");
|
|
3360
|
+
consola$1.info("preparing output directory for source templates");
|
|
2954
3361
|
const outputPath = path.resolve(process.cwd(), this.config.output);
|
|
2955
3362
|
if (this.fileSystem.pathIsExist(outputPath)) {
|
|
2956
3363
|
if (this.config.cleanOutput) this.fileSystem.cleanDir(outputPath);
|
|
@@ -2982,7 +3389,7 @@ var TemplatesGenProcess = class {
|
|
|
2982
3389
|
});
|
|
2983
3390
|
}
|
|
2984
3391
|
}
|
|
2985
|
-
consola.success(`source templates has been successfully created in "${outputPath}"`);
|
|
3392
|
+
consola$1.success(`source templates has been successfully created in "${outputPath}"`);
|
|
2986
3393
|
}
|
|
2987
3394
|
return {
|
|
2988
3395
|
files: templates,
|
|
@@ -3029,11 +3436,11 @@ var TemplatesGenProcess = class {
|
|
|
3029
3436
|
//#endregion
|
|
3030
3437
|
//#region src/commands/generate-templates/index.ts
|
|
3031
3438
|
async function generateTemplates(config) {
|
|
3032
|
-
if (config.debug) consola.level = Number.MAX_SAFE_INTEGER;
|
|
3033
|
-
if (config.silent) consola.level = 0;
|
|
3439
|
+
if (config.debug) consola$1.level = Number.MAX_SAFE_INTEGER;
|
|
3440
|
+
if (config.silent) consola$1.level = 0;
|
|
3034
3441
|
return await new TemplatesGenProcess(config).start();
|
|
3035
3442
|
}
|
|
3036
3443
|
|
|
3037
3444
|
//#endregion
|
|
3038
3445
|
export { CodeGenProcess as a, constants_exports as c, version as d, SCHEMA_TYPES as i, description as l, TemplatesGenConfig as n, CodeGenConfig as o, RequestContentKind as r, HTTP_CLIENT as s, generateTemplates as t, name as u };
|
|
3039
|
-
//# sourceMappingURL=generate-templates-
|
|
3446
|
+
//# sourceMappingURL=generate-templates-BaT2BiRR.mjs.map
|