swagger-typescript-api 13.1.0 → 13.1.2

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.
@@ -0,0 +1,3133 @@
1
+ "use strict";
2
+ //#region rolldown:runtime
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name$1 in all) __defProp(target, name$1, {
11
+ get: all[name$1],
12
+ enumerable: true
13
+ });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
17
+ key = keys[i];
18
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
19
+ get: ((k) => from[k]).bind(null, key),
20
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
21
+ });
22
+ }
23
+ return to;
24
+ };
25
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
26
+ value: mod,
27
+ enumerable: true
28
+ }) : target, mod));
29
+
30
+ //#endregion
31
+ const consola = __toESM(require("consola"));
32
+ const lodash = __toESM(require("lodash"));
33
+ const typescript = __toESM(require("typescript"));
34
+ const node_path = __toESM(require("node:path"));
35
+ const __biomejs_js_api = __toESM(require("@biomejs/js-api"));
36
+ const nanoid = __toESM(require("nanoid"));
37
+ const js_yaml = __toESM(require("js-yaml"));
38
+ const swagger2openapi = __toESM(require("swagger2openapi"));
39
+ const node_url = __toESM(require("node:url"));
40
+ const eta = __toESM(require("eta"));
41
+ const node_fs = __toESM(require("node:fs"));
42
+
43
+ //#region src/code-formatter.ts
44
+ var CodeFormatter = class {
45
+ constructor(config) {
46
+ this.removeUnusedImports = (content) => {
47
+ const tempFileName = "file.ts";
48
+ const host = new TsLanguageServiceHost(tempFileName, content);
49
+ const languageService = typescript.createLanguageService(host);
50
+ const fileTextChanges = languageService.organizeImports({
51
+ type: "file",
52
+ fileName: tempFileName
53
+ }, { newLineCharacter: typescript.sys.newLine }, void 0)[0];
54
+ if (fileTextChanges?.textChanges.length) return fileTextChanges.textChanges.reduceRight((content$1, { span, newText }) => `${content$1.slice(0, span.start)}${newText}${content$1.slice(span.start + span.length)}`, content);
55
+ return content;
56
+ };
57
+ this.format = async (content) => {
58
+ const biome = await __biomejs_js_api.Biome.create({ distribution: __biomejs_js_api.Distribution.NODE });
59
+ biome.applyConfiguration({
60
+ files: { maxSize: Number.MAX_SAFE_INTEGER },
61
+ formatter: { indentStyle: "space" }
62
+ });
63
+ const formatted = biome.formatContent(content, { filePath: node_path.format({
64
+ name: nanoid.nanoid(),
65
+ ext: "ts"
66
+ }) });
67
+ return formatted.content;
68
+ };
69
+ this.formatCode = async (code, { removeUnusedImports = true, format = true } = {}) => {
70
+ if (removeUnusedImports) code = this.removeUnusedImports(code);
71
+ if (format) code = await this.format(code);
72
+ return code;
73
+ };
74
+ this.config = config;
75
+ }
76
+ };
77
+ var TsLanguageServiceHost = class {
78
+ constructor(fileName, content) {
79
+ this.fileName = fileName;
80
+ this.content = content;
81
+ const tsconfig = typescript.findConfigFile(fileName, typescript.sys.fileExists);
82
+ this.compilerOptions = tsconfig ? typescript.convertCompilerOptionsFromJson(typescript.readConfigFile(tsconfig, typescript.sys.readFile).config.compilerOptions, "").options : typescript.getDefaultCompilerOptions();
83
+ }
84
+ getNewLine() {
85
+ return "newLine" in typescript.sys ? typescript.sys.newLine : "\n";
86
+ }
87
+ getScriptFileNames() {
88
+ return [this.fileName];
89
+ }
90
+ getCompilationSettings() {
91
+ return this.compilerOptions;
92
+ }
93
+ getDefaultLibFileName() {
94
+ return typescript.getDefaultLibFileName(this.getCompilationSettings());
95
+ }
96
+ getCurrentDirectory() {
97
+ return process.cwd();
98
+ }
99
+ getScriptVersion() {
100
+ return typescript.version;
101
+ }
102
+ getScriptSnapshot() {
103
+ return typescript.ScriptSnapshot.fromString(this.content);
104
+ }
105
+ readFile(fileName, encoding) {
106
+ if (fileName === this.fileName) return this.content;
107
+ return typescript.sys.readFile(fileName, encoding);
108
+ }
109
+ fileExists(path$1) {
110
+ return typescript.sys.fileExists(path$1);
111
+ }
112
+ };
113
+
114
+ //#endregion
115
+ //#region src/util/name-resolver.ts
116
+ var NameResolver = class {
117
+ constructor(config, reservedNames, getFallbackName) {
118
+ this.reservedNames = [];
119
+ this.config = config;
120
+ this.getFallbackName = getFallbackName;
121
+ this.reserve(reservedNames);
122
+ }
123
+ reserve(names) {
124
+ const fixedNames = lodash.default.uniq(lodash.default.compact(names));
125
+ for (const name$1 of fixedNames) if (this.reservedNames.indexOf(name$1) === -1) this.reservedNames.push(name$1);
126
+ }
127
+ unreserve(names) {
128
+ this.reservedNames.filter((reservedName) => !names.some((name$1) => name$1 === reservedName));
129
+ }
130
+ isReserved(name$1) {
131
+ return this.reservedNames.some((reservedName) => reservedName === name$1);
132
+ }
133
+ resolve(variants, resolver, extras, shouldReserve = true) {
134
+ if (typeof resolver === "function") {
135
+ let usageName = null;
136
+ while (usageName === null) {
137
+ const variant = resolver(variants, extras);
138
+ if (variant === void 0) {
139
+ consola.consola.warn("unable to resolve name. current reserved names: ", ...this.reservedNames);
140
+ return null;
141
+ }
142
+ if (!shouldReserve || !this.isReserved(variant)) usageName = variant;
143
+ }
144
+ shouldReserve && this.reserve([usageName]);
145
+ return usageName;
146
+ }
147
+ if (Array.isArray(variants)) {
148
+ let usageName = null;
149
+ const uniqVariants = lodash.default.uniq(lodash.default.compact(variants));
150
+ for (const variant of uniqVariants) if (!usageName && (!shouldReserve || !this.isReserved(variant))) usageName = variant;
151
+ if (usageName) {
152
+ shouldReserve && this.reserve([usageName]);
153
+ return usageName;
154
+ }
155
+ consola.consola.debug("trying to resolve name with using fallback name generator using variants", ...variants);
156
+ return this.resolve(variants, this.getFallbackName, extras);
157
+ }
158
+ consola.consola.debug("problem with reserving names. current reserved names: ", ...this.reservedNames);
159
+ return null;
160
+ }
161
+ };
162
+
163
+ //#endregion
164
+ //#region src/util/random.ts
165
+ const getRandomFloat = (min = 0, max = 1) => {
166
+ return Math.random() * (max - min) + min;
167
+ };
168
+ const getRandomInt = (min = 0, max = 1) => {
169
+ if (min === max) return min;
170
+ return Math.round(getRandomFloat(min, max));
171
+ };
172
+
173
+ //#endregion
174
+ //#region src/component-type-name-resolver.ts
175
+ var ComponentTypeNameResolver = class extends NameResolver {
176
+ constructor(config, reservedNames) {
177
+ super(config, reservedNames, (variants) => {
178
+ const randomVariant = variants[getRandomInt(0, variants.length - 1)];
179
+ if (randomVariant) {
180
+ if (!this.countersByVariant.has(randomVariant)) this.countersByVariant.set(randomVariant, 0);
181
+ const variantCounter = this.countersByVariant.get(randomVariant) + 1;
182
+ this.countersByVariant.set(randomVariant, variantCounter);
183
+ const dirtyResolvedName = `${randomVariant}${variantCounter}`;
184
+ consola.consola.debug("generated dirty resolved type name for component - ", dirtyResolvedName);
185
+ return dirtyResolvedName;
186
+ }
187
+ const fallbackName = `${this.config.componentTypeNameResolver}${this.fallbackNameCounter++}`;
188
+ consola.consola.debug("generated fallback type name for component - ", fallbackName);
189
+ return fallbackName;
190
+ });
191
+ this.counter = 1;
192
+ this.fallbackNameCounter = 1;
193
+ this.countersByVariant = new Map();
194
+ }
195
+ };
196
+
197
+ //#endregion
198
+ //#region package.json
199
+ var name = "swagger-typescript-api";
200
+ var version = "13.1.2";
201
+ var description = "Generate the API client for Fetch or Axios from an OpenAPI Specification";
202
+ var homepage = "https://github.com/acacode/swagger-typescript-api";
203
+ var bugs = "https://github.com/acacode/swagger-typescript-api/issues";
204
+ var repository = "github:acacode/swagger-typescript-api";
205
+ var license = "MIT";
206
+ var author = "Sergey Volkov <js2me@outlook.com>";
207
+ var maintainers = ["Sora Morimoto <sora@morimoto.io>"];
208
+ var type = "module";
209
+ var exports$1 = { ".": {
210
+ "import": {
211
+ "types": "./dist/lib.d.ts",
212
+ "default": "./dist/lib.js"
213
+ },
214
+ "require": {
215
+ "types": "./dist/lib.d.cts",
216
+ "default": "./dist/lib.cjs"
217
+ }
218
+ } };
219
+ var main = "./dist/lib.cjs";
220
+ var module$1 = "./dist/lib.js";
221
+ var types = "./dist/lib.d.cts";
222
+ var bin = {
223
+ "sta": "./dist/cli.js",
224
+ "swagger-typescript-api": "./dist/cli.js"
225
+ };
226
+ var files = ["dist", "templates"];
227
+ var scripts = {
228
+ "build": "tsdown",
229
+ "cli:help": "node index.js -h",
230
+ "cli:json": "node index.js -r -d -p ./swagger-test-cli.json -n swagger-test-cli.ts",
231
+ "cli:yaml": "node index.js -r -d -p ./swagger-test-cli.yaml -n swagger-test-cli.ts",
232
+ "format": "biome format --write .",
233
+ "format:check": "biome format .",
234
+ "lint": "biome check",
235
+ "prepack": "tsdown",
236
+ "test": "vitest run",
237
+ "typedoc": "typedoc"
238
+ };
239
+ var dependencies = {
240
+ "@biomejs/js-api": "^0.7.1",
241
+ "@biomejs/wasm-nodejs": "^1.9.4",
242
+ "@types/swagger-schema-official": "^2.0.25",
243
+ "c12": "^3.0.3",
244
+ "citty": "^0.1.6",
245
+ "consola": "^3.4.2",
246
+ "eta": "^2.2.0",
247
+ "js-yaml": "^4.1.0",
248
+ "lodash": "^4.17.21",
249
+ "nanoid": "^5.1.5",
250
+ "swagger-schema-official": "2.0.0-bab6bed",
251
+ "swagger2openapi": "^7.0.8",
252
+ "typescript": "~5.8.3"
253
+ };
254
+ var devDependencies = {
255
+ "@biomejs/biome": "2.0.0-beta.2",
256
+ "@changesets/changelog-github": "0.5.1",
257
+ "@changesets/cli": "2.29.2",
258
+ "@tsconfig/node18": "18.2.4",
259
+ "@tsconfig/strictest": "2.0.5",
260
+ "@types/js-yaml": "4.0.9",
261
+ "@types/lodash": "4.17.16",
262
+ "@types/node": "22.15.3",
263
+ "@types/swagger2openapi": "7.0.4",
264
+ "axios": "1.9.0",
265
+ "openapi-types": "12.1.3",
266
+ "tsdown": "0.10.2",
267
+ "typedoc": "0.28.3",
268
+ "vitest": "3.1.2"
269
+ };
270
+ var packageManager = "yarn@4.9.1";
271
+ var engines = { "node": ">=18.0.0" };
272
+ var publishConfig = {
273
+ "access": "public",
274
+ "provenance": true,
275
+ "registry": "https://registry.npmjs.org"
276
+ };
277
+ var typedocOptions = {
278
+ "entryPoints": ["src/index.ts"],
279
+ "skipErrorChecking": true
280
+ };
281
+ var package_default = {
282
+ name,
283
+ version,
284
+ description,
285
+ homepage,
286
+ bugs,
287
+ repository,
288
+ license,
289
+ author,
290
+ maintainers,
291
+ type,
292
+ exports: exports$1,
293
+ main,
294
+ module: module$1,
295
+ types,
296
+ bin,
297
+ files,
298
+ scripts,
299
+ dependencies,
300
+ devDependencies,
301
+ packageManager,
302
+ engines,
303
+ publishConfig,
304
+ typedocOptions
305
+ };
306
+
307
+ //#endregion
308
+ //#region src/constants.ts
309
+ var constants_exports = {};
310
+ __export(constants_exports, {
311
+ DEFAULT_BODY_ARG_NAME: () => DEFAULT_BODY_ARG_NAME,
312
+ FILE_PREFIX: () => FILE_PREFIX$1,
313
+ HTTP_CLIENT: () => HTTP_CLIENT,
314
+ PROJECT_VERSION: () => PROJECT_VERSION,
315
+ RESERVED_BODY_ARG_NAMES: () => RESERVED_BODY_ARG_NAMES,
316
+ RESERVED_HEADER_ARG_NAMES: () => RESERVED_HEADER_ARG_NAMES,
317
+ RESERVED_PATH_ARG_NAMES: () => RESERVED_PATH_ARG_NAMES,
318
+ RESERVED_QUERY_ARG_NAMES: () => RESERVED_QUERY_ARG_NAMES,
319
+ RESERVED_REQ_PARAMS_ARG_NAMES: () => RESERVED_REQ_PARAMS_ARG_NAMES,
320
+ SCHEMA_TYPES: () => SCHEMA_TYPES
321
+ });
322
+ const DEFAULT_BODY_ARG_NAME = "data";
323
+ const FILE_PREFIX$1 = `/* eslint-disable */
324
+ /* tslint:disable */
325
+ // @ts-nocheck
326
+ /*
327
+ * ---------------------------------------------------------------
328
+ * ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ##
329
+ * ## ##
330
+ * ## AUTHOR: acacode ##
331
+ * ## SOURCE: https://github.com/acacode/swagger-typescript-api ##
332
+ * ---------------------------------------------------------------
333
+ */
334
+
335
+ `;
336
+ const HTTP_CLIENT = {
337
+ FETCH: "fetch",
338
+ AXIOS: "axios"
339
+ };
340
+ const PROJECT_VERSION = package_default.version;
341
+ const RESERVED_BODY_ARG_NAMES = [
342
+ "data",
343
+ "body",
344
+ "reqBody"
345
+ ];
346
+ const RESERVED_HEADER_ARG_NAMES = ["headers", "headersParams"];
347
+ const RESERVED_PATH_ARG_NAMES = ["path", "pathParams"];
348
+ const RESERVED_QUERY_ARG_NAMES = [
349
+ "query",
350
+ "queryParams",
351
+ "queryArg"
352
+ ];
353
+ const RESERVED_REQ_PARAMS_ARG_NAMES = [
354
+ "params",
355
+ "requestParams",
356
+ "reqParams",
357
+ "httpParams"
358
+ ];
359
+ const SCHEMA_TYPES = {
360
+ ARRAY: "array",
361
+ OBJECT: "object",
362
+ ENUM: "enum",
363
+ REF: "$ref",
364
+ PRIMITIVE: "primitive",
365
+ COMPLEX: "complex",
366
+ DISCRIMINATOR: "discriminator",
367
+ COMPLEX_ONE_OF: "oneOf",
368
+ COMPLEX_ANY_OF: "anyOf",
369
+ COMPLEX_ALL_OF: "allOf",
370
+ COMPLEX_NOT: "not",
371
+ COMPLEX_UNKNOWN: "__unknown"
372
+ };
373
+
374
+ //#endregion
375
+ //#region src/util/object-assign.ts
376
+ const objectAssign = (target, updater) => {
377
+ if (!updater) return;
378
+ const update = typeof updater === "function" ? updater(target) : updater;
379
+ const undefinedKeys = lodash.default.map(update, (value, key) => value === void 0 && key).filter((key) => typeof key === "string");
380
+ Object.assign(target, lodash.default.merge(target, update));
381
+ for (const key of undefinedKeys) target[key] = void 0;
382
+ };
383
+
384
+ //#endregion
385
+ //#region src/configuration.ts
386
+ const TsKeyword = {
387
+ Number: "number",
388
+ String: "string",
389
+ Boolean: "boolean",
390
+ Any: "any",
391
+ Void: "void",
392
+ Unknown: "unknown",
393
+ Null: "null",
394
+ Undefined: "undefined",
395
+ Object: "object",
396
+ File: "File",
397
+ Date: "Date",
398
+ Type: "type",
399
+ Enum: "enum",
400
+ Interface: "interface",
401
+ Array: "Array",
402
+ Record: "Record",
403
+ Intersection: "&",
404
+ Union: "|"
405
+ };
406
+ const TsCodeGenKeyword = { UtilRequiredKeys: "UtilRequiredKeys" };
407
+ var CodeGenConfig = class {
408
+ constructor({ codeGenConstructs, primitiveTypeConstructs, constants, templateInfos, hooks,...otherConfig }) {
409
+ this.version = PROJECT_VERSION;
410
+ this.templates = "";
411
+ this.generateResponses = false;
412
+ this.defaultResponseAsSuccess = false;
413
+ this.generateRouteTypes = false;
414
+ this.generateClient = true;
415
+ this.generateUnionEnums = false;
416
+ this.addReadonly = false;
417
+ this.enumNamesAsValues = false;
418
+ this.swaggerSchema = null;
419
+ this.originalSchema = null;
420
+ this.componentsMap = {};
421
+ this.convertedFromSwagger2 = false;
422
+ this.moduleNameIndex = 0;
423
+ this.moduleNameFirstTag = false;
424
+ this.extractRequestParams = false;
425
+ this.extractRequestBody = false;
426
+ this.extractResponseBody = false;
427
+ this.extractResponseError = false;
428
+ this.extractResponses = false;
429
+ this.extractEnums = false;
430
+ this.fileNames = {
431
+ dataContracts: "data-contracts",
432
+ routeTypes: "route-types",
433
+ httpClient: "http-client",
434
+ outOfModuleApi: "Common"
435
+ };
436
+ this.routeNameDuplicatesMap = new Map();
437
+ this.hooks = {
438
+ onPreBuildRoutePath: (_routePath) => void 0,
439
+ onBuildRoutePath: (_routeData) => void 0,
440
+ onInsertPathParam: (_pathParam) => void 0,
441
+ onCreateComponent: (schema) => schema,
442
+ onPreParseSchema: (_originalSchema, _typeName, _schemaType) => void 0,
443
+ onParseSchema: (_originalSchema, parsedSchema) => parsedSchema,
444
+ onCreateRoute: (routeData) => routeData,
445
+ onInit: (config, _codeGenProcess) => config,
446
+ onPrepareConfig: (apiConfig) => apiConfig,
447
+ onCreateRequestParams: (_rawType) => {},
448
+ onCreateRouteName: () => {},
449
+ onFormatTypeName: (_typeName, _rawTypeName, _schemaType) => {},
450
+ onFormatRouteName: (_routeInfo, _templateRouteName) => {}
451
+ };
452
+ this.singleHttpClient = false;
453
+ this.httpClientType = HTTP_CLIENT.FETCH;
454
+ this.unwrapResponseData = false;
455
+ this.disableThrowOnError = false;
456
+ this.sortTypes = false;
457
+ this.sortRoutes = false;
458
+ this.templatePaths = {
459
+ base: "",
460
+ default: "",
461
+ modular: "",
462
+ original: "",
463
+ custom: ""
464
+ };
465
+ this.templatesToRender = {
466
+ api: "",
467
+ dataContracts: "",
468
+ dataContractJsDoc: "",
469
+ interfaceDataContract: "",
470
+ typeDataContract: "",
471
+ enumDataContract: "",
472
+ objectFieldJsDoc: "",
473
+ httpClient: "",
474
+ routeTypes: "",
475
+ routeName: ""
476
+ };
477
+ this.schemaParsers = {};
478
+ this.toJS = false;
479
+ this.silent = false;
480
+ this.typePrefix = "";
481
+ this.typeSuffix = "";
482
+ this.enumKeyPrefix = "";
483
+ this.enumKeySuffix = "";
484
+ this.patch = false;
485
+ this.apiClassName = "Api";
486
+ this.debug = false;
487
+ this.anotherArrayType = false;
488
+ this.internalTemplateOptions = { addUtilRequiredKeysType: false };
489
+ this.extraTemplates = [];
490
+ this.input = "";
491
+ this.modular = false;
492
+ this.output = "";
493
+ this.url = "";
494
+ this.cleanOutput = false;
495
+ this.spec = null;
496
+ this.fileName = "Api.ts";
497
+ this.requestOptions = null;
498
+ this.jsPrimitiveTypes = [];
499
+ this.jsEmptyTypes = [];
500
+ this.fixInvalidTypeNamePrefix = "Type";
501
+ this.fixInvalidEnumKeyPrefix = "Value";
502
+ this.enumKeyResolverName = "Value";
503
+ this.typeNameResolverName = "ComponentType";
504
+ this.specificArgNameResolverName = "arg";
505
+ this.successResponseStatusRange = [200, 299];
506
+ this.extractingOptions = {
507
+ requestBodySuffix: [
508
+ "Payload",
509
+ "Body",
510
+ "Input"
511
+ ],
512
+ requestParamsSuffix: ["Params"],
513
+ responseBodySuffix: [
514
+ "Data",
515
+ "Result",
516
+ "Output"
517
+ ],
518
+ responseErrorSuffix: [
519
+ "Error",
520
+ "Fail",
521
+ "Fails",
522
+ "ErrorData",
523
+ "HttpError",
524
+ "BadResponse"
525
+ ],
526
+ enumSuffix: ["Enum"],
527
+ discriminatorMappingSuffix: [
528
+ "Mapping",
529
+ "Mapper",
530
+ "MapType"
531
+ ],
532
+ discriminatorAbstractPrefix: [
533
+ "Base",
534
+ "Abstract",
535
+ "Discriminator",
536
+ "Internal",
537
+ "Polymorph"
538
+ ]
539
+ };
540
+ this.compilerTsConfig = {
541
+ module: typescript.ModuleKind.ESNext,
542
+ noImplicitReturns: true,
543
+ alwaysStrict: true,
544
+ target: typescript.ScriptTarget.ESNext,
545
+ declaration: true,
546
+ noImplicitAny: false,
547
+ sourceMap: false,
548
+ removeComments: false,
549
+ disableSizeLimit: true,
550
+ esModuleInterop: true,
551
+ emitDecoratorMetadata: true,
552
+ skipLibCheck: true
553
+ };
554
+ this.Ts = {
555
+ Keyword: structuredClone(TsKeyword),
556
+ CodeGenKeyword: structuredClone(TsCodeGenKeyword),
557
+ ArrayType: (content) => {
558
+ if (this.anotherArrayType) return this.Ts.TypeWithGeneric(this.Ts.Keyword.Array, [content]);
559
+ return `${this.Ts.ExpressionGroup(content)}[]`;
560
+ },
561
+ StringValue: (content) => `"${content}"`,
562
+ BooleanValue: (content) => `${content}`,
563
+ NumberValue: (content) => `${content}`,
564
+ NullValue: () => "null",
565
+ UnionType: (contents) => lodash.default.join(lodash.default.uniq(contents), ` ${this.Ts.Keyword.Union} `),
566
+ ExpressionGroup: (content) => content ? `(${content})` : "",
567
+ IntersectionType: (contents) => lodash.default.join(lodash.default.uniq(contents), ` ${this.Ts.Keyword.Intersection} `),
568
+ RecordType: (key, value) => this.Ts.TypeWithGeneric(this.Ts.Keyword.Record, [key, value]),
569
+ TypeField: ({ readonly, key, optional, value }) => lodash.default.compact([
570
+ readonly && "readonly ",
571
+ key,
572
+ optional && "?",
573
+ ": ",
574
+ value
575
+ ]).join(""),
576
+ InterfaceDynamicField: (key, value) => `[key: ${key}]: ${value}`,
577
+ EnumUsageKey: (enumStruct, key) => `${enumStruct}.${key}`,
578
+ EnumField: (key, value) => `${key} = ${value}`,
579
+ EnumFieldsWrapper: (contents) => lodash.default.map(contents, ({ key, value }) => ` ${this.Ts.EnumField(key, value)}`).join(",\n"),
580
+ ObjectWrapper: (content) => `{\n${content}\n}`,
581
+ MultilineComment: (contents, formatFn) => [...contents.length === 1 ? [`/** ${contents[0]} */`] : [
582
+ "/**",
583
+ ...contents.map((content) => ` * ${content}`),
584
+ " */"
585
+ ]].map((part) => `${formatFn ? formatFn(part) : part}\n`),
586
+ TypeWithGeneric: (typeName, genericArgs) => {
587
+ return `${typeName}${genericArgs.length ? `<${genericArgs.join(",")}>` : ""}`;
588
+ },
589
+ Tuple: (values) => {
590
+ return `[${values.join(", ")}]`;
591
+ }
592
+ };
593
+ this.primitiveTypes = {
594
+ integer: () => this.Ts.Keyword.Number,
595
+ number: () => this.Ts.Keyword.Number,
596
+ boolean: () => this.Ts.Keyword.Boolean,
597
+ object: () => this.Ts.Keyword.Object,
598
+ file: () => this.Ts.Keyword.File,
599
+ string: {
600
+ $default: this.Ts.Keyword.String,
601
+ binary: () => this.Ts.Keyword.File,
602
+ file: () => this.Ts.Keyword.File,
603
+ "date-time": () => this.Ts.Keyword.String,
604
+ time: () => this.Ts.Keyword.String,
605
+ date: () => this.Ts.Keyword.String,
606
+ duration: () => this.Ts.Keyword.String,
607
+ email: () => this.Ts.Keyword.String,
608
+ "idn-email": () => this.Ts.Keyword.String,
609
+ "idn-hostname": () => this.Ts.Keyword.String,
610
+ ipv4: () => this.Ts.Keyword.String,
611
+ ipv6: () => this.Ts.Keyword.String,
612
+ uuid: () => this.Ts.Keyword.String,
613
+ uri: () => this.Ts.Keyword.String,
614
+ "uri-reference": () => this.Ts.Keyword.String,
615
+ "uri-template": () => this.Ts.Keyword.String,
616
+ "json-pointer": () => this.Ts.Keyword.String,
617
+ "relative-json-pointer": () => this.Ts.Keyword.String,
618
+ regex: () => this.Ts.Keyword.String
619
+ }
620
+ };
621
+ this.templateInfos = [
622
+ {
623
+ name: "api",
624
+ fileName: "api"
625
+ },
626
+ {
627
+ name: "dataContracts",
628
+ fileName: "data-contracts"
629
+ },
630
+ {
631
+ name: "dataContractJsDoc",
632
+ fileName: "data-contract-jsdoc"
633
+ },
634
+ {
635
+ name: "interfaceDataContract",
636
+ fileName: "interface-data-contract"
637
+ },
638
+ {
639
+ name: "typeDataContract",
640
+ fileName: "type-data-contract"
641
+ },
642
+ {
643
+ name: "enumDataContract",
644
+ fileName: "enum-data-contract"
645
+ },
646
+ {
647
+ name: "objectFieldJsDoc",
648
+ fileName: "object-field-jsdoc"
649
+ },
650
+ {
651
+ name: "httpClient",
652
+ fileName: "http-client"
653
+ },
654
+ {
655
+ name: "routeTypes",
656
+ fileName: "route-types"
657
+ },
658
+ {
659
+ name: "routeName",
660
+ fileName: "route-name"
661
+ }
662
+ ];
663
+ this.templateExtensions = [".eta", ".ejs"];
664
+ this.update = (update) => {
665
+ objectAssign(this, update);
666
+ };
667
+ objectAssign(this.Ts, codeGenConstructs);
668
+ objectAssign(this.primitiveTypes, primitiveTypeConstructs);
669
+ this.defaultResponseType = this.Ts.Keyword.Void;
670
+ this.update({
671
+ ...otherConfig,
672
+ hooks: lodash.default.merge(this.hooks, hooks || {}),
673
+ constants: {
674
+ ...constants_exports,
675
+ ...constants
676
+ },
677
+ templateInfos: templateInfos || this.templateInfos
678
+ });
679
+ this.jsPrimitiveTypes = [
680
+ this.Ts.Keyword.Number,
681
+ this.Ts.Keyword.String,
682
+ this.Ts.Keyword.Boolean
683
+ ];
684
+ this.jsEmptyTypes = [this.Ts.Keyword.Null, this.Ts.Keyword.Undefined];
685
+ this.componentTypeNameResolver = new ComponentTypeNameResolver(this, []);
686
+ }
687
+ };
688
+
689
+ //#endregion
690
+ //#region src/schema-components-map.ts
691
+ var SchemaComponentsMap = class {
692
+ constructor(config) {
693
+ this._data = [];
694
+ this.createRef = (paths) => {
695
+ return ["#", ...paths].join("/");
696
+ };
697
+ this.parseRef = (ref) => {
698
+ return ref.split("/");
699
+ };
700
+ this.config = config;
701
+ }
702
+ clear() {
703
+ this._data = [];
704
+ }
705
+ createComponent($ref, rawTypeData) {
706
+ const parsed = this.parseRef($ref);
707
+ const typeName = parsed[parsed.length - 1];
708
+ const componentName = parsed[parsed.length - 2];
709
+ const componentSchema = {
710
+ $ref,
711
+ typeName,
712
+ rawTypeData,
713
+ componentName,
714
+ typeData: null
715
+ };
716
+ const usageComponent = this.config.hooks.onCreateComponent(componentSchema) || componentSchema;
717
+ const refIndex = this._data.findIndex((c) => c.$ref === $ref);
718
+ if (refIndex === -1) this._data.push(usageComponent);
719
+ else this._data[refIndex] = usageComponent;
720
+ return usageComponent;
721
+ }
722
+ getComponents() {
723
+ return this._data;
724
+ }
725
+ filter(...componentNames) {
726
+ return this._data.filter((it) => componentNames.some((componentName) => it.$ref.startsWith(`#/components/${componentName}`)));
727
+ }
728
+ get($ref) {
729
+ return this._data.find((c) => c.$ref === $ref) || null;
730
+ }
731
+ enumsFirst() {
732
+ this._data.sort((a, b) => {
733
+ if (Object.keys(a.rawTypeData || {}).includes("enum")) return -1;
734
+ if (Object.keys(b.rawTypeData || {}).includes("enum")) return 1;
735
+ return 0;
736
+ });
737
+ }
738
+ };
739
+
740
+ //#endregion
741
+ //#region src/schema-parser/schema-formatters.ts
742
+ var SchemaFormatters = class {
743
+ constructor(schemaParser) {
744
+ this.base = {
745
+ [SCHEMA_TYPES.ENUM]: (parsedSchema) => {
746
+ if (this.config.generateUnionEnums) return {
747
+ ...parsedSchema,
748
+ $content: parsedSchema.content,
749
+ content: this.config.Ts.UnionType(parsedSchema.content.map(({ value }) => value))
750
+ };
751
+ return {
752
+ ...parsedSchema,
753
+ $content: parsedSchema.content,
754
+ content: this.config.Ts.EnumFieldsWrapper(parsedSchema.content)
755
+ };
756
+ },
757
+ [SCHEMA_TYPES.OBJECT]: (parsedSchema) => {
758
+ if (parsedSchema.nullable) return this.inline[SCHEMA_TYPES.OBJECT](parsedSchema);
759
+ return {
760
+ ...parsedSchema,
761
+ $content: parsedSchema.content,
762
+ content: this.formatObjectContent(parsedSchema.content)
763
+ };
764
+ },
765
+ [SCHEMA_TYPES.PRIMITIVE]: (parsedSchema) => {
766
+ return {
767
+ ...parsedSchema,
768
+ $content: parsedSchema.content
769
+ };
770
+ }
771
+ };
772
+ this.inline = {
773
+ [SCHEMA_TYPES.ENUM]: (parsedSchema) => {
774
+ return {
775
+ ...parsedSchema,
776
+ content: parsedSchema.$ref ? parsedSchema.typeName : this.config.Ts.UnionType(lodash.default.compact([...parsedSchema.content.map(({ value }) => `${value}`), parsedSchema.nullable && this.config.Ts.Keyword.Null])) || this.config.Ts.Keyword.Any
777
+ };
778
+ },
779
+ [SCHEMA_TYPES.OBJECT]: (parsedSchema) => {
780
+ if (typeof parsedSchema.content === "string") return {
781
+ ...parsedSchema,
782
+ typeIdentifier: this.config.Ts.Keyword.Type,
783
+ content: this.schemaUtils.safeAddNullToType(parsedSchema.content)
784
+ };
785
+ return {
786
+ ...parsedSchema,
787
+ typeIdentifier: this.config.Ts.Keyword.Type,
788
+ content: this.schemaUtils.safeAddNullToType(parsedSchema, parsedSchema.content.length ? this.config.Ts.ObjectWrapper(this.formatObjectContent(parsedSchema.content)) : this.config.Ts.RecordType(this.config.Ts.Keyword.String, this.config.Ts.Keyword.Any))
789
+ };
790
+ }
791
+ };
792
+ this.formatSchema = (parsedSchema, formatType = "base") => {
793
+ const schemaType = lodash.default.get(parsedSchema, ["schemaType"]) || lodash.default.get(parsedSchema, ["$parsed", "schemaType"]);
794
+ const formatterFn = lodash.default.get(this, [formatType, schemaType]);
795
+ return formatterFn?.(parsedSchema) || parsedSchema;
796
+ };
797
+ this.formatDescription = (description$1, inline) => {
798
+ if (!description$1) return "";
799
+ const hasMultipleLines = description$1.includes("\n");
800
+ if (!hasMultipleLines) return description$1;
801
+ if (inline) return lodash.default._(description$1).split(/\n/g).map((part) => part.trim()).compact().join(" ").valueOf();
802
+ return description$1.replace(/\n$/g, "");
803
+ };
804
+ this.formatObjectContent = (content) => {
805
+ const fields = [];
806
+ for (const part of content) {
807
+ const extraSpace = " ";
808
+ const result = `${extraSpace}${part.field},\n`;
809
+ const renderedJsDoc = this.templatesWorker.renderTemplate(this.config.templatesToRender.dataContractJsDoc, { data: part });
810
+ const routeNameFromTemplate = renderedJsDoc.split("\n").map((c) => `${extraSpace}${c}`).join("\n");
811
+ if (routeNameFromTemplate) fields.push(`${routeNameFromTemplate}${result}`);
812
+ else fields.push(`${result}`);
813
+ }
814
+ return fields.join("");
815
+ };
816
+ this.config = schemaParser.config;
817
+ this.schemaUtils = schemaParser.schemaUtils;
818
+ this.templatesWorker = schemaParser.templatesWorker;
819
+ }
820
+ };
821
+
822
+ //#endregion
823
+ //#region src/util/sort-by-property.ts
824
+ const sortByProperty = (propertyName) => (o1, o2) => {
825
+ if (o1[propertyName] > o2[propertyName]) return 1;
826
+ if (o1[propertyName] < o2[propertyName]) return -1;
827
+ return 0;
828
+ };
829
+
830
+ //#endregion
831
+ //#region src/schema-parser/mono-schema-parser.ts
832
+ var MonoSchemaParser = class {
833
+ constructor(schemaParser, schema, typeName = null, schemaPath = []) {
834
+ this.buildTypeNameFromPath = () => {
835
+ return this.schemaUtils.buildTypeNameFromPath(this.schemaPath);
836
+ };
837
+ this.schemaParser = schemaParser;
838
+ this.schemaParserFabric = schemaParser.schemaParserFabric;
839
+ this.schema = schema;
840
+ this.typeName = typeName;
841
+ this.typeNameFormatter = schemaParser.typeNameFormatter;
842
+ this.schemaPath = schemaPath;
843
+ this.schemaComponentsMap = this.schemaParser.schemaComponentsMap;
844
+ this.schemaUtils = this.schemaParser.schemaUtils;
845
+ this.config = this.schemaParser.config;
846
+ this.schemaFormatters = this.schemaParser.schemaFormatters;
847
+ }
848
+ parse() {
849
+ throw new Error("not implemented");
850
+ }
851
+ };
852
+
853
+ //#endregion
854
+ //#region src/schema-parser/base-schema-parsers/array.ts
855
+ var ArraySchemaParser = class extends MonoSchemaParser {
856
+ parse() {
857
+ let contentType;
858
+ const { type: type$1, description: description$1, items } = this.schema || {};
859
+ if (Array.isArray(items) && type$1 === SCHEMA_TYPES.ARRAY) {
860
+ const tupleContent = [];
861
+ for (const item of items) tupleContent.push(this.schemaParserFabric.createSchemaParser({
862
+ schema: item,
863
+ schemaPath: this.schemaPath
864
+ }).getInlineParseContent());
865
+ contentType = this.config.Ts.Tuple(tupleContent);
866
+ } else {
867
+ const content = this.schemaParserFabric.createSchemaParser({
868
+ schema: items,
869
+ schemaPath: this.schemaPath
870
+ }).getInlineParseContent();
871
+ contentType = this.config.Ts.ArrayType(content);
872
+ }
873
+ return {
874
+ ...typeof this.schema === "object" ? this.schema : {},
875
+ $schemaPath: this.schemaPath.slice(),
876
+ $parsedSchema: true,
877
+ schemaType: SCHEMA_TYPES.PRIMITIVE,
878
+ type: SCHEMA_TYPES.PRIMITIVE,
879
+ typeIdentifier: this.config.Ts.Keyword.Type,
880
+ name: this.typeName,
881
+ description: this.schemaFormatters.formatDescription(description$1),
882
+ content: this.schemaUtils.safeAddNullToType(this.schema, contentType)
883
+ };
884
+ }
885
+ };
886
+
887
+ //#endregion
888
+ //#region src/schema-parser/base-schema-parsers/complex.ts
889
+ var ComplexSchemaParser = class extends MonoSchemaParser {
890
+ parse() {
891
+ const complexType = this.schemaUtils.getComplexType(this.schema);
892
+ const simpleSchema = lodash.default.omit(lodash.default.clone(this.schema), lodash.default.keys(this.schemaParser._complexSchemaParsers));
893
+ const complexSchemaContent = this.schemaParser._complexSchemaParsers[complexType](this.schema);
894
+ return {
895
+ ...typeof this.schema === "object" ? this.schema : {},
896
+ $schemaPath: this.schemaPath.slice(),
897
+ $parsedSchema: true,
898
+ schemaType: SCHEMA_TYPES.COMPLEX,
899
+ type: SCHEMA_TYPES.PRIMITIVE,
900
+ typeIdentifier: this.config.Ts.Keyword.Type,
901
+ name: this.typeName,
902
+ description: this.schemaFormatters.formatDescription(this.schema.description || lodash.default.compact(lodash.default.map(this.schema[complexType], "description"))[0] || ""),
903
+ content: this.config.Ts.IntersectionType(lodash.default.compact([this.config.Ts.ExpressionGroup(complexSchemaContent), this.schemaUtils.getInternalSchemaType(simpleSchema) === SCHEMA_TYPES.OBJECT && this.config.Ts.ExpressionGroup(this.schemaParserFabric.createSchemaParser({
904
+ schema: simpleSchema,
905
+ schemaPath: this.schemaPath
906
+ }).getInlineParseContent())])) || this.config.Ts.Keyword.Any
907
+ };
908
+ }
909
+ };
910
+
911
+ //#endregion
912
+ //#region src/schema-parser/base-schema-parsers/discriminator.ts
913
+ var DiscriminatorSchemaParser = class extends MonoSchemaParser {
914
+ constructor(..._args) {
915
+ super(..._args);
916
+ this.createDiscriminatorSchema = ({ skipMappingType, abstractSchemaStruct }) => {
917
+ const ts = this.config.Ts;
918
+ const refPath = this.schemaComponentsMap.createRef([
919
+ "components",
920
+ "schemas",
921
+ this.typeName
922
+ ]);
923
+ const { discriminator } = this.schema;
924
+ const mappingEntries = lodash.default.entries(discriminator.mapping);
925
+ const ableToCreateMappingType = !skipMappingType && !!(abstractSchemaStruct?.typeName && mappingEntries.length);
926
+ const mappingContents = [];
927
+ let mappingTypeName;
928
+ /** { mapping_key: SchemaEnum.MappingKey, ... } */
929
+ const mappingPropertySchemaEnumKeysMap = this.createMappingPropertySchemaEnumKeys({
930
+ abstractSchemaStruct,
931
+ discPropertyName: discriminator.propertyName
932
+ });
933
+ if (ableToCreateMappingType) {
934
+ const rawTypeName = `${abstractSchemaStruct.typeName}_${discriminator.propertyName}`;
935
+ const generatedTypeName = this.schemaUtils.resolveTypeName(rawTypeName, {
936
+ suffixes: this.config.extractingOptions.discriminatorMappingSuffix,
937
+ resolver: this.config.extractingOptions.discriminatorMappingNameResolver
938
+ });
939
+ const content$1 = ts.IntersectionType([ts.ObjectWrapper(ts.TypeField({
940
+ key: ts.StringValue(discriminator.propertyName),
941
+ value: "Key"
942
+ })), "Type"]);
943
+ const component = this.schemaParserFabric.createParsedComponent({
944
+ typeName: generatedTypeName,
945
+ schema: {
946
+ type: "object",
947
+ properties: {},
948
+ genericArgs: [{ name: "Key" }, { name: "Type" }],
949
+ internal: true
950
+ }
951
+ });
952
+ component.typeData.content = content$1;
953
+ mappingTypeName = this.typeNameFormatter.format(component.typeName);
954
+ }
955
+ /** returns (GenericType<"mapping_key", MappingType>) or ({ discriminatorProperty: "mapping_key" } & MappingType) */
956
+ const createMappingContent = (mappingSchema, mappingKey) => {
957
+ const content$1 = this.schemaParserFabric.createSchemaParser({
958
+ schema: mappingSchema,
959
+ schemaPath: this.schemaPath
960
+ }).getInlineParseContent();
961
+ const mappingUsageKey = mappingPropertySchemaEnumKeysMap[mappingKey] || ts.StringValue(mappingKey);
962
+ if (ableToCreateMappingType) return ts.TypeWithGeneric(mappingTypeName, [mappingUsageKey, content$1]);
963
+ return ts.ExpressionGroup(ts.IntersectionType([ts.ObjectWrapper(ts.TypeField({
964
+ key: discriminator.propertyName,
965
+ value: mappingUsageKey
966
+ })), content$1]));
967
+ };
968
+ for (const [mappingKey, schema] of mappingEntries) {
969
+ const mappingSchema = typeof schema === "string" ? { $ref: schema } : schema;
970
+ this.mutateMappingDependentSchema({
971
+ discPropertyName: discriminator.propertyName,
972
+ abstractSchemaStruct,
973
+ mappingSchema,
974
+ refPath,
975
+ mappingPropertySchemaEnumKeysMap
976
+ });
977
+ mappingContents.push(createMappingContent(mappingSchema, mappingKey));
978
+ }
979
+ if (skipMappingType) return null;
980
+ const content = ts.ExpressionGroup(ts.UnionType(mappingContents));
981
+ return { content };
982
+ };
983
+ this.createMappingPropertySchemaEnumKeys = ({ abstractSchemaStruct, discPropertyName }) => {
984
+ const ts = this.config.Ts;
985
+ let mappingPropertySchemaEnumKeysMap = {};
986
+ let mappingPropertySchema = lodash.default.get(abstractSchemaStruct?.component?.rawTypeData, ["properties", discPropertyName]);
987
+ if (this.schemaUtils.isRefSchema(mappingPropertySchema)) mappingPropertySchema = this.schemaUtils.getSchemaRefType(mappingPropertySchema);
988
+ if (mappingPropertySchema?.rawTypeData?.$parsed?.type === SCHEMA_TYPES.ENUM) mappingPropertySchemaEnumKeysMap = lodash.default.reduce(mappingPropertySchema.rawTypeData.$parsed.enum, (acc, key, index) => {
989
+ const enumKey = mappingPropertySchema.rawTypeData.$parsed.content[index].key;
990
+ acc[key] = ts.EnumUsageKey(mappingPropertySchema.rawTypeData.$parsed.typeName, enumKey);
991
+ return acc;
992
+ }, {});
993
+ return mappingPropertySchemaEnumKeysMap;
994
+ };
995
+ this.mutateMappingDependentSchema = ({ discPropertyName, abstractSchemaStruct, mappingSchema, refPath, mappingPropertySchemaEnumKeysMap }) => {
996
+ const complexSchemaKeys = lodash.default.keys(this.schemaParser._complexSchemaParsers);
997
+ if (mappingSchema.$ref && abstractSchemaStruct?.component?.$ref) {
998
+ const mappingRefSchema = this.schemaUtils.getSchemaRefType(mappingSchema)?.rawTypeData;
999
+ if (mappingRefSchema) {
1000
+ for (const schemaKey of complexSchemaKeys) if (Array.isArray(mappingRefSchema[schemaKey])) mappingRefSchema[schemaKey] = mappingRefSchema[schemaKey].map((schema) => {
1001
+ if (schema.$ref === refPath) return {
1002
+ ...schema,
1003
+ $ref: abstractSchemaStruct.component.$ref
1004
+ };
1005
+ if (this.schemaUtils.getInternalSchemaType(schema) === SCHEMA_TYPES.OBJECT) for (const schemaPropertyName in schema.properties) {
1006
+ const schemaProperty = schema.properties[schemaPropertyName];
1007
+ if (schemaPropertyName === discPropertyName && this.schemaUtils.getInternalSchemaType(schemaProperty) === SCHEMA_TYPES.ENUM && schemaProperty.enum.length === 1 && mappingPropertySchemaEnumKeysMap[schemaProperty.enum[0]]) schema.properties[schemaPropertyName] = this.schemaParserFabric.createSchema({ content: mappingPropertySchemaEnumKeysMap[schemaProperty.enum[0]] });
1008
+ }
1009
+ return schema;
1010
+ });
1011
+ }
1012
+ }
1013
+ };
1014
+ this.createAbstractSchemaStruct = () => {
1015
+ const { discriminator,...noDiscriminatorSchema } = this.schema;
1016
+ const complexSchemaKeys = lodash.default.keys(this.schemaParser._complexSchemaParsers);
1017
+ const schema = lodash.default.omit(structuredClone(noDiscriminatorSchema), complexSchemaKeys);
1018
+ const schemaIsAny = this.schemaParserFabric.getInlineParseContent(structuredClone(schema)) === this.config.Ts.Keyword.Any;
1019
+ const schemaIsEmpty = !lodash.default.keys(schema).length;
1020
+ if (schemaIsEmpty || schemaIsAny) return null;
1021
+ const typeName = this.schemaUtils.resolveTypeName(this.typeName, {
1022
+ prefixes: this.config.extractingOptions.discriminatorAbstractPrefix,
1023
+ resolver: this.config.extractingOptions.discriminatorAbstractResolver
1024
+ });
1025
+ const component = this.schemaComponentsMap.createComponent(this.schemaComponentsMap.createRef([
1026
+ "components",
1027
+ "schemas",
1028
+ typeName
1029
+ ]), {
1030
+ ...schema,
1031
+ internal: true
1032
+ });
1033
+ const content = this.schemaParserFabric.createSchemaParser({
1034
+ schema: component,
1035
+ schemaPath: this.schemaPath
1036
+ }).getInlineParseContent();
1037
+ return {
1038
+ typeName,
1039
+ component,
1040
+ content
1041
+ };
1042
+ };
1043
+ this.createComplexSchemaStruct = () => {
1044
+ const ts = this.config.Ts;
1045
+ const complexType = this.schemaUtils.getComplexType(this.schema);
1046
+ if (complexType === SCHEMA_TYPES.COMPLEX_UNKNOWN) return null;
1047
+ return { content: ts.ExpressionGroup(this.schemaParser._complexSchemaParsers[complexType](this.schema)) };
1048
+ };
1049
+ }
1050
+ parse() {
1051
+ const ts = this.config.Ts;
1052
+ const { discriminator,...noDiscriminatorSchema } = this.schema;
1053
+ if (!discriminator.mapping) return this.schemaParserFabric.createSchemaParser({
1054
+ schema: noDiscriminatorSchema,
1055
+ typeName: this.typeName,
1056
+ schemaPath: this.schemaPath
1057
+ }).parseSchema();
1058
+ const skipMappingType = false;
1059
+ const abstractSchemaStruct = this.createAbstractSchemaStruct();
1060
+ const discriminatorSchemaStruct = this.createDiscriminatorSchema({
1061
+ skipMappingType,
1062
+ abstractSchemaStruct
1063
+ });
1064
+ const schemaContent = ts.IntersectionType([abstractSchemaStruct?.content, discriminatorSchemaStruct?.content].filter(Boolean));
1065
+ return {
1066
+ ...typeof this.schema === "object" ? this.schema : {},
1067
+ $schemaPath: this.schemaPath.slice(),
1068
+ $parsedSchema: true,
1069
+ schemaType: SCHEMA_TYPES.COMPLEX,
1070
+ type: SCHEMA_TYPES.PRIMITIVE,
1071
+ typeIdentifier: ts.Keyword.Type,
1072
+ name: this.typeName,
1073
+ description: this.schemaFormatters.formatDescription(this.schema.description),
1074
+ content: schemaContent
1075
+ };
1076
+ }
1077
+ };
1078
+
1079
+ //#endregion
1080
+ //#region src/schema-parser/util/enum-key-resolver.ts
1081
+ var EnumKeyResolver = class extends NameResolver {
1082
+ constructor(config, reservedNames) {
1083
+ super(config, reservedNames, (variants) => {
1084
+ const generatedVariant = variants[0] && `${variants[0]}${this.counter++}` || `${this.config.enumKeyResolverName}${this.counter++}`;
1085
+ consola.consola.debug("generated fallback type name for enum key - ", generatedVariant);
1086
+ return generatedVariant;
1087
+ });
1088
+ this.counter = 1;
1089
+ }
1090
+ };
1091
+
1092
+ //#endregion
1093
+ //#region src/schema-parser/base-schema-parsers/enum.ts
1094
+ var EnumSchemaParser = class extends MonoSchemaParser {
1095
+ constructor(...args) {
1096
+ super(...args);
1097
+ this.extractEnum = (pathTypeName) => {
1098
+ const generatedTypeName = this.schemaUtils.resolveTypeName(pathTypeName, {
1099
+ suffixes: this.config.extractingOptions.enumSuffix,
1100
+ resolver: this.config.extractingOptions.enumNameResolver
1101
+ });
1102
+ const customComponent = this.schemaComponentsMap.createComponent(this.schemaComponentsMap.createRef([
1103
+ "components",
1104
+ "schemas",
1105
+ generatedTypeName
1106
+ ]), { ...this.schema });
1107
+ return this.schemaParserFabric.parseSchema(customComponent);
1108
+ };
1109
+ this.formatEnumKey = ({ key, value }) => {
1110
+ let formatted;
1111
+ if (key) formatted = this.typeNameFormatter.format(key, { type: "enum-key" });
1112
+ if (!formatted) formatted = this.typeNameFormatter.format(`${value}`, { type: "enum-key" });
1113
+ return this.enumKeyResolver.resolve([formatted]);
1114
+ };
1115
+ this.enumKeyResolver = new EnumKeyResolver(this.config, []);
1116
+ }
1117
+ parse() {
1118
+ const pathTypeName = this.buildTypeNameFromPath();
1119
+ if (this.config.extractEnums && !this.typeName && pathTypeName != null) return this.extractEnum(pathTypeName);
1120
+ const refType = this.schemaUtils.getSchemaRefType(this.schema);
1121
+ const $ref = refType?.$ref || null;
1122
+ if (Array.isArray(this.schema.enum)) this.schema.enum = this.schema.enum.filter((key) => key != null);
1123
+ if (Array.isArray(this.schema.enum) && Array.isArray(this.schema.enum[0])) return this.schemaParserFabric.parseSchema({ oneOf: this.schema.enum.map((enumNames$1) => ({
1124
+ type: "array",
1125
+ items: enumNames$1.map((enumName) => ({
1126
+ type: "string",
1127
+ enum: [enumName]
1128
+ }))
1129
+ })) }, this.typeName, this.schemaPath);
1130
+ const keyType = this.schemaUtils.getSchemaType(this.schema);
1131
+ const enumNames = this.schemaUtils.getEnumNames(this.schema);
1132
+ let content = null;
1133
+ const formatValue = (value) => {
1134
+ if (value === null) return this.config.Ts.NullValue(value);
1135
+ if (keyType.includes(this.schemaUtils.getSchemaType({ type: "number" }))) return this.config.Ts.NumberValue(value);
1136
+ if (keyType.includes(this.schemaUtils.getSchemaType({ type: "boolean" }))) return this.config.Ts.BooleanValue(value);
1137
+ return this.config.Ts.StringValue(value);
1138
+ };
1139
+ if (Array.isArray(enumNames) && lodash.default.size(enumNames)) content = enumNames.map((enumName, index) => {
1140
+ const enumValue = lodash.default.get(this.schema.enum, index);
1141
+ const formattedKey = this.formatEnumKey({
1142
+ key: enumName,
1143
+ value: enumValue
1144
+ });
1145
+ if (this.config.enumNamesAsValues || enumValue === void 0) return {
1146
+ key: formattedKey,
1147
+ type: this.config.Ts.Keyword.String,
1148
+ value: this.config.Ts.StringValue(enumName)
1149
+ };
1150
+ return {
1151
+ key: formattedKey,
1152
+ type: keyType,
1153
+ value: formatValue(enumValue)
1154
+ };
1155
+ });
1156
+ else content = this.schema.enum.map((value) => {
1157
+ return {
1158
+ key: this.formatEnumKey({ value }),
1159
+ type: keyType,
1160
+ value: formatValue(value)
1161
+ };
1162
+ });
1163
+ return {
1164
+ ...typeof this.schema === "object" ? this.schema : {},
1165
+ $ref,
1166
+ typeName: this.typeName || $ref && refType.typeName || null,
1167
+ $parsedSchema: true,
1168
+ schemaType: SCHEMA_TYPES.ENUM,
1169
+ type: SCHEMA_TYPES.ENUM,
1170
+ keyType,
1171
+ typeIdentifier: this.config.generateUnionEnums ? this.config.Ts.Keyword.Type : this.config.Ts.Keyword.Enum,
1172
+ name: this.typeName,
1173
+ description: this.schemaFormatters.formatDescription(this.schema.description),
1174
+ content
1175
+ };
1176
+ }
1177
+ };
1178
+
1179
+ //#endregion
1180
+ //#region src/schema-parser/base-schema-parsers/object.ts
1181
+ var ObjectSchemaParser = class extends MonoSchemaParser {
1182
+ constructor(..._args) {
1183
+ super(..._args);
1184
+ this.getObjectSchemaContent = (schema) => {
1185
+ const { properties, additionalProperties } = schema || {};
1186
+ const propertiesContent = lodash.default.map(properties, (property, name$1) => {
1187
+ const required = this.schemaUtils.isPropertyRequired(name$1, property, schema);
1188
+ const rawTypeData = lodash.default.get(this.schemaUtils.getSchemaRefType(property), "rawTypeData", {});
1189
+ const nullable = !!(rawTypeData.nullable || property.nullable);
1190
+ const fieldName = this.typeNameFormatter.isValidName(name$1) ? name$1 : this.config.Ts.StringValue(name$1);
1191
+ const fieldValue = this.schemaParserFabric.createSchemaParser({
1192
+ schema: property,
1193
+ schemaPath: [...this.schemaPath, name$1]
1194
+ }).getInlineParseContent();
1195
+ const readOnly = property.readOnly;
1196
+ return {
1197
+ ...property,
1198
+ $$raw: property,
1199
+ title: property.title,
1200
+ description: property.description || lodash.default.compact(lodash.default.map(property[this.schemaUtils.getComplexType(property)], "description"))[0] || rawTypeData.description || lodash.default.compact(lodash.default.map(rawTypeData[this.schemaUtils.getComplexType(rawTypeData)], "description"))[0] || "",
1201
+ isRequired: required,
1202
+ isNullable: nullable,
1203
+ name: fieldName,
1204
+ value: fieldValue,
1205
+ field: this.config.Ts.TypeField({
1206
+ readonly: readOnly && this.config.addReadonly,
1207
+ optional: !required,
1208
+ key: fieldName,
1209
+ value: fieldValue
1210
+ })
1211
+ };
1212
+ });
1213
+ if (additionalProperties) propertiesContent.push({
1214
+ $$raw: { additionalProperties },
1215
+ description: "",
1216
+ isRequired: false,
1217
+ field: this.config.Ts.InterfaceDynamicField(this.config.Ts.Keyword.String, this.config.Ts.Keyword.Any)
1218
+ });
1219
+ return propertiesContent;
1220
+ };
1221
+ }
1222
+ parse() {
1223
+ const contentProperties = this.getObjectSchemaContent(this.schema);
1224
+ return {
1225
+ ...typeof this.schema === "object" ? this.schema : {},
1226
+ $schemaPath: this.schemaPath.slice(),
1227
+ $parsedSchema: true,
1228
+ schemaType: SCHEMA_TYPES.OBJECT,
1229
+ type: SCHEMA_TYPES.OBJECT,
1230
+ typeIdentifier: this.config.Ts.Keyword.Interface,
1231
+ name: this.typeName,
1232
+ description: this.schemaFormatters.formatDescription(this.schema.description),
1233
+ allFieldsAreOptional: !contentProperties.some((part) => part.isRequired),
1234
+ content: contentProperties
1235
+ };
1236
+ }
1237
+ };
1238
+
1239
+ //#endregion
1240
+ //#region src/schema-parser/base-schema-parsers/primitive.ts
1241
+ var PrimitiveSchemaParser = class extends MonoSchemaParser {
1242
+ parse() {
1243
+ let contentType = null;
1244
+ const { additionalProperties, type: type$1, description: description$1, items } = this.schema || {};
1245
+ if (type$1 === this.config.Ts.Keyword.Object && additionalProperties) {
1246
+ const fieldType = typeof additionalProperties === "object" ? this.schemaParserFabric.createSchemaParser({
1247
+ schema: additionalProperties,
1248
+ schemaPath: this.schemaPath
1249
+ }).getInlineParseContent() : this.config.Ts.Keyword.Any;
1250
+ contentType = this.config.Ts.RecordType(this.config.Ts.Keyword.String, fieldType);
1251
+ }
1252
+ if (Array.isArray(type$1) && type$1.length) contentType = this.schemaParser._complexSchemaParsers.oneOf({
1253
+ ...typeof this.schema === "object" ? this.schema : {},
1254
+ oneOf: type$1.map((type$2) => ({ type: type$2 }))
1255
+ });
1256
+ if (Array.isArray(items) && type$1 === SCHEMA_TYPES.ARRAY) contentType = this.config.Ts.Tuple(items.map((item) => this.schemaParserFabric.createSchemaParser({
1257
+ schema: item,
1258
+ schemaPath: this.schemaPath
1259
+ }).getInlineParseContent()));
1260
+ return {
1261
+ ...typeof this.schema === "object" ? this.schema : {},
1262
+ $schemaPath: this.schemaPath.slice(),
1263
+ $parsedSchema: true,
1264
+ schemaType: SCHEMA_TYPES.PRIMITIVE,
1265
+ type: SCHEMA_TYPES.PRIMITIVE,
1266
+ typeIdentifier: this.config.Ts.Keyword.Type,
1267
+ name: this.typeName,
1268
+ description: this.schemaFormatters.formatDescription(description$1),
1269
+ content: type$1 === this.config.Ts.Keyword.Null ? type$1 : contentType || this.schemaUtils.getSchemaType(this.schema)
1270
+ };
1271
+ }
1272
+ };
1273
+
1274
+ //#endregion
1275
+ //#region src/schema-parser/complex-schema-parsers/all-of.ts
1276
+ var AllOfSchemaParser = class extends MonoSchemaParser {
1277
+ parse() {
1278
+ const ignoreTypes = [this.config.Ts.Keyword.Any];
1279
+ const combined = this.schema.allOf.map((childSchema) => this.schemaParserFabric.getInlineParseContent(this.schemaUtils.makeAddRequiredToChildSchema(this.schema, childSchema), null, this.schemaPath));
1280
+ const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));
1281
+ const type$1 = this.config.Ts.IntersectionType(filtered);
1282
+ return this.schemaUtils.safeAddNullToType(this.schema, type$1);
1283
+ }
1284
+ };
1285
+
1286
+ //#endregion
1287
+ //#region src/schema-parser/complex-schema-parsers/any-of.ts
1288
+ var AnyOfSchemaParser = class extends MonoSchemaParser {
1289
+ parse() {
1290
+ const ignoreTypes = [this.config.Ts.Keyword.Any];
1291
+ const combined = this.schema.anyOf.map((childSchema) => this.schemaParserFabric.getInlineParseContent(this.schemaUtils.makeAddRequiredToChildSchema(this.schema, childSchema), null, this.schemaPath));
1292
+ const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));
1293
+ const type$1 = this.config.Ts.UnionType(filtered);
1294
+ return this.schemaUtils.safeAddNullToType(this.schema, type$1);
1295
+ }
1296
+ };
1297
+
1298
+ //#endregion
1299
+ //#region src/schema-parser/complex-schema-parsers/not.ts
1300
+ var NotSchemaParser = class extends MonoSchemaParser {
1301
+ parse() {
1302
+ return this.config.Ts.Keyword.Any;
1303
+ }
1304
+ };
1305
+
1306
+ //#endregion
1307
+ //#region src/schema-parser/complex-schema-parsers/one-of.ts
1308
+ var OneOfSchemaParser = class extends MonoSchemaParser {
1309
+ parse() {
1310
+ const ignoreTypes = [this.config.Ts.Keyword.Any];
1311
+ const combined = this.schema.oneOf.map((childSchema) => this.schemaParserFabric.getInlineParseContent(this.schemaUtils.makeAddRequiredToChildSchema(this.schema, childSchema), null, this.schemaPath));
1312
+ const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));
1313
+ const type$1 = this.config.Ts.UnionType(filtered);
1314
+ return this.schemaUtils.safeAddNullToType(this.schema, type$1);
1315
+ }
1316
+ };
1317
+
1318
+ //#endregion
1319
+ //#region src/schema-parser/schema-parser.ts
1320
+ var SchemaParser = class {
1321
+ constructor(schemaParserFabric, { typeName, schema, schemaPath } = {}) {
1322
+ this.schemaPath = [];
1323
+ this._complexSchemaParsers = {
1324
+ [SCHEMA_TYPES.COMPLEX_ONE_OF]: (schema$1) => {
1325
+ const SchemaParser$1 = this.config.schemaParsers.complexOneOf || OneOfSchemaParser;
1326
+ const schemaParser = new SchemaParser$1(this, schema$1, null, this.schemaPath);
1327
+ return schemaParser.parse();
1328
+ },
1329
+ [SCHEMA_TYPES.COMPLEX_ALL_OF]: (schema$1) => {
1330
+ const SchemaParser$1 = this.config.schemaParsers.complexAllOf || AllOfSchemaParser;
1331
+ const schemaParser = new SchemaParser$1(this, schema$1, null, this.schemaPath);
1332
+ return schemaParser.parse();
1333
+ },
1334
+ [SCHEMA_TYPES.COMPLEX_ANY_OF]: (schema$1) => {
1335
+ const SchemaParser$1 = this.config.schemaParsers.complexAnyOf || AnyOfSchemaParser;
1336
+ const schemaParser = new SchemaParser$1(this, schema$1, null, this.schemaPath);
1337
+ return schemaParser.parse();
1338
+ },
1339
+ [SCHEMA_TYPES.COMPLEX_NOT]: (schema$1) => {
1340
+ const SchemaParser$1 = this.config.schemaParsers.complexNot || NotSchemaParser;
1341
+ const schemaParser = new SchemaParser$1(this, schema$1, null, this.schemaPath);
1342
+ return schemaParser.parse();
1343
+ }
1344
+ };
1345
+ this._baseSchemaParsers = {
1346
+ [SCHEMA_TYPES.ENUM]: (schema$1, typeName$1) => {
1347
+ const SchemaParser$1 = this.config.schemaParsers.enum || EnumSchemaParser;
1348
+ const schemaParser = new SchemaParser$1(this, schema$1, typeName$1, this.schemaPath);
1349
+ return schemaParser.parse();
1350
+ },
1351
+ [SCHEMA_TYPES.OBJECT]: (schema$1, typeName$1) => {
1352
+ const SchemaParser$1 = this.config.schemaParsers.object || ObjectSchemaParser;
1353
+ const schemaParser = new SchemaParser$1(this, schema$1, typeName$1, this.schemaPath);
1354
+ return schemaParser.parse();
1355
+ },
1356
+ [SCHEMA_TYPES.COMPLEX]: (schema$1, typeName$1) => {
1357
+ const SchemaParser$1 = this.config.schemaParsers.complex || ComplexSchemaParser;
1358
+ const schemaParser = new SchemaParser$1(this, schema$1, typeName$1, this.schemaPath);
1359
+ return schemaParser.parse();
1360
+ },
1361
+ [SCHEMA_TYPES.PRIMITIVE]: (schema$1, typeName$1) => {
1362
+ const SchemaParser$1 = this.config.schemaParsers.primitive || PrimitiveSchemaParser;
1363
+ const schemaParser = new SchemaParser$1(this, schema$1, typeName$1, this.schemaPath);
1364
+ return schemaParser.parse();
1365
+ },
1366
+ [SCHEMA_TYPES.DISCRIMINATOR]: (schema$1, typeName$1) => {
1367
+ const SchemaParser$1 = this.config.schemaParsers.discriminator || DiscriminatorSchemaParser;
1368
+ const schemaParser = new SchemaParser$1(this, schema$1, typeName$1, this.schemaPath);
1369
+ return schemaParser.parse();
1370
+ },
1371
+ [SCHEMA_TYPES.ARRAY]: (schema$1, typeName$1) => {
1372
+ const SchemaParser$1 = this.config.schemaParsers.array || ArraySchemaParser;
1373
+ const schemaParser = new SchemaParser$1(this, schema$1, typeName$1, this.schemaPath);
1374
+ return schemaParser.parse();
1375
+ }
1376
+ };
1377
+ this.parseSchema = () => {
1378
+ if (!this.schema) return this._baseSchemaParsers[SCHEMA_TYPES.PRIMITIVE](null, this.typeName);
1379
+ let schemaType = null;
1380
+ let parsedSchema = null;
1381
+ if (typeof this.schema === "string") return this.schema;
1382
+ if (!this.schema.$parsed) {
1383
+ if (!this.typeName && this.schemaUtils.isRefSchema(this.schema)) this.typeName = this.schemaUtils.getSchemaType(this.schema);
1384
+ if (this.schema.items && !Array.isArray(this.schema.items) && !this.schema.type) this.schema.type = SCHEMA_TYPES.ARRAY;
1385
+ if (Array.isArray(this.schema.enum) && this.schema.enum.length === 1 && this.schema.enum[0] == null) {
1386
+ consola.consola.debug("invalid enum schema", this.schema);
1387
+ this.schema = { type: this.config.Ts.Keyword.Null };
1388
+ }
1389
+ if ("content" in this.schema && typeof this.schema.content === "object") {
1390
+ const schema$1 = this.extractSchemaFromResponseStruct(this.schema);
1391
+ const schemaParser = this.schemaParserFabric.createSchemaParser({
1392
+ schema: schema$1,
1393
+ typeName: this.typeName,
1394
+ schemaPath: this.schemaPath
1395
+ });
1396
+ this.schema.$parsed = schemaParser.parseSchema();
1397
+ return this.schema.$parsed;
1398
+ }
1399
+ schemaType = this.schemaUtils.getInternalSchemaType(this.schema);
1400
+ this.schemaPath.push(this.typeName);
1401
+ lodash.default.merge(this.schema, this.config.hooks.onPreParseSchema(this.schema, this.typeName, schemaType));
1402
+ parsedSchema = this._baseSchemaParsers[schemaType](this.schema, this.typeName);
1403
+ this.schema.$parsed = this.config.hooks.onParseSchema(this.schema, parsedSchema) || parsedSchema;
1404
+ if (this.config.sortTypes && Array.isArray(this.schema.$parsed?.content)) this.schema.$parsed.content = this.schema.$parsed.content.sort(sortByProperty("name"));
1405
+ }
1406
+ this.schemaPath.pop();
1407
+ return this.schema.$parsed;
1408
+ };
1409
+ this.getInlineParseContent = () => {
1410
+ const parsedSchema = this.parseSchema();
1411
+ const formattedSchema = this.schemaFormatters.formatSchema(parsedSchema, "inline");
1412
+ return formattedSchema.content;
1413
+ };
1414
+ this.getParseContent = () => {
1415
+ const parsedSchema = this.parseSchema();
1416
+ const formattedSchema = this.schemaFormatters.formatSchema(parsedSchema, "base");
1417
+ return formattedSchema.content;
1418
+ };
1419
+ this.extractSchemaFromResponseStruct = (responseStruct) => {
1420
+ const { content,...extras } = responseStruct;
1421
+ const firstResponse = lodash.default.first(lodash.default.values(content));
1422
+ const firstSchema = lodash.default.get(firstResponse, "schema");
1423
+ if (!firstSchema) return;
1424
+ return {
1425
+ ...extras,
1426
+ ...lodash.default.omit(firstResponse, "schema"),
1427
+ ...firstSchema
1428
+ };
1429
+ };
1430
+ this.schemaParserFabric = schemaParserFabric;
1431
+ this.config = schemaParserFabric.config;
1432
+ this.templatesWorker = schemaParserFabric.templatesWorker;
1433
+ this.schemaComponentsMap = schemaParserFabric.schemaComponentsMap;
1434
+ this.typeNameFormatter = schemaParserFabric.typeNameFormatter;
1435
+ this.schemaWalker = schemaParserFabric.schemaWalker;
1436
+ this.schemaFormatters = schemaParserFabric.schemaFormatters;
1437
+ this.schemaUtils = schemaParserFabric.schemaUtils;
1438
+ this.typeName = typeName || null;
1439
+ this.schema = schema;
1440
+ this.schemaPath = [...schemaPath || []];
1441
+ }
1442
+ };
1443
+
1444
+ //#endregion
1445
+ //#region src/util/internal-case.ts
1446
+ function internalCase(value) {
1447
+ return lodash.default.camelCase(lodash.default.lowerCase(value));
1448
+ }
1449
+
1450
+ //#endregion
1451
+ //#region src/util/pascal-case.ts
1452
+ function pascalCase(value) {
1453
+ return lodash.default.upperFirst(lodash.default.camelCase(value));
1454
+ }
1455
+
1456
+ //#endregion
1457
+ //#region src/schema-parser/schema-utils.ts
1458
+ var SchemaUtils = class {
1459
+ constructor({ config, schemaComponentsMap, typeNameFormatter, schemaWalker }) {
1460
+ this.getRequiredProperties = (schema) => {
1461
+ return lodash.default.uniq(schema && Array.isArray(schema.required) && schema.required || []);
1462
+ };
1463
+ this.isRefSchema = (schema) => {
1464
+ return !!schema?.$ref;
1465
+ };
1466
+ this.getEnumNames = (schema) => {
1467
+ return schema["x-enumNames"] || schema.xEnumNames || schema["x-enumnames"] || schema["x-enum-varnames"];
1468
+ };
1469
+ this.getSchemaRefType = (schema) => {
1470
+ if (!this.isRefSchema(schema)) return null;
1471
+ return this.schemaComponentsMap.get(schema.$ref);
1472
+ };
1473
+ this.isPropertyRequired = (name$1, propertySchema, rootSchema) => {
1474
+ if (propertySchema["x-omitempty"] === false) return true;
1475
+ const isRequired = typeof propertySchema.required === "boolean" ? !!propertySchema.required : Array.isArray(rootSchema.required) ? rootSchema.required.includes(name$1) : !!rootSchema.required;
1476
+ if (this.config.convertedFromSwagger2) return typeof propertySchema.nullable === this.config.Ts.Keyword.Undefined ? isRequired : !propertySchema.nullable;
1477
+ return isRequired;
1478
+ };
1479
+ this.isNullMissingInType = (schema, type$1) => {
1480
+ const { nullable, type: schemaType } = schema || {};
1481
+ return (nullable || !!lodash.default.get(schema, "x-nullable") || schemaType === this.config.Ts.Keyword.Null) && typeof type$1 === "string" && !type$1.includes(` ${this.config.Ts.Keyword.Null}`) && !type$1.includes(`${this.config.Ts.Keyword.Null} `);
1482
+ };
1483
+ this.safeAddNullToType = (schema, type$1) => {
1484
+ if (this.isNullMissingInType(schema, type$1)) return this.config.Ts.UnionType([type$1, this.config.Ts.Keyword.Null]);
1485
+ return type$1;
1486
+ };
1487
+ this.getSchemaPrimitiveType = (rawSchema) => {
1488
+ const schema = rawSchema || {};
1489
+ if (schema.type) return internalCase(schema.type);
1490
+ if (schema.enum) {
1491
+ const enumFieldType = typeof schema.enum[0];
1492
+ if (enumFieldType === this.config.Ts.Keyword.Undefined) return;
1493
+ return internalCase(enumFieldType);
1494
+ }
1495
+ if (lodash.default.keys(schema.properties).length) return SCHEMA_TYPES.OBJECT;
1496
+ if (schema.items) return SCHEMA_TYPES.ARRAY;
1497
+ return null;
1498
+ };
1499
+ this.checkAndAddRequiredKeys = (schema, resultType) => {
1500
+ if ("$$requiredKeys" in schema && schema.$$requiredKeys.length) {
1501
+ this.config.update({ internalTemplateOptions: { addUtilRequiredKeysType: true } });
1502
+ return this.config.Ts.TypeWithGeneric(this.config.Ts.CodeGenKeyword.UtilRequiredKeys, [resultType, this.config.Ts.UnionType(schema.$$requiredKeys.map(this.config.Ts.StringValue))]);
1503
+ }
1504
+ return resultType;
1505
+ };
1506
+ this.makeAddRequiredToChildSchema = (parentSchema, childSchema) => {
1507
+ if (!childSchema) return childSchema;
1508
+ const required = lodash.default.uniq([...this.getRequiredProperties(parentSchema), ...this.getRequiredProperties(childSchema)]);
1509
+ const refData = this.getSchemaRefType(childSchema);
1510
+ if (refData) {
1511
+ const refObjectProperties = lodash.default.keys(refData.rawTypeData?.properties || {});
1512
+ const existedRequiredKeys = refObjectProperties.filter((key) => required.includes(key));
1513
+ if (!existedRequiredKeys.length) return childSchema;
1514
+ return {
1515
+ ...childSchema,
1516
+ $$requiredKeys: existedRequiredKeys
1517
+ };
1518
+ }
1519
+ if (childSchema.properties) {
1520
+ const childSchemaProperties = lodash.default.keys(childSchema.properties);
1521
+ const existedRequiredKeys = childSchemaProperties.filter((key) => required.includes(key));
1522
+ if (!existedRequiredKeys.length) return childSchema;
1523
+ return {
1524
+ required: lodash.default.uniq([...this.getRequiredProperties(childSchema), ...existedRequiredKeys]),
1525
+ ...childSchema
1526
+ };
1527
+ }
1528
+ return childSchema;
1529
+ };
1530
+ this.filterSchemaContents = (contents, filterFn) => {
1531
+ return lodash.default.uniq(contents.filter((type$1) => filterFn(type$1)));
1532
+ };
1533
+ this.resolveTypeName = (typeName, { suffixes, resolver, prefixes, shouldReserve = true }) => {
1534
+ if (resolver) return this.config.componentTypeNameResolver.resolve([], (reserved) => {
1535
+ return resolver(pascalCase(typeName), reserved);
1536
+ });
1537
+ return this.config.componentTypeNameResolver.resolve([...(prefixes || []).map((prefix) => pascalCase(`${prefix} ${typeName}`)), ...(suffixes || []).map((suffix) => pascalCase(`${typeName} ${suffix}`))], shouldReserve);
1538
+ };
1539
+ this.getComplexType = (schema) => {
1540
+ if (schema.oneOf) return SCHEMA_TYPES.COMPLEX_ONE_OF;
1541
+ if (schema.allOf) return SCHEMA_TYPES.COMPLEX_ALL_OF;
1542
+ if (schema.anyOf) return SCHEMA_TYPES.COMPLEX_ANY_OF;
1543
+ if (schema.not) return SCHEMA_TYPES.COMPLEX_NOT;
1544
+ return SCHEMA_TYPES.COMPLEX_UNKNOWN;
1545
+ };
1546
+ this.getInternalSchemaType = (schema) => {
1547
+ if (!lodash.default.isEmpty(schema.enum) || !lodash.default.isEmpty(this.getEnumNames(schema))) return SCHEMA_TYPES.ENUM;
1548
+ if (schema.discriminator) return SCHEMA_TYPES.DISCRIMINATOR;
1549
+ if (schema.allOf || schema.oneOf || schema.anyOf || schema.not) return SCHEMA_TYPES.COMPLEX;
1550
+ if (!lodash.default.isEmpty(schema.properties)) return SCHEMA_TYPES.OBJECT;
1551
+ if (schema.type === SCHEMA_TYPES.ARRAY) return SCHEMA_TYPES.ARRAY;
1552
+ return SCHEMA_TYPES.PRIMITIVE;
1553
+ };
1554
+ this.getSchemaType = (schema) => {
1555
+ if (!schema) return this.config.Ts.Keyword.Any;
1556
+ const refTypeInfo = this.getSchemaRefType(schema);
1557
+ if (refTypeInfo) return this.checkAndAddRequiredKeys(schema, this.safeAddNullToType(schema, this.typeNameFormatter.format(refTypeInfo.typeName)));
1558
+ let resultType;
1559
+ if (this.isConstantSchema(schema)) resultType = this.formatJsValue(schema.const);
1560
+ else {
1561
+ const primitiveType = this.getSchemaPrimitiveType(schema);
1562
+ if (primitiveType == null) return this.config.Ts.Keyword.Any;
1563
+ const typeAlias = lodash.default.get(this.config.primitiveTypes, [primitiveType, schema.format]) || lodash.default.get(this.config.primitiveTypes, [primitiveType, "$default"]) || this.config.primitiveTypes[primitiveType];
1564
+ if (typeof typeAlias === "function") resultType = typeAlias(schema, this);
1565
+ else resultType = typeAlias || primitiveType;
1566
+ }
1567
+ if (!resultType) return this.config.Ts.Keyword.Any;
1568
+ return this.checkAndAddRequiredKeys(schema, this.safeAddNullToType(schema, resultType));
1569
+ };
1570
+ this.buildTypeNameFromPath = (schemaPath) => {
1571
+ schemaPath = lodash.default.uniq(lodash.default.compact(schemaPath));
1572
+ if (!schemaPath || !schemaPath[0]) return null;
1573
+ return pascalCase(lodash.default.camelCase(lodash.default.uniq([schemaPath[0], schemaPath[schemaPath.length - 1]]).join("_")));
1574
+ };
1575
+ this.formatJsValue = (value) => {
1576
+ switch (typeof value) {
1577
+ case "string": return this.config.Ts.StringValue(value);
1578
+ case "boolean": return this.config.Ts.BooleanValue(value);
1579
+ case "number": return this.config.Ts.NumberValue(value);
1580
+ default: {
1581
+ if (value === null) return this.config.Ts.NullValue(value);
1582
+ return this.config.Ts.Keyword.Any;
1583
+ }
1584
+ }
1585
+ };
1586
+ this.config = config;
1587
+ this.schemaComponentsMap = schemaComponentsMap;
1588
+ this.typeNameFormatter = typeNameFormatter;
1589
+ this.schemaWalker = schemaWalker;
1590
+ }
1591
+ isConstantSchema(schema) {
1592
+ return "const" in schema;
1593
+ }
1594
+ };
1595
+
1596
+ //#endregion
1597
+ //#region src/schema-parser/schema-parser-fabric.ts
1598
+ var SchemaParserFabric = class {
1599
+ constructor(config, templatesWorker, schemaComponentsMap, typeNameFormatter, schemaWalker) {
1600
+ this.createSchemaParser = ({ schema, typeName, schemaPath }) => {
1601
+ return new SchemaParser(this, {
1602
+ schema,
1603
+ typeName,
1604
+ schemaPath
1605
+ });
1606
+ };
1607
+ this.createSchema = ({ content, linkedSchema = {}, linkedComponent, schemaPath,...otherSchemaProps }) => {
1608
+ const parser = this.createSchemaParser({
1609
+ schema: linkedComponent || linkedSchema,
1610
+ schemaPath
1611
+ });
1612
+ const parsed = parser.parseSchema();
1613
+ parsed.content = content;
1614
+ Object.assign(parsed, otherSchemaProps);
1615
+ if (linkedComponent) linkedComponent.typeData = parsed;
1616
+ return parser.schema;
1617
+ };
1618
+ this.createParsedComponent = ({ typeName, schema, schemaPath }) => {
1619
+ const schemaCopy = structuredClone(schema);
1620
+ const customComponent = this.schemaComponentsMap.createComponent(this.schemaComponentsMap.createRef([
1621
+ "components",
1622
+ "schemas",
1623
+ typeName
1624
+ ]), schemaCopy);
1625
+ const parsed = this.parseSchema(schemaCopy, null, schemaPath);
1626
+ parsed.name = typeName;
1627
+ customComponent.typeData = parsed;
1628
+ return customComponent;
1629
+ };
1630
+ this.parseSchema = (schema, typeName = null, schemaPath = []) => {
1631
+ const schemaParser = this.createSchemaParser({
1632
+ schema,
1633
+ typeName,
1634
+ schemaPath
1635
+ });
1636
+ return schemaParser.parseSchema();
1637
+ };
1638
+ this.getInlineParseContent = (schema, typeName, schemaPath) => {
1639
+ const parser = this.createSchemaParser({
1640
+ schema,
1641
+ typeName,
1642
+ schemaPath
1643
+ });
1644
+ return parser.getInlineParseContent();
1645
+ };
1646
+ this.getParseContent = (schema, typeName, schemaPath) => {
1647
+ const parser = this.createSchemaParser({
1648
+ schema,
1649
+ typeName,
1650
+ schemaPath
1651
+ });
1652
+ return parser.getParseContent();
1653
+ };
1654
+ this.config = config;
1655
+ this.schemaComponentsMap = schemaComponentsMap;
1656
+ this.typeNameFormatter = typeNameFormatter;
1657
+ this.templatesWorker = templatesWorker;
1658
+ this.schemaWalker = schemaWalker;
1659
+ this.schemaUtils = new SchemaUtils(this);
1660
+ this.schemaFormatters = new SchemaFormatters(this);
1661
+ }
1662
+ };
1663
+
1664
+ //#endregion
1665
+ //#region src/util/id.ts
1666
+ const ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789";
1667
+ const generateId = nanoid.customAlphabet(ALPHABET, 12);
1668
+
1669
+ //#endregion
1670
+ //#region src/schema-routes/util/specific-arg-name-resolver.ts
1671
+ var SpecificArgNameResolver = class extends NameResolver {
1672
+ constructor(config, reservedNames) {
1673
+ super(config, reservedNames, (variants) => {
1674
+ const generatedVariant = variants[0] && `${variants[0]}${this.counter++}` || `${this.config.specificArgNameResolverName}${this.counter++}`;
1675
+ consola.consola.debug("generated fallback type name for specific arg - ", generatedVariant);
1676
+ return generatedVariant;
1677
+ });
1678
+ this.counter = 1;
1679
+ }
1680
+ };
1681
+
1682
+ //#endregion
1683
+ //#region src/schema-routes/schema-routes.ts
1684
+ const CONTENT_KIND = {
1685
+ JSON: "JSON",
1686
+ URL_ENCODED: "URL_ENCODED",
1687
+ FORM_DATA: "FORM_DATA",
1688
+ IMAGE: "IMAGE",
1689
+ OTHER: "OTHER",
1690
+ TEXT: "TEXT"
1691
+ };
1692
+ var SchemaRoutes = class {
1693
+ constructor(config, schemaParserFabric, schemaComponentsMap, templatesWorker, typeNameFormatter) {
1694
+ this.FORM_DATA_TYPES = [];
1695
+ this.routes = [];
1696
+ this.hasSecurityRoutes = false;
1697
+ this.hasQueryRoutes = false;
1698
+ this.hasFormDataRoutes = false;
1699
+ this.createRequestsMap = (routeInfoByMethodsMap) => {
1700
+ const parameters = lodash.default.get(routeInfoByMethodsMap, "parameters");
1701
+ return lodash.default.reduce(routeInfoByMethodsMap, (acc, requestInfo, method) => {
1702
+ if (method.startsWith("x-") || ["parameters", "$ref"].includes(method)) return acc;
1703
+ acc[method] = {
1704
+ ...requestInfo,
1705
+ parameters: lodash.default.compact(lodash.default.concat(parameters, requestInfo.parameters))
1706
+ };
1707
+ return acc;
1708
+ }, {});
1709
+ };
1710
+ this.parseRouteName = (originalRouteName) => {
1711
+ const routeName = this.config.hooks.onPreBuildRoutePath(originalRouteName) || originalRouteName;
1712
+ const pathParamMatches = (routeName || "").match(/({[\w[\\\]^`][-_.\w]*})|(:[\w[\\\]^`][-_.\w]*:?)/g);
1713
+ const pathParams = lodash.default.reduce(pathParamMatches, (pathParams$1, match) => {
1714
+ const paramName = match.replace(/\{|\}|:/g, "");
1715
+ if (!paramName) return pathParams$1;
1716
+ if (paramName.includes("-")) consola.consola.warn("wrong path param name", paramName);
1717
+ pathParams$1.push({
1718
+ $match: match,
1719
+ name: lodash.default.camelCase(paramName),
1720
+ required: true,
1721
+ type: "string",
1722
+ description: "",
1723
+ schema: { type: "string" },
1724
+ in: "path"
1725
+ });
1726
+ return pathParams$1;
1727
+ }, []);
1728
+ let fixedRoute = pathParams.reduce((fixedRoute$1, pathParam, i, arr) => {
1729
+ const insertion = this.config.hooks.onInsertPathParam(pathParam.name, i, arr, fixedRoute$1) || pathParam.name;
1730
+ return fixedRoute$1.replace(pathParam.$match, `\${${insertion}}`);
1731
+ }, routeName || "");
1732
+ const queryParamMatches = fixedRoute.match(/(\{\?.*\})/g);
1733
+ const queryParams = [];
1734
+ if (queryParamMatches?.length) {
1735
+ for (const match of queryParamMatches) fixedRoute = fixedRoute.replace(match, "");
1736
+ const paramNames = lodash.default.uniq(queryParamMatches.join(",").replace(/(\{\?)|(\})|\s/g, "").split(","));
1737
+ for (const paramName of paramNames) {
1738
+ if (paramName.includes("-")) consola.consola.warn("wrong query param name", paramName);
1739
+ queryParams.push({
1740
+ $match: paramName,
1741
+ name: lodash.default.camelCase(paramName),
1742
+ required: true,
1743
+ type: "string",
1744
+ description: "",
1745
+ schema: { type: "string" },
1746
+ in: "query"
1747
+ });
1748
+ }
1749
+ }
1750
+ const result = {
1751
+ originalRoute: originalRouteName || "",
1752
+ route: fixedRoute,
1753
+ pathParams,
1754
+ queryParams
1755
+ };
1756
+ return this.config.hooks.onBuildRoutePath(result) || result;
1757
+ };
1758
+ this.getRouteParams = (routeInfo, pathParamsFromRouteName, queryParamsFromRouteName) => {
1759
+ const { parameters } = routeInfo;
1760
+ const routeParams = {
1761
+ path: [],
1762
+ header: [],
1763
+ body: [],
1764
+ query: [],
1765
+ formData: [],
1766
+ cookie: []
1767
+ };
1768
+ lodash.default.each(parameters, (parameter) => {
1769
+ const refTypeInfo = this.schemaParserFabric.schemaUtils.getSchemaRefType(parameter);
1770
+ let routeParam = null;
1771
+ if (refTypeInfo?.rawTypeData.in && refTypeInfo.rawTypeData) {
1772
+ if (!routeParams[refTypeInfo.rawTypeData.in]) routeParams[refTypeInfo.rawTypeData.in] = [];
1773
+ routeParam = {
1774
+ ...refTypeInfo.rawTypeData,
1775
+ ...refTypeInfo.rawTypeData.schema || {}
1776
+ };
1777
+ } else {
1778
+ if (!parameter.in) return;
1779
+ if (!routeParams[parameter.in]) routeParams[parameter.in] = [];
1780
+ routeParam = {
1781
+ ...parameter,
1782
+ ...parameter.schema || {}
1783
+ };
1784
+ }
1785
+ if (routeParam.in === "path") {
1786
+ if (!routeParam.name) return;
1787
+ routeParam.name = lodash.default.camelCase(routeParam.name);
1788
+ }
1789
+ if (routeParam) routeParams[routeParam.in].push(routeParam);
1790
+ });
1791
+ for (const pathParam of pathParamsFromRouteName) {
1792
+ const alreadyExist = routeParams.path.some((parameter) => parameter.name === pathParam.name);
1793
+ if (!alreadyExist) routeParams.path.push(pathParam);
1794
+ }
1795
+ for (const queryParam of queryParamsFromRouteName) {
1796
+ const alreadyExist = routeParams.query.some((parameter) => parameter.name === queryParam.name);
1797
+ if (!alreadyExist) routeParams.query.push(queryParam);
1798
+ }
1799
+ return routeParams;
1800
+ };
1801
+ this.getContentTypes = (requestInfo, extraContentTypes) => lodash.default.uniq(lodash.default.compact([...extraContentTypes || [], ...lodash.default.flatten(lodash.default.map(requestInfo, (requestInfoData) => requestInfoData && lodash.default.keys(requestInfoData.content)))]));
1802
+ this.getContentKind = (contentTypes) => {
1803
+ if (contentTypes.some((contentType) => contentType.startsWith("application/json")) || contentTypes.some((contentType) => contentType.endsWith("+json"))) return CONTENT_KIND.JSON;
1804
+ if (contentTypes.includes("application/x-www-form-urlencoded")) return CONTENT_KIND.URL_ENCODED;
1805
+ if (contentTypes.includes("multipart/form-data")) return CONTENT_KIND.FORM_DATA;
1806
+ if (contentTypes.some((contentType) => contentType.includes("image/"))) return CONTENT_KIND.IMAGE;
1807
+ if (contentTypes.some((contentType) => contentType.startsWith("text/"))) return CONTENT_KIND.TEXT;
1808
+ return CONTENT_KIND.OTHER;
1809
+ };
1810
+ this.isSuccessStatus = (status) => this.config.defaultResponseAsSuccess && status === "default" || +status >= this.config.successResponseStatusRange[0] && +status <= this.config.successResponseStatusRange[1] || status === "2xx";
1811
+ this.getSchemaFromRequestType = (requestInfo) => {
1812
+ const content = lodash.default.get(requestInfo, "content");
1813
+ if (!content) return null;
1814
+ for (const dataType in content) if (content[dataType]?.schema) return {
1815
+ ...content[dataType].schema,
1816
+ dataType
1817
+ };
1818
+ return null;
1819
+ };
1820
+ this.getTypeFromRequestInfo = ({ requestInfo, parsedSchemas, operationId, defaultType, typeName }) => {
1821
+ const schema = this.getSchemaFromRequestType(requestInfo);
1822
+ const refTypeInfo = this.schemaParserFabric.schemaUtils.getSchemaRefType(requestInfo);
1823
+ if (schema) {
1824
+ const content = this.schemaParserFabric.getInlineParseContent(schema, typeName, [operationId]);
1825
+ const foundedSchemaByName = parsedSchemas.find((parsedSchema) => this.typeNameFormatter.format(parsedSchema.name) === content);
1826
+ const foundSchemaByContent = parsedSchemas.find((parsedSchema) => lodash.default.isEqual(parsedSchema.content, content));
1827
+ const foundSchema = foundedSchemaByName || foundSchemaByContent;
1828
+ return foundSchema ? this.typeNameFormatter.format(foundSchema.name) : content;
1829
+ }
1830
+ if (refTypeInfo) {
1831
+ const typeNameWithoutOpId = refTypeInfo.typeName.replace(operationId, "");
1832
+ if (parsedSchemas.find((schema$1) => schema$1.name === typeNameWithoutOpId)) return this.typeNameFormatter.format(typeNameWithoutOpId);
1833
+ switch (refTypeInfo.componentName) {
1834
+ case "schemas": return this.typeNameFormatter.format(refTypeInfo.typeName);
1835
+ case "responses":
1836
+ case "requestBodies": return this.schemaParserFabric.getInlineParseContent(this.getSchemaFromRequestType(refTypeInfo.rawTypeData), refTypeInfo.typeName || null, [operationId]);
1837
+ default: return this.schemaParserFabric.getInlineParseContent(refTypeInfo.rawTypeData, refTypeInfo.typeName || null, [operationId]);
1838
+ }
1839
+ }
1840
+ return defaultType || this.config.Ts.Keyword.Any;
1841
+ };
1842
+ this.getRequestInfoTypes = ({ requestInfos, parsedSchemas, operationId, defaultType }) => lodash.default.reduce(requestInfos, (acc, requestInfo, status) => {
1843
+ const contentTypes = this.getContentTypes([requestInfo]);
1844
+ return [...acc, {
1845
+ ...requestInfo || {},
1846
+ contentTypes,
1847
+ contentKind: this.getContentKind(contentTypes),
1848
+ type: this.schemaParserFabric.schemaUtils.safeAddNullToType(
1849
+ requestInfo,
1850
+ // @ts-expect-error TS(2345) FIXME: Argument of type '{ requestInfo: any; parsedSchema... Remove this comment to see the full error message
1851
+ this.getTypeFromRequestInfo({
1852
+ requestInfo,
1853
+ parsedSchemas,
1854
+ operationId,
1855
+ defaultType
1856
+ })
1857
+ ),
1858
+ description: this.schemaParserFabric.schemaFormatters.formatDescription(requestInfo.description || "", true),
1859
+ status: Number.isNaN(+status) ? status : +status,
1860
+ isSuccess: this.isSuccessStatus(status)
1861
+ }];
1862
+ }, []);
1863
+ this.getResponseBodyInfo = (routeInfo, parsedSchemas) => {
1864
+ const { produces, operationId, responses } = routeInfo;
1865
+ const contentTypes = this.getContentTypes(responses, [...produces || [], routeInfo["x-accepts"]]);
1866
+ const responseInfos = this.getRequestInfoTypes({
1867
+ requestInfos: responses,
1868
+ parsedSchemas,
1869
+ operationId,
1870
+ defaultType: this.config.defaultResponseType
1871
+ });
1872
+ const successResponse = responseInfos.find((response) => response.isSuccess);
1873
+ const errorResponses = responseInfos.filter((response) => !response.isSuccess && response.type !== this.config.Ts.Keyword.Any);
1874
+ const handleResponseHeaders = (src) => {
1875
+ if (!src) return "headers: {},";
1876
+ const headerTypes = Object.fromEntries(Object.entries(src).map(([k, v]) => {
1877
+ return [k, this.schemaUtils.getSchemaType(v)];
1878
+ }));
1879
+ const r = `headers: { ${Object.entries(headerTypes).map(([k, v]) => `"${k}": ${v}`).join(",")} },`;
1880
+ return r;
1881
+ };
1882
+ return {
1883
+ contentTypes,
1884
+ responses: responseInfos,
1885
+ success: {
1886
+ schema: successResponse,
1887
+ type: successResponse?.type || this.config.Ts.Keyword.Any
1888
+ },
1889
+ error: {
1890
+ schemas: errorResponses,
1891
+ type: this.config.Ts.UnionType(errorResponses.map((response) => response.type)) || this.config.Ts.Keyword.Any
1892
+ },
1893
+ full: { types: this.config.Ts.UnionType(responseInfos.map((response) => `{
1894
+ data: ${response.type}, status: ${response.status}, statusCode: ${response.status}, statusText: "${response.description}", ${handleResponseHeaders(response.headers)} config: {} }`)) || this.config.Ts.Keyword.Any }
1895
+ };
1896
+ };
1897
+ this.convertRouteParamsIntoObject = (params) => {
1898
+ return params.reduce((objectSchema, schemaPart) => {
1899
+ if (!schemaPart || !schemaPart.name) return objectSchema;
1900
+ return {
1901
+ ...objectSchema,
1902
+ properties: {
1903
+ ...objectSchema.properties,
1904
+ [schemaPart.name]: {
1905
+ ...schemaPart,
1906
+ ...schemaPart.schema || {}
1907
+ }
1908
+ }
1909
+ };
1910
+ }, {
1911
+ properties: {},
1912
+ type: "object"
1913
+ });
1914
+ };
1915
+ this.getRequestBodyInfo = (routeInfo, routeParams, parsedSchemas, routeName) => {
1916
+ const { requestBody, consumes, requestBodyName, operationId } = routeInfo;
1917
+ let schema = null;
1918
+ let content = null;
1919
+ const contentTypes = this.getContentTypes([requestBody], [...consumes || [], routeInfo["x-contentType"]]);
1920
+ let contentKind = this.getContentKind(contentTypes);
1921
+ let typeName = null;
1922
+ if (this.config.extractRequestBody) typeName = this.schemaUtils.resolveTypeName(routeName.usage, {
1923
+ suffixes: this.config.extractingOptions.requestBodySuffix,
1924
+ resolver: this.config.extractingOptions.requestBodyNameResolver
1925
+ });
1926
+ if (routeParams.formData.length) {
1927
+ contentKind = CONTENT_KIND.FORM_DATA;
1928
+ schema = this.convertRouteParamsIntoObject(routeParams.formData);
1929
+ content = this.schemaParserFabric.getInlineParseContent(schema, typeName, [operationId]);
1930
+ } else if (contentKind === CONTENT_KIND.FORM_DATA) {
1931
+ schema = this.getSchemaFromRequestType(requestBody);
1932
+ content = this.schemaParserFabric.getInlineParseContent(schema, typeName, [operationId]);
1933
+ } else if (requestBody) {
1934
+ schema = this.getSchemaFromRequestType(requestBody);
1935
+ content = this.schemaParserFabric.schemaUtils.safeAddNullToType(
1936
+ requestBody,
1937
+ // @ts-expect-error TS(2345) FIXME: Argument of type '{ requestInfo: any; parsedSchema... Remove this comment to see the full error message
1938
+ this.getTypeFromRequestInfo({
1939
+ requestInfo: requestBody,
1940
+ parsedSchemas,
1941
+ operationId,
1942
+ typeName
1943
+ })
1944
+ );
1945
+ if (this.FORM_DATA_TYPES.some((dataType) => content.includes(`: ${dataType}`))) contentKind = CONTENT_KIND.FORM_DATA;
1946
+ }
1947
+ if (schema && !schema.$ref && this.config.extractRequestBody) {
1948
+ schema = this.schemaParserFabric.createParsedComponent({
1949
+ schema,
1950
+ typeName,
1951
+ schemaPath: [operationId]
1952
+ });
1953
+ if (schema?.typeData) schema.typeData.isExtractedRequestBody = true;
1954
+ content = this.schemaParserFabric.getInlineParseContent({ $ref: schema.$ref });
1955
+ }
1956
+ return {
1957
+ paramName: requestBodyName || requestBody?.name || DEFAULT_BODY_ARG_NAME,
1958
+ contentTypes,
1959
+ contentKind,
1960
+ schema,
1961
+ type: content,
1962
+ required: requestBody && (typeof requestBody.required === "undefined" || !!requestBody.required)
1963
+ };
1964
+ };
1965
+ this.createRequestParamsSchema = ({ queryParams, queryObjectSchema, pathArgsSchemas, extractRequestParams, routeName }) => {
1966
+ if (!queryParams || !queryParams.length) return null;
1967
+ const pathParams = pathArgsSchemas.reduce((acc, pathArgSchema) => {
1968
+ if (pathArgSchema.name) acc[pathArgSchema.name] = {
1969
+ ...pathArgSchema,
1970
+ in: "path"
1971
+ };
1972
+ return acc;
1973
+ }, {});
1974
+ const fixedQueryParams = lodash.default.reduce(lodash.default.get(queryObjectSchema, "properties", {}), (acc, property, name$1) => {
1975
+ if (name$1 && typeof property === "object") acc[name$1] = {
1976
+ ...property,
1977
+ in: "query"
1978
+ };
1979
+ return acc;
1980
+ }, {});
1981
+ const schema = {
1982
+ ...queryObjectSchema,
1983
+ properties: {
1984
+ ...fixedQueryParams,
1985
+ ...pathParams
1986
+ }
1987
+ };
1988
+ const fixedSchema = this.config.hooks.onCreateRequestParams(schema);
1989
+ if (fixedSchema) return fixedSchema;
1990
+ if (extractRequestParams) {
1991
+ const generatedTypeName = this.schemaUtils.resolveTypeName(routeName.usage, {
1992
+ suffixes: this.config.extractingOptions.requestParamsSuffix,
1993
+ resolver: this.config.extractingOptions.requestParamsNameResolver
1994
+ });
1995
+ const component = this.schemaParserFabric.createParsedComponent({
1996
+ typeName: generatedTypeName,
1997
+ schema
1998
+ });
1999
+ if (component.typeData) component.typeData.isExtractedRequestParams = true;
2000
+ return component;
2001
+ }
2002
+ return schema;
2003
+ };
2004
+ this.extractResponseBodyIfItNeeded = (routeInfo, responseBodyInfo, routeName) => {
2005
+ if (responseBodyInfo.responses.length && responseBodyInfo.success && responseBodyInfo.success.schema) {
2006
+ const typeName = this.schemaUtils.resolveTypeName(routeName.usage, {
2007
+ suffixes: this.config.extractingOptions.responseBodySuffix,
2008
+ resolver: this.config.extractingOptions.responseBodyNameResolver
2009
+ });
2010
+ const idx = responseBodyInfo.responses.indexOf(responseBodyInfo.success.schema);
2011
+ const successResponse = responseBodyInfo.success;
2012
+ if (successResponse.schema && !successResponse.schema.$ref) {
2013
+ const contentKind = successResponse.schema.contentKind;
2014
+ const schema = this.getSchemaFromRequestType(successResponse.schema);
2015
+ successResponse.schema = this.schemaParserFabric.createParsedComponent({
2016
+ schema,
2017
+ typeName,
2018
+ schemaPath: [routeInfo.operationId]
2019
+ });
2020
+ successResponse.schema.contentKind = contentKind;
2021
+ if (successResponse.schema.typeData) successResponse.schema.typeData.isExtractedResponseBody = true;
2022
+ successResponse.type = this.schemaParserFabric.getInlineParseContent({ $ref: successResponse.schema.$ref });
2023
+ if (idx > -1) lodash.default.assign(responseBodyInfo.responses[idx], {
2024
+ ...successResponse.schema,
2025
+ type: successResponse.type
2026
+ });
2027
+ }
2028
+ }
2029
+ };
2030
+ this.extractResponseErrorIfItNeeded = (routeInfo, responseBodyInfo, routeName) => {
2031
+ if (responseBodyInfo.responses.length && responseBodyInfo.error.schemas && responseBodyInfo.error.schemas.length) {
2032
+ const typeName = this.schemaUtils.resolveTypeName(routeName.usage, {
2033
+ suffixes: this.config.extractingOptions.responseErrorSuffix,
2034
+ resolver: this.config.extractingOptions.responseErrorNameResolver
2035
+ });
2036
+ const errorSchemas = responseBodyInfo.error.schemas.map(this.getSchemaFromRequestType).filter(Boolean);
2037
+ if (!errorSchemas.length) return;
2038
+ const schema = this.schemaParserFabric.parseSchema({
2039
+ oneOf: errorSchemas,
2040
+ title: errorSchemas.map((schema$1) => schema$1.title).filter(Boolean).join(" "),
2041
+ description: errorSchemas.map((schema$1) => schema$1.description).filter(Boolean).join("\n")
2042
+ }, null, [routeInfo.operationId]);
2043
+ const component = this.schemaComponentsMap.createComponent(this.schemaComponentsMap.createRef([
2044
+ "components",
2045
+ "schemas",
2046
+ typeName
2047
+ ]), { ...schema });
2048
+ responseBodyInfo.error.schemas = [component];
2049
+ if (component.typeData) component.typeData.isExtractedResponseError = true;
2050
+ responseBodyInfo.error.type = this.typeNameFormatter.format(component.typeName);
2051
+ }
2052
+ };
2053
+ this.getRouteName = (rawRouteInfo) => {
2054
+ const { moduleName } = rawRouteInfo;
2055
+ const { routeNameDuplicatesMap, templatesToRender } = this.config;
2056
+ const routeNameTemplate = templatesToRender.routeName;
2057
+ const routeNameFromTemplate = this.templatesWorker.renderTemplate(routeNameTemplate, { routeInfo: rawRouteInfo });
2058
+ const routeName = this.config.hooks.onFormatRouteName(rawRouteInfo, routeNameFromTemplate) || routeNameFromTemplate;
2059
+ const duplicateIdentifier = `${moduleName}|${routeName}`;
2060
+ if (routeNameDuplicatesMap.has(duplicateIdentifier)) {
2061
+ routeNameDuplicatesMap.set(duplicateIdentifier, routeNameDuplicatesMap.get(duplicateIdentifier) + 1);
2062
+ consola.consola.warn(`Module "${moduleName}" already has method "${routeName}()".`, `This method has been renamed to "${routeName + routeNameDuplicatesMap.get(duplicateIdentifier)}()" to solve conflict names.`);
2063
+ } else routeNameDuplicatesMap.set(duplicateIdentifier, 1);
2064
+ const duplicates = routeNameDuplicatesMap.get(duplicateIdentifier);
2065
+ const routeNameInfo = {
2066
+ usage: routeName + (duplicates > 1 ? duplicates : ""),
2067
+ original: routeName,
2068
+ duplicate: duplicates > 1
2069
+ };
2070
+ return this.config.hooks.onCreateRouteName(routeNameInfo, rawRouteInfo) || routeNameInfo;
2071
+ };
2072
+ this.parseRouteInfo = (rawRouteName, routeInfo, method, usageSchema, parsedSchemas) => {
2073
+ const { security: globalSecurity } = usageSchema;
2074
+ const { moduleNameIndex, moduleNameFirstTag, extractRequestParams } = this.config;
2075
+ const { operationId, requestBody, security, parameters, summary, description: description$1, tags, responses, requestBodyName, produces, consumes,...otherInfo } = routeInfo;
2076
+ const { route, pathParams: pathParamsFromRouteName, queryParams: queryParamsFromRouteName } = this.parseRouteName(rawRouteName);
2077
+ const routeId = generateId();
2078
+ const firstTag = tags && tags.length > 0 ? tags[0] : null;
2079
+ const moduleName = moduleNameFirstTag && firstTag ? lodash.default.camelCase(firstTag) : lodash.default.camelCase(lodash.default.compact(route.split("/"))[moduleNameIndex]);
2080
+ let hasSecurity = !!globalSecurity?.length;
2081
+ if (security) hasSecurity = security.length > 0;
2082
+ const routeParams = this.getRouteParams(routeInfo, pathParamsFromRouteName, queryParamsFromRouteName);
2083
+ const pathArgs = routeParams.path.map((pathArgSchema) => ({
2084
+ name: pathArgSchema.name,
2085
+ optional: !pathArgSchema.required,
2086
+ type: this.config.Ts.Keyword.Any,
2087
+ description: pathArgSchema.description
2088
+ }));
2089
+ const pathArgsNames = pathArgs.map((arg) => arg.name);
2090
+ const responseBodyInfo = this.getResponseBodyInfo(routeInfo, parsedSchemas);
2091
+ const rawRouteInfo = {
2092
+ ...otherInfo,
2093
+ pathArgs,
2094
+ operationId,
2095
+ method,
2096
+ route: rawRouteName,
2097
+ moduleName,
2098
+ responsesTypes: responseBodyInfo.responses,
2099
+ description: description$1,
2100
+ tags,
2101
+ summary,
2102
+ responses,
2103
+ produces,
2104
+ requestBody,
2105
+ consumes,
2106
+ security
2107
+ };
2108
+ const queryObjectSchema = this.convertRouteParamsIntoObject(routeParams.query);
2109
+ const pathObjectSchema = this.convertRouteParamsIntoObject(routeParams.path);
2110
+ const headersObjectSchema = this.convertRouteParamsIntoObject(routeParams.header);
2111
+ const routeName = this.getRouteName(rawRouteInfo);
2112
+ const requestBodyInfo = this.getRequestBodyInfo(routeInfo, routeParams, parsedSchemas, routeName);
2113
+ const requestParamsSchema = this.createRequestParamsSchema({
2114
+ queryParams: routeParams.query,
2115
+ pathArgsSchemas: routeParams.path,
2116
+ queryObjectSchema,
2117
+ extractRequestParams,
2118
+ routeName
2119
+ });
2120
+ if (this.config.extractResponseBody) this.extractResponseBodyIfItNeeded(routeInfo, responseBodyInfo, routeName);
2121
+ if (this.config.extractResponseError) this.extractResponseErrorIfItNeeded(routeInfo, responseBodyInfo, routeName);
2122
+ const typeName = this.schemaUtils.resolveTypeName(routeName.usage, {
2123
+ suffixes: this.config.extractingOptions.requestParamsSuffix,
2124
+ resolver: this.config.extractingOptions.requestParamsNameResolver,
2125
+ shouldReserve: false
2126
+ });
2127
+ const queryType = routeParams.query.length ? this.schemaParserFabric.getInlineParseContent(queryObjectSchema, null, [typeName]) : null;
2128
+ const pathType = routeParams.path.length ? this.schemaParserFabric.getInlineParseContent(pathObjectSchema, null, [typeName]) : null;
2129
+ const headersType = routeParams.header.length ? this.schemaParserFabric.getInlineParseContent(headersObjectSchema, null, [typeName]) : null;
2130
+ const nameResolver = new SpecificArgNameResolver(this.config, pathArgsNames);
2131
+ const specificArgs = {
2132
+ query: queryType ? {
2133
+ name: nameResolver.resolve(RESERVED_QUERY_ARG_NAMES),
2134
+ optional: this.schemaParserFabric.parseSchema(queryObjectSchema, null, [routeName.usage]).allFieldsAreOptional,
2135
+ type: queryType
2136
+ } : void 0,
2137
+ body: requestBodyInfo.type ? {
2138
+ name: nameResolver.resolve([requestBodyInfo.paramName, ...RESERVED_BODY_ARG_NAMES]),
2139
+ optional: !requestBodyInfo.required,
2140
+ type: requestBodyInfo.type
2141
+ } : void 0,
2142
+ pathParams: pathType ? {
2143
+ name: nameResolver.resolve(RESERVED_PATH_ARG_NAMES),
2144
+ optional: this.schemaParserFabric.parseSchema(pathObjectSchema, null, [routeName.usage]).allFieldsAreOptional,
2145
+ type: pathType
2146
+ } : void 0,
2147
+ headers: headersType ? {
2148
+ name: nameResolver.resolve(RESERVED_HEADER_ARG_NAMES),
2149
+ optional: this.schemaParserFabric.parseSchema(headersObjectSchema, null, [routeName.usage]).allFieldsAreOptional,
2150
+ type: headersType
2151
+ } : void 0
2152
+ };
2153
+ pathArgs.forEach((pathArg, i) => {
2154
+ pathArg.type = this.schemaParserFabric.getInlineParseContent(routeParams.path[i].schema, null, [typeName]);
2155
+ });
2156
+ return {
2157
+ id: routeId,
2158
+ namespace: moduleName.replace(/^(\d)/, "v$1"),
2159
+ routeName,
2160
+ routeParams,
2161
+ requestBodyInfo,
2162
+ responseBodyInfo,
2163
+ specificArgs,
2164
+ queryObjectSchema,
2165
+ pathObjectSchema,
2166
+ headersObjectSchema,
2167
+ responseBodySchema: responseBodyInfo.success.schema,
2168
+ requestBodySchema: requestBodyInfo.schema,
2169
+ specificArgNameResolver: nameResolver,
2170
+ request: {
2171
+ contentTypes: requestBodyInfo.contentTypes,
2172
+ parameters: pathArgs,
2173
+ path: route,
2174
+ formData: requestBodyInfo.contentKind === CONTENT_KIND.FORM_DATA,
2175
+ isQueryBody: requestBodyInfo.contentKind === CONTENT_KIND.URL_ENCODED,
2176
+ security: hasSecurity,
2177
+ method,
2178
+ requestParams: requestParamsSchema,
2179
+ payload: specificArgs.body,
2180
+ query: specificArgs.query,
2181
+ pathParams: specificArgs.pathParams,
2182
+ headers: specificArgs.headers
2183
+ },
2184
+ response: {
2185
+ contentTypes: responseBodyInfo.contentTypes,
2186
+ type: responseBodyInfo.success.type,
2187
+ errorType: responseBodyInfo.error.type,
2188
+ fullTypes: responseBodyInfo.full.types
2189
+ },
2190
+ raw: rawRouteInfo
2191
+ };
2192
+ };
2193
+ this.attachSchema = ({ usageSchema, parsedSchemas }) => {
2194
+ this.config.routeNameDuplicatesMap.clear();
2195
+ const pathsEntries = lodash.default.entries(usageSchema.paths);
2196
+ for (const [rawRouteName, routeInfoByMethodsMap] of pathsEntries) {
2197
+ const routeInfosMap = this.createRequestsMap(routeInfoByMethodsMap);
2198
+ for (const [method, routeInfo] of Object.entries(routeInfosMap)) {
2199
+ const parsedRouteInfo = this.parseRouteInfo(rawRouteName, routeInfo, method, usageSchema, parsedSchemas);
2200
+ const processedRouteInfo = this.config.hooks.onCreateRoute(parsedRouteInfo);
2201
+ if (processedRouteInfo !== false) {
2202
+ const route = processedRouteInfo || parsedRouteInfo;
2203
+ if (!this.hasSecurityRoutes && route.security) this.hasSecurityRoutes = route.security;
2204
+ if (!this.hasQueryRoutes && route.hasQuery) this.hasQueryRoutes = route.hasQuery;
2205
+ if (!this.hasFormDataRoutes && route.hasFormDataParams) this.hasFormDataRoutes = route.hasFormDataParams;
2206
+ this.routes.push(route);
2207
+ }
2208
+ }
2209
+ }
2210
+ };
2211
+ this.getGroupedRoutes = () => {
2212
+ const groupedRoutes = this.routes.reduce((modules, route) => {
2213
+ if (route.namespace) {
2214
+ if (!modules[route.namespace]) modules[route.namespace] = [];
2215
+ modules[route.namespace].push(route);
2216
+ } else modules.$outOfModule.push(route);
2217
+ return modules;
2218
+ }, { $outOfModule: [] });
2219
+ const routeGroups = lodash.default.reduce(groupedRoutes, (acc, routesGroup, moduleName) => {
2220
+ if (moduleName === "$outOfModule") acc.outOfModule = routesGroup;
2221
+ else {
2222
+ if (!acc.combined) acc.combined = [];
2223
+ acc.combined.push({
2224
+ moduleName,
2225
+ routes: routesGroup.map((route) => {
2226
+ const { original: originalName, usage: usageName } = route.routeName;
2227
+ if (routesGroup.length > 1 && usageName !== originalName && !routesGroup.some(({ routeName, id }) => id !== route.id && originalName === routeName.original)) return {
2228
+ ...route,
2229
+ routeName: {
2230
+ ...route.routeName,
2231
+ usage: originalName
2232
+ }
2233
+ };
2234
+ return route;
2235
+ })
2236
+ });
2237
+ }
2238
+ return acc;
2239
+ }, {});
2240
+ if (this.config.sortRoutes) {
2241
+ if (routeGroups.outOfModule) routeGroups.outOfModule = this.sortRoutes(routeGroups.outOfModule);
2242
+ if (routeGroups.combined) lodash.default.each(routeGroups.combined, (routeGroup) => {
2243
+ routeGroup.routes = this.sortRoutes(routeGroup.routes);
2244
+ });
2245
+ }
2246
+ return routeGroups;
2247
+ };
2248
+ this.sortRoutes = (routes) => {
2249
+ return lodash.default.slice(routes).sort((routeA, routeB) => routeA.routeName.usage.localeCompare(routeB.routeName.usage));
2250
+ };
2251
+ this.config = config;
2252
+ this.schemaParserFabric = schemaParserFabric;
2253
+ this.schemaUtils = this.schemaParserFabric.schemaUtils;
2254
+ this.typeNameFormatter = typeNameFormatter;
2255
+ this.schemaComponentsMap = schemaComponentsMap;
2256
+ this.templatesWorker = templatesWorker;
2257
+ this.FORM_DATA_TYPES = lodash.default.uniq([this.schemaUtils.getSchemaType({
2258
+ type: "string",
2259
+ format: "file"
2260
+ }), this.schemaUtils.getSchemaType({
2261
+ type: "string",
2262
+ format: "binary"
2263
+ })]);
2264
+ }
2265
+ };
2266
+
2267
+ //#endregion
2268
+ //#region src/schema-walker.ts
2269
+ var SchemaWalker = class {
2270
+ constructor(config, swaggerSchemaResolver) {
2271
+ this.schemas = new Map();
2272
+ this.caches = new Map();
2273
+ this.addSchema = (name$1, schema) => {
2274
+ this.schemas.set(name$1, structuredClone(schema));
2275
+ };
2276
+ this._isLocalRef = (ref) => {
2277
+ return ref.startsWith("#");
2278
+ };
2279
+ this._isRemoteRef = (ref) => {
2280
+ return ref.startsWith("http://") || ref.startsWith("https://");
2281
+ };
2282
+ this._getRefDataFromSchema = (schema, ref) => {
2283
+ const path$1 = ref.replace("#", "").split("/");
2284
+ const refData = lodash.default.get(schema, path$1);
2285
+ if (refData) this.caches.set(ref, refData);
2286
+ return refData;
2287
+ };
2288
+ this.config = config;
2289
+ this.swaggerSchemaResolver = swaggerSchemaResolver;
2290
+ }
2291
+ };
2292
+
2293
+ //#endregion
2294
+ //#region src/util/request.ts
2295
+ var Request = class {
2296
+ constructor(config) {
2297
+ this.config = config;
2298
+ }
2299
+ async download({ url: url$1, authToken,...options }) {
2300
+ const requestOptions = {};
2301
+ if (authToken) requestOptions.headers = { Authorization: authToken };
2302
+ lodash.default.merge(requestOptions, options, this.config.requestOptions);
2303
+ try {
2304
+ const response = await fetch(url$1, requestOptions);
2305
+ return await response.text();
2306
+ } catch (error) {
2307
+ const message = `error while fetching data from URL "${url$1}"`;
2308
+ consola.consola.error(message, error);
2309
+ return message;
2310
+ }
2311
+ }
2312
+ };
2313
+
2314
+ //#endregion
2315
+ //#region src/swagger-schema-resolver.ts
2316
+ var SwaggerSchemaResolver = class {
2317
+ constructor(config, fileSystem) {
2318
+ this.getSwaggerSchemaByPath = (pathToSwagger) => {
2319
+ consola.consola.info(`try to get swagger by path "${pathToSwagger}"`);
2320
+ return this.fileSystem.getFileContent(pathToSwagger);
2321
+ };
2322
+ this.config = config;
2323
+ this.fileSystem = fileSystem;
2324
+ this.request = new Request(config);
2325
+ }
2326
+ async create() {
2327
+ const { spec, patch, input, url: url$1, authorizationToken } = this.config;
2328
+ if (spec) return await this.convertSwaggerObject(spec, { patch });
2329
+ const swaggerSchemaFile = await this.fetchSwaggerSchemaFile(input, url$1, authorizationToken);
2330
+ const swaggerSchemaObject = this.processSwaggerSchemaFile(swaggerSchemaFile);
2331
+ return await this.convertSwaggerObject(swaggerSchemaObject, { patch });
2332
+ }
2333
+ convertSwaggerObject(swaggerSchema, converterOptions) {
2334
+ return new Promise((resolve) => {
2335
+ const result = structuredClone(swaggerSchema);
2336
+ result.info = lodash.default.merge({
2337
+ title: "No title",
2338
+ version: ""
2339
+ }, result.info);
2340
+ if (!Object.hasOwn(result, "openapi")) {
2341
+ result.paths = lodash.default.merge({}, result.paths);
2342
+ swagger2openapi.convertObj(result, {
2343
+ ...converterOptions,
2344
+ resolveInternal: true,
2345
+ warnOnly: true,
2346
+ refSiblings: "preserve",
2347
+ rbname: "requestBodyName"
2348
+ }, (err, options) => {
2349
+ const parsedSwaggerSchema = lodash.default.get(err, "options.openapi", lodash.default.get(options, "openapi"));
2350
+ if (!parsedSwaggerSchema && err) throw err;
2351
+ this.config.update({ convertedFromSwagger2: true });
2352
+ resolve({
2353
+ usageSchema: parsedSwaggerSchema,
2354
+ originalSchema: result
2355
+ });
2356
+ });
2357
+ } else resolve({
2358
+ usageSchema: result,
2359
+ originalSchema: structuredClone(result)
2360
+ });
2361
+ });
2362
+ }
2363
+ async fetchSwaggerSchemaFile(pathToSwagger, urlToSwagger, authToken) {
2364
+ if (this.fileSystem.pathIsExist(pathToSwagger)) return this.getSwaggerSchemaByPath(pathToSwagger);
2365
+ consola.consola.info(`try to get swagger by URL "${urlToSwagger}"`);
2366
+ return await this.request.download({
2367
+ url: urlToSwagger,
2368
+ authToken
2369
+ });
2370
+ }
2371
+ processSwaggerSchemaFile(file) {
2372
+ if (typeof file !== "string") return file;
2373
+ try {
2374
+ return JSON.parse(file);
2375
+ } catch (e) {
2376
+ return js_yaml.load(file);
2377
+ }
2378
+ }
2379
+ fixSwaggerSchema({ usageSchema, originalSchema }) {
2380
+ const usagePaths = lodash.default.get(usageSchema, "paths");
2381
+ const originalPaths = lodash.default.get(originalSchema, "paths");
2382
+ lodash.default.each(usagePaths, (usagePathObject, route) => {
2383
+ const originalPathObject = lodash.default.get(originalPaths, route);
2384
+ lodash.default.each(usagePathObject, (usageRouteInfo, methodName) => {
2385
+ const originalRouteInfo = lodash.default.get(originalPathObject, methodName);
2386
+ const usageRouteParams = lodash.default.get(usageRouteInfo, "parameters", []);
2387
+ const originalRouteParams = lodash.default.get(originalRouteInfo, "parameters", []);
2388
+ if (typeof usageRouteInfo === "object") {
2389
+ usageRouteInfo.consumes = lodash.default.uniq(lodash.default.compact([...usageRouteInfo.consumes || [], ...originalRouteInfo.consumes || []]));
2390
+ usageRouteInfo.produces = lodash.default.uniq(lodash.default.compact([...usageRouteInfo.produces || [], ...originalRouteInfo.produces || []]));
2391
+ }
2392
+ lodash.default.each(originalRouteParams, (originalRouteParam) => {
2393
+ const existUsageParam = usageRouteParams.find((param) => originalRouteParam.in === param.in && originalRouteParam.name === param.name);
2394
+ if (!existUsageParam) usageRouteParams.push(originalRouteParam);
2395
+ });
2396
+ });
2397
+ });
2398
+ }
2399
+ };
2400
+
2401
+ //#endregion
2402
+ //#region src/templates-worker.ts
2403
+ var TemplatesWorker = class {
2404
+ constructor(config, fileSystem, getRenderTemplateData) {
2405
+ this.getTemplatePaths = (config$1) => {
2406
+ const __dirname$2 = node_path.dirname(node_url.fileURLToPath(require("url").pathToFileURL(__filename).href));
2407
+ const baseTemplatesPath = node_path.resolve(__dirname$2, "../templates/base");
2408
+ const defaultTemplatesPath = node_path.resolve(__dirname$2, "../templates/default");
2409
+ const modularTemplatesPath = node_path.resolve(__dirname$2, "../templates/modular");
2410
+ const originalTemplatesPath = config$1.modular ? modularTemplatesPath : defaultTemplatesPath;
2411
+ const customTemplatesPath = config$1.templates && node_path.resolve(process.cwd(), config$1.templates);
2412
+ return {
2413
+ base: baseTemplatesPath,
2414
+ default: defaultTemplatesPath,
2415
+ modular: modularTemplatesPath,
2416
+ original: originalTemplatesPath,
2417
+ custom: customTemplatesPath
2418
+ };
2419
+ };
2420
+ this.cropExtension = (path$1) => this.config.templateExtensions.reduce((path$2, ext) => path$2.endsWith(ext) ? path$2.replace(ext, "") : path$2, path$1);
2421
+ this.getTemplateFullPath = (path_, fileName) => {
2422
+ const raw = node_path.resolve(path_, "./", this.cropExtension(fileName));
2423
+ const pathVariants = this.config.templateExtensions.map((extension) => `${raw}${extension}`);
2424
+ return pathVariants.find((variant) => !!this.fileSystem.pathIsExist(variant));
2425
+ };
2426
+ this.requireFnFromTemplate = async (packageOrPath) => {
2427
+ const isPath = packageOrPath.startsWith("./") || packageOrPath.startsWith("../");
2428
+ if (isPath) return await import(node_path.resolve(this.config.templatePaths.custom || this.config.templatePaths.original, packageOrPath));
2429
+ return await import(packageOrPath);
2430
+ };
2431
+ this.getTemplate = (name$1, fileName, path$1) => {
2432
+ const { templatePaths } = this.config;
2433
+ if (path$1) return this.fileSystem.getFileContent(path$1);
2434
+ if (!fileName) return "";
2435
+ const customFullPath = templatePaths.custom && this.getTemplateFullPath(templatePaths.custom, fileName);
2436
+ let fileContent = customFullPath && this.fileSystem.getFileContent(customFullPath);
2437
+ if (fileContent) {
2438
+ consola.consola.info(`"${name$1.toLowerCase()}" template found in "${templatePaths.custom}"`);
2439
+ return fileContent;
2440
+ }
2441
+ const baseFullPath = this.getTemplateFullPath(templatePaths.base, fileName);
2442
+ if (baseFullPath) fileContent = this.fileSystem.getFileContent(baseFullPath);
2443
+ else if (templatePaths.custom) consola.consola.warn("Code generator will use the default template:", `"${name$1.toLowerCase()}"`, "template not found in", `"${templatePaths.custom}"`);
2444
+ else consola.consola.info(`Code generator will use the default template for "${name$1.toLowerCase()}"`);
2445
+ const originalFullPath = this.getTemplateFullPath(templatePaths.original, fileName);
2446
+ if (originalFullPath) fileContent = this.fileSystem.getFileContent(originalFullPath);
2447
+ return fileContent;
2448
+ };
2449
+ this.getTemplates = ({ templatePaths }) => {
2450
+ if (templatePaths.custom) consola.consola.info(`try to read templates from directory "${templatePaths.custom}"`);
2451
+ return lodash.default.reduce(this.config.templateInfos, (acc, { name: name$1, fileName }) => ({
2452
+ ...acc,
2453
+ [name$1]: this.getTemplate(name$1, fileName)
2454
+ }), {});
2455
+ };
2456
+ this.findTemplateWithExt = (path$1) => {
2457
+ const raw = this.cropExtension(path$1);
2458
+ const pathVariants = this.config.templateExtensions.map((extension) => `${raw}${extension}`);
2459
+ return pathVariants.find((variant) => this.fileSystem.pathIsExist(variant));
2460
+ };
2461
+ this.getTemplateContent = (path_) => {
2462
+ const foundTemplatePathKey = lodash.default.keys(this.config.templatePaths).find((key) => path_.startsWith(`@${key}`));
2463
+ if (foundTemplatePathKey) {
2464
+ const rawPath = node_path.resolve(path_.replace(`@${foundTemplatePathKey}`, lodash.default.get(this.config.templatePaths, foundTemplatePathKey)));
2465
+ const fixedPath = this.findTemplateWithExt(rawPath);
2466
+ if (fixedPath) return this.fileSystem.getFileContent(fixedPath);
2467
+ }
2468
+ const customPath = this.config.templatePaths.custom && this.findTemplateWithExt(node_path.resolve(this.config.templatePaths.custom, path_));
2469
+ if (customPath) return this.fileSystem.getFileContent(customPath);
2470
+ const originalPath = this.findTemplateWithExt(node_path.resolve(this.config.templatePaths.original, path_));
2471
+ if (originalPath) return this.fileSystem.getFileContent(originalPath);
2472
+ return "";
2473
+ };
2474
+ this.renderTemplate = (template, configuration, options = {}) => {
2475
+ if (!template) return "";
2476
+ return eta.render(template, {
2477
+ ...this.getRenderTemplateData(),
2478
+ ...configuration
2479
+ }, {
2480
+ async: false,
2481
+ ...options,
2482
+ includeFile: (path$1, configuration$1, options$1 = {}) => {
2483
+ return this.renderTemplate(this.getTemplateContent(path$1), configuration$1, options$1);
2484
+ }
2485
+ });
2486
+ };
2487
+ this.config = config;
2488
+ this.fileSystem = fileSystem;
2489
+ this.getRenderTemplateData = getRenderTemplateData;
2490
+ if (this.config.debug) consola.consola.level = Number.MAX_SAFE_INTEGER;
2491
+ if (this.config.silent) consola.consola.level = 0;
2492
+ }
2493
+ };
2494
+
2495
+ //#endregion
2496
+ //#region src/translators/translator.ts
2497
+ var Translator = class {
2498
+ constructor(config, codeFormatter) {
2499
+ this.config = config;
2500
+ this.codeFormatter = codeFormatter;
2501
+ }
2502
+ translate(_input) {
2503
+ throw new Error("not implemented");
2504
+ }
2505
+ };
2506
+
2507
+ //#endregion
2508
+ //#region src/translators/javascript.ts
2509
+ var JavascriptTranslator = class extends Translator {
2510
+ constructor(..._args) {
2511
+ super(..._args);
2512
+ this.compileTSCode = (input) => {
2513
+ const fileNameFull = `${input.fileName}${input.fileExtension}`;
2514
+ const output = {};
2515
+ const host = typescript.createCompilerHost(this.config.compilerTsConfig, true);
2516
+ const fileNames = [fileNameFull];
2517
+ const originalSourceFileGet = host.getSourceFile.bind(host);
2518
+ host.getSourceFile = (sourceFileName, languageVersion, onError, shouldCreateNewSourceFile) => {
2519
+ if (sourceFileName !== fileNameFull) return originalSourceFileGet(sourceFileName, languageVersion, onError, shouldCreateNewSourceFile);
2520
+ return typescript.createSourceFile(sourceFileName, input.fileContent, languageVersion, true, typescript.ScriptKind.TS);
2521
+ };
2522
+ host.writeFile = (fileName, contents) => {
2523
+ output[fileName] = contents;
2524
+ };
2525
+ typescript.createProgram(fileNames, this.config.compilerTsConfig, host).emit();
2526
+ return output;
2527
+ };
2528
+ this.translate = async (input) => {
2529
+ const compiled = this.compileTSCode(input);
2530
+ const jsFileName = `${input.fileName}${typescript.Extension.Js}`;
2531
+ const dtsFileName = `${input.fileName}${typescript.Extension.Dts}`;
2532
+ const sourceContent = compiled[jsFileName];
2533
+ const tsImportRows = input.fileContent.split("\n").filter((line) => line.startsWith("import "));
2534
+ const declarationContent = compiled[dtsFileName].split("\n").map((line) => {
2535
+ if (line.startsWith("import ")) return tsImportRows.shift();
2536
+ return line;
2537
+ }).join("\n");
2538
+ return [{
2539
+ fileName: input.fileName,
2540
+ fileExtension: typescript.Extension.Js,
2541
+ fileContent: await this.codeFormatter.formatCode(sourceContent)
2542
+ }, {
2543
+ fileName: input.fileName,
2544
+ fileExtension: typescript.Extension.Dts,
2545
+ fileContent: await this.codeFormatter.formatCode(declarationContent)
2546
+ }];
2547
+ };
2548
+ }
2549
+ };
2550
+
2551
+ //#endregion
2552
+ //#region src/type-name-formatter.ts
2553
+ var TypeNameFormatter = class {
2554
+ constructor(config) {
2555
+ this.formattedModelNamesMap = new Map();
2556
+ this.format = (name$1, options = {}) => {
2557
+ const schemaType = options.type ?? "type-name";
2558
+ const typePrefix = schemaType === "enum-key" ? this.config.enumKeyPrefix : this.config.typePrefix;
2559
+ const typeSuffix = schemaType === "enum-key" ? this.config.enumKeySuffix : this.config.typeSuffix;
2560
+ const hashKey = `${typePrefix}_${name$1}_${typeSuffix}`;
2561
+ if (typeof name$1 !== "string") {
2562
+ consola.consola.warn("wrong name of the model name", name$1);
2563
+ return name$1;
2564
+ }
2565
+ if (/^([A-Z_]{1,})$/g.test(name$1)) return lodash.default.compact([
2566
+ typePrefix,
2567
+ name$1,
2568
+ typeSuffix
2569
+ ]).join("_");
2570
+ if (this.formattedModelNamesMap.has(hashKey)) return this.formattedModelNamesMap.get(hashKey);
2571
+ const fixedModelName = this.fixModelName(name$1, { type: schemaType });
2572
+ const formattedName = lodash.default.startCase(`${typePrefix}_${fixedModelName}_${typeSuffix}`).replace(/\s/g, "");
2573
+ const formattedResultName = this.config.hooks.onFormatTypeName(formattedName, name$1, schemaType) || formattedName;
2574
+ this.formattedModelNamesMap.set(hashKey, formattedResultName);
2575
+ return formattedResultName;
2576
+ };
2577
+ this.isValidName = (name$1) => /^([A-Za-z$_]{1,})$/g.test(name$1);
2578
+ this.fixModelName = (name$1, options) => {
2579
+ if (!this.isValidName(name$1)) {
2580
+ if (!/^[a-zA-Z_$]/g.test(name$1)) {
2581
+ const fixPrefix = options.type === "enum-key" ? this.config.fixInvalidEnumKeyPrefix : this.config.fixInvalidTypeNamePrefix;
2582
+ return `${fixPrefix} ${name$1}`;
2583
+ }
2584
+ if (name$1.includes(".")) return name$1.replace(/Exclude_keyof[A-Za-z]+/g, () => "ExcludeKeys").replace(/%22~AND~%22/g, "And").replace(/%22~OR~%22/g, "Or").replace(/(\.?%22)|\./g, "_").replace(/__+$/, "");
2585
+ if (name$1.includes("-")) return lodash.default.startCase(name$1).replace(/ /g, "");
2586
+ }
2587
+ return name$1;
2588
+ };
2589
+ this.config = config;
2590
+ }
2591
+ };
2592
+
2593
+ //#endregion
2594
+ //#region src/util/file-system.ts
2595
+ const FILE_PREFIX = `/* eslint-disable */
2596
+ /* tslint:disable */
2597
+ // @ts-nocheck
2598
+ /*
2599
+ * ---------------------------------------------------------------
2600
+ * ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ##
2601
+ * ## ##
2602
+ * ## AUTHOR: acacode ##
2603
+ * ## SOURCE: https://github.com/acacode/swagger-typescript-api ##
2604
+ * ---------------------------------------------------------------
2605
+ */
2606
+
2607
+ `;
2608
+ var FileSystem = class {
2609
+ constructor() {
2610
+ this.getFileContent = (path$1) => {
2611
+ return node_fs.readFileSync(path$1, { encoding: "utf8" });
2612
+ };
2613
+ this.readDir = (path$1) => {
2614
+ return node_fs.readdirSync(path$1);
2615
+ };
2616
+ this.pathIsDir = (path$1) => {
2617
+ if (!path$1) return false;
2618
+ try {
2619
+ const stat = node_fs.statSync(path$1);
2620
+ return stat.isDirectory();
2621
+ } catch (e) {
2622
+ return false;
2623
+ }
2624
+ };
2625
+ this.cropExtension = (fileName) => {
2626
+ const fileNameParts = fileName.split(".");
2627
+ if (fileNameParts.length > 1) fileNameParts.pop();
2628
+ return fileNameParts.join(".");
2629
+ };
2630
+ this.removeDir = (path$1) => {
2631
+ try {
2632
+ if (typeof node_fs.rmSync === "function") node_fs.rmSync(path$1, { recursive: true });
2633
+ else node_fs.rmdirSync(path$1, { recursive: true });
2634
+ } catch (e) {
2635
+ consola.consola.debug("failed to remove dir", e);
2636
+ }
2637
+ };
2638
+ this.createDir = (path$1) => {
2639
+ try {
2640
+ node_fs.mkdirSync(path$1, { recursive: true });
2641
+ } catch (e) {
2642
+ consola.consola.debug("failed to create dir", e);
2643
+ }
2644
+ };
2645
+ this.cleanDir = (path$1) => {
2646
+ this.removeDir(path$1);
2647
+ this.createDir(path$1);
2648
+ };
2649
+ this.pathIsExist = (path$1) => {
2650
+ return !!path$1 && node_fs.existsSync(path$1);
2651
+ };
2652
+ this.createFile = ({ path: path_, fileName, content, withPrefix }) => {
2653
+ const __dirname$2 = node_path.dirname(node_url.fileURLToPath(require("url").pathToFileURL(__filename).href));
2654
+ const absolutePath = node_path.resolve(__dirname$2, path_, `./${fileName}`);
2655
+ const fileContent = `${withPrefix ? FILE_PREFIX : ""}${content}`;
2656
+ return node_fs.writeFileSync(absolutePath, fileContent);
2657
+ };
2658
+ }
2659
+ };
2660
+
2661
+ //#endregion
2662
+ //#region src/code-gen-process.ts
2663
+ const PATCHABLE_INSTANCES = [
2664
+ "schemaWalker",
2665
+ "swaggerSchemaResolver",
2666
+ "schemaComponentsMap",
2667
+ "typeNameFormatter",
2668
+ "templatesWorker",
2669
+ "codeFormatter",
2670
+ "schemaParserFabric",
2671
+ "schemaRoutes",
2672
+ "javascriptTranslator"
2673
+ ];
2674
+ var CodeGenProcess = class {
2675
+ constructor(config) {
2676
+ this.getRenderTemplateData = () => {
2677
+ return {
2678
+ utils: {
2679
+ Ts: this.config.Ts,
2680
+ formatDescription: this.schemaParserFabric.schemaFormatters.formatDescription,
2681
+ internalCase,
2682
+ classNameCase: pascalCase,
2683
+ pascalCase,
2684
+ getInlineParseContent: this.schemaParserFabric.getInlineParseContent,
2685
+ getParseContent: this.schemaParserFabric.getParseContent,
2686
+ getComponentByRef: this.schemaComponentsMap.get,
2687
+ parseSchema: this.schemaParserFabric.parseSchema,
2688
+ checkAndAddNull: this.schemaParserFabric.schemaUtils.safeAddNullToType,
2689
+ safeAddNullToType: this.schemaParserFabric.schemaUtils.safeAddNullToType,
2690
+ isNeedToAddNull: this.schemaParserFabric.schemaUtils.isNullMissingInType,
2691
+ inlineExtraFormatters: this.schemaParserFabric.schemaFormatters.inline,
2692
+ formatters: this.schemaParserFabric.schemaFormatters.base,
2693
+ formatModelName: this.typeNameFormatter.format,
2694
+ fmtToJSDocLine: (line, { eol = true }) => {
2695
+ return ` * ${line}${eol ? "\n" : ""}`;
2696
+ },
2697
+ NameResolver,
2698
+ _: lodash.default,
2699
+ require: this.templatesWorker.requireFnFromTemplate
2700
+ },
2701
+ config: this.config
2702
+ };
2703
+ };
2704
+ this.collectModelTypes = () => {
2705
+ const components = this.schemaComponentsMap.getComponents();
2706
+ let modelTypes = [];
2707
+ const modelTypeComponents = lodash.default.compact(["schemas", this.config.extractResponses && "responses"]);
2708
+ const getSchemaComponentsCount = () => this.schemaComponentsMap.filter(...modelTypeComponents).length;
2709
+ let schemaComponentsCount = getSchemaComponentsCount();
2710
+ let processedCount = 0;
2711
+ while (processedCount < schemaComponentsCount) {
2712
+ modelTypes = [];
2713
+ processedCount = 0;
2714
+ for (const component of components) if (modelTypeComponents.includes(component.componentName)) {
2715
+ const modelType = this.prepareModelType(component);
2716
+ if (modelType) modelTypes.push(modelType);
2717
+ processedCount++;
2718
+ }
2719
+ schemaComponentsCount = getSchemaComponentsCount();
2720
+ }
2721
+ if (this.config.sortTypes) return modelTypes.sort(sortByProperty("name"));
2722
+ return modelTypes;
2723
+ };
2724
+ this.prepareModelType = (typeInfo) => {
2725
+ if (typeInfo.$prepared) return typeInfo.$prepared;
2726
+ if (!typeInfo.typeData) typeInfo.typeData = this.schemaParserFabric.parseSchema(typeInfo.rawTypeData, typeInfo.typeName);
2727
+ const rawTypeData = typeInfo.typeData;
2728
+ const typeData = this.schemaParserFabric.schemaFormatters.base[rawTypeData.type] ? this.schemaParserFabric.schemaFormatters.base[rawTypeData.type](rawTypeData) : rawTypeData;
2729
+ const { typeIdentifier, name: originalName, content, description: description$1 } = typeData;
2730
+ const name$1 = this.typeNameFormatter.format(originalName);
2731
+ if (name$1 === null) return null;
2732
+ const preparedModelType = {
2733
+ ...typeData,
2734
+ typeIdentifier,
2735
+ name: name$1,
2736
+ description: description$1,
2737
+ $content: rawTypeData.content,
2738
+ rawContent: rawTypeData.content,
2739
+ content,
2740
+ typeData
2741
+ };
2742
+ typeInfo.$prepared = preparedModelType;
2743
+ return preparedModelType;
2744
+ };
2745
+ this.generateOutputFiles = async ({ configuration }) => {
2746
+ const { modular, templatesToRender } = this.config;
2747
+ const output = modular ? await this.createMultipleFileInfos(templatesToRender, configuration) : await this.createSingleFileInfo(templatesToRender, configuration);
2748
+ if (!lodash.default.isEmpty(configuration.extraTemplates)) for (const extraTemplate of configuration.extraTemplates) {
2749
+ const content = this.templatesWorker.renderTemplate(this.fileSystem.getFileContent(extraTemplate.path), configuration);
2750
+ output.push(...await this.createOutputFileInfo(configuration, extraTemplate.name, content));
2751
+ }
2752
+ return output.filter((fileInfo) => !!fileInfo && !!fileInfo.fileContent);
2753
+ };
2754
+ this.createMultipleFileInfos = async (templatesToRender, configuration) => {
2755
+ const { routes } = configuration;
2756
+ const { fileNames, generateRouteTypes, generateClient } = configuration.config;
2757
+ const modularApiFileInfos = [];
2758
+ if (routes.$outOfModule) {
2759
+ if (generateRouteTypes) {
2760
+ const outOfModuleRouteContent = this.templatesWorker.renderTemplate(templatesToRender.routeTypes, {
2761
+ ...configuration,
2762
+ route: configuration.routes.$outOfModule
2763
+ });
2764
+ modularApiFileInfos.push(...await this.createOutputFileInfo(configuration, fileNames.outOfModuleApi, outOfModuleRouteContent));
2765
+ }
2766
+ if (generateClient) {
2767
+ const outOfModuleApiContent = this.templatesWorker.renderTemplate(templatesToRender.api, {
2768
+ ...configuration,
2769
+ route: configuration.routes.$outOfModule
2770
+ });
2771
+ modularApiFileInfos.push(...await this.createOutputFileInfo(configuration, fileNames.outOfModuleApi, outOfModuleApiContent));
2772
+ }
2773
+ }
2774
+ if (routes.combined) for (const route of routes.combined) {
2775
+ if (generateRouteTypes) {
2776
+ const routeModuleContent = this.templatesWorker.renderTemplate(templatesToRender.routeTypes, {
2777
+ ...configuration,
2778
+ route
2779
+ });
2780
+ modularApiFileInfos.push(...await this.createOutputFileInfo(configuration, pascalCase(`${route.moduleName}_Route`), routeModuleContent));
2781
+ }
2782
+ if (generateClient) {
2783
+ const apiModuleContent = this.templatesWorker.renderTemplate(templatesToRender.api, {
2784
+ ...configuration,
2785
+ route
2786
+ });
2787
+ modularApiFileInfos.push(...await this.createOutputFileInfo(configuration, pascalCase(route.moduleName), apiModuleContent));
2788
+ }
2789
+ }
2790
+ return [
2791
+ ...await this.createOutputFileInfo(configuration, fileNames.dataContracts, this.templatesWorker.renderTemplate(templatesToRender.dataContracts, configuration)),
2792
+ ...generateClient ? await this.createOutputFileInfo(configuration, fileNames.httpClient, this.templatesWorker.renderTemplate(templatesToRender.httpClient, configuration)) : [],
2793
+ ...modularApiFileInfos
2794
+ ];
2795
+ };
2796
+ this.createSingleFileInfo = async (templatesToRender, configuration) => {
2797
+ const { generateRouteTypes, generateClient } = configuration.config;
2798
+ return await this.createOutputFileInfo(configuration, configuration.fileName, lodash.default.compact([
2799
+ this.templatesWorker.renderTemplate(templatesToRender.dataContracts, configuration),
2800
+ generateRouteTypes && this.templatesWorker.renderTemplate(templatesToRender.routeTypes, configuration),
2801
+ generateClient && this.templatesWorker.renderTemplate(templatesToRender.httpClient, configuration),
2802
+ generateClient && this.templatesWorker.renderTemplate(templatesToRender.api, configuration)
2803
+ ]).join("\n"));
2804
+ };
2805
+ this.createOutputFileInfo = async (configuration, fileNameFull, content) => {
2806
+ const fileName = this.fileSystem.cropExtension(fileNameFull);
2807
+ const fileExtension = typescript.Extension.Ts;
2808
+ if (configuration.translateToJavaScript) {
2809
+ consola.consola.debug("using js translator for", fileName);
2810
+ return await this.javascriptTranslator.translate({
2811
+ fileName,
2812
+ fileExtension,
2813
+ fileContent: content
2814
+ });
2815
+ }
2816
+ if (configuration.customTranslator) {
2817
+ consola.consola.debug("using custom translator for", fileName);
2818
+ return await configuration.customTranslator.translate({
2819
+ fileName,
2820
+ fileExtension,
2821
+ fileContent: content
2822
+ });
2823
+ }
2824
+ consola.consola.debug("generating output for", `${fileName}${fileExtension}`);
2825
+ return [{
2826
+ fileName,
2827
+ fileExtension,
2828
+ fileContent: await this.codeFormatter.formatCode(content)
2829
+ }];
2830
+ };
2831
+ this.createApiConfig = (swaggerSchema) => {
2832
+ const { info, servers, host, basePath, externalDocs, tags } = swaggerSchema;
2833
+ const server = servers?.[0] || { url: "" };
2834
+ const { title = "No title", version: version$1 } = info || {};
2835
+ const { url: serverUrl } = server;
2836
+ return {
2837
+ info: info || {},
2838
+ servers: servers || [],
2839
+ basePath,
2840
+ host,
2841
+ externalDocs: lodash.default.merge({
2842
+ url: "",
2843
+ description: ""
2844
+ }, externalDocs),
2845
+ tags: lodash.default.compact(tags),
2846
+ baseUrl: serverUrl,
2847
+ title,
2848
+ version: version$1
2849
+ };
2850
+ };
2851
+ this.injectClassInstance = (key, value) => {
2852
+ this[key] = value;
2853
+ for (const instanceKey of PATCHABLE_INSTANCES) if (instanceKey !== key && key in this[instanceKey]) this[instanceKey][key] = value;
2854
+ };
2855
+ this.config = new CodeGenConfig(config);
2856
+ this.fileSystem = new FileSystem();
2857
+ this.swaggerSchemaResolver = new SwaggerSchemaResolver(this.config, this.fileSystem);
2858
+ this.schemaWalker = new SchemaWalker(this.config, this.swaggerSchemaResolver);
2859
+ this.schemaComponentsMap = new SchemaComponentsMap(this.config);
2860
+ this.typeNameFormatter = new TypeNameFormatter(this.config);
2861
+ this.templatesWorker = new TemplatesWorker(this.config, this.fileSystem, this.getRenderTemplateData);
2862
+ this.codeFormatter = new CodeFormatter(this.config);
2863
+ this.schemaParserFabric = new SchemaParserFabric(this.config, this.templatesWorker, this.schemaComponentsMap, this.typeNameFormatter, this.schemaWalker);
2864
+ this.schemaRoutes = new SchemaRoutes(this.config, this.schemaParserFabric, this.schemaComponentsMap, this.templatesWorker, this.typeNameFormatter);
2865
+ this.javascriptTranslator = new JavascriptTranslator(this.config, this.codeFormatter);
2866
+ }
2867
+ async start() {
2868
+ this.config.update({ templatePaths: this.templatesWorker.getTemplatePaths(this.config) });
2869
+ this.config.update({ templatesToRender: this.templatesWorker.getTemplates(this.config) });
2870
+ const swagger = await this.swaggerSchemaResolver.create();
2871
+ this.swaggerSchemaResolver.fixSwaggerSchema(swagger);
2872
+ this.config.update({
2873
+ swaggerSchema: swagger.usageSchema,
2874
+ originalSchema: swagger.originalSchema
2875
+ });
2876
+ this.schemaWalker.addSchema("$usage", swagger.usageSchema);
2877
+ this.schemaWalker.addSchema("$original", swagger.originalSchema);
2878
+ consola.consola.info("start generating your typescript api");
2879
+ this.config.update(this.config.hooks.onInit(this.config, this) || this.config);
2880
+ this.schemaComponentsMap.clear();
2881
+ lodash.default.each(swagger.usageSchema.components, (component, componentName) => lodash.default.each(component, (rawTypeData, typeName) => {
2882
+ this.schemaComponentsMap.createComponent(this.schemaComponentsMap.createRef([
2883
+ "components",
2884
+ componentName,
2885
+ typeName
2886
+ ]), rawTypeData);
2887
+ }));
2888
+ this.schemaComponentsMap.enumsFirst();
2889
+ const componentsToParse = this.schemaComponentsMap.filter(lodash.default.compact(["schemas", this.config.extractResponses && "responses"]));
2890
+ const parsedSchemas = componentsToParse.map((schemaComponent) => {
2891
+ const parsed = this.schemaParserFabric.parseSchema(schemaComponent.rawTypeData, schemaComponent.typeName);
2892
+ schemaComponent.typeData = parsed;
2893
+ return parsed;
2894
+ });
2895
+ this.schemaRoutes.attachSchema({
2896
+ usageSchema: swagger.usageSchema,
2897
+ parsedSchemas
2898
+ });
2899
+ const rawConfiguration = {
2900
+ apiConfig: this.createApiConfig(swagger.usageSchema),
2901
+ config: this.config,
2902
+ modelTypes: this.collectModelTypes(),
2903
+ hasSecurityRoutes: this.schemaRoutes.hasSecurityRoutes,
2904
+ hasQueryRoutes: this.schemaRoutes.hasQueryRoutes,
2905
+ hasFormDataRoutes: this.schemaRoutes.hasFormDataRoutes,
2906
+ generateResponses: this.config.generateResponses,
2907
+ routes: this.schemaRoutes.getGroupedRoutes(),
2908
+ extraTemplates: this.config.extraTemplates,
2909
+ fileName: this.config.fileName,
2910
+ translateToJavaScript: this.config.toJS,
2911
+ customTranslator: this.config.customTranslator ? new this.config.customTranslator() : null,
2912
+ utils: this.getRenderTemplateData().utils
2913
+ };
2914
+ const configuration = this.config.hooks.onPrepareConfig(rawConfiguration) || rawConfiguration;
2915
+ if (this.fileSystem.pathIsExist(this.config.output)) {
2916
+ if (this.config.cleanOutput) {
2917
+ consola.consola.debug("cleaning dir", this.config.output);
2918
+ this.fileSystem.cleanDir(this.config.output);
2919
+ }
2920
+ } else {
2921
+ consola.consola.debug(`path ${this.config.output} is not exist. creating dir by this path`);
2922
+ this.fileSystem.createDir(this.config.output);
2923
+ }
2924
+ const files$1 = await this.generateOutputFiles({ configuration });
2925
+ const isDirPath = this.fileSystem.pathIsDir(this.config.output);
2926
+ if (isDirPath) for (const file of files$1) {
2927
+ this.fileSystem.createFile({
2928
+ path: this.config.output,
2929
+ fileName: `${file.fileName}${file.fileExtension}`,
2930
+ content: file.fileContent,
2931
+ withPrefix: true
2932
+ });
2933
+ consola.consola.success("api file", `"${file.fileName}${file.fileExtension}"`, `created in ${this.config.output}`);
2934
+ }
2935
+ return {
2936
+ files: files$1,
2937
+ configuration,
2938
+ getTemplate: this.templatesWorker.getTemplate,
2939
+ renderTemplate: this.templatesWorker.renderTemplate,
2940
+ createFile: this.fileSystem.createFile,
2941
+ formatTSContent: this.codeFormatter.formatCode
2942
+ };
2943
+ }
2944
+ };
2945
+
2946
+ //#endregion
2947
+ //#region src/commands/generate-templates/configuration.ts
2948
+ var TemplatesGenConfig = class {
2949
+ constructor(config) {
2950
+ this.cleanOutput = false;
2951
+ this.debug = false;
2952
+ this.httpClientType = HTTP_CLIENT.FETCH;
2953
+ this.modular = false;
2954
+ this.output = void 0;
2955
+ this.rewrite = false;
2956
+ this.silent = false;
2957
+ this.version = PROJECT_VERSION;
2958
+ this.update = (update) => {
2959
+ objectAssign(this, update);
2960
+ };
2961
+ this.update(config);
2962
+ }
2963
+ };
2964
+
2965
+ //#endregion
2966
+ //#region src/commands/generate-templates/templates-gen-process.ts
2967
+ const __dirname$1 = node_path.default.dirname(node_url.default.fileURLToPath(require("url").pathToFileURL(__filename).href));
2968
+ var TemplatesGenProcess = class {
2969
+ constructor(config) {
2970
+ this.rootDir = node_path.default.resolve(__dirname$1, "..");
2971
+ this.paths = {
2972
+ baseTemplates: "templates/base",
2973
+ httpClientTemplates: "templates/base/http-clients",
2974
+ moduleApiTemplates: "templates/modular",
2975
+ defaultApiTemplates: "templates/default"
2976
+ };
2977
+ this.importTemplatePrefixes = [
2978
+ "@base",
2979
+ "@modular",
2980
+ "@default"
2981
+ ];
2982
+ this.getTemplates = () => {
2983
+ const outputFiles = [];
2984
+ const baseTemplates = this.getTemplateNamesFromDir(this.paths.baseTemplates);
2985
+ const httpClientTemplates = this.getTemplateNamesFromDir(this.paths.httpClientTemplates);
2986
+ const apiTemplatesPath = this.config.modular ? this.paths.moduleApiTemplates : this.paths.defaultApiTemplates;
2987
+ const apiTemplates = this.getTemplateNamesFromDir(apiTemplatesPath);
2988
+ const usingHttpClientTemplate = httpClientTemplates.find((template) => template.startsWith(`${this.config.httpClientType}-`));
2989
+ let httpClientTemplateContent = "";
2990
+ if (usingHttpClientTemplate) httpClientTemplateContent = this.fixTemplateContent(this.getTemplateContent(`${this.paths.httpClientTemplates}/${usingHttpClientTemplate}`));
2991
+ for (const fileName of baseTemplates) {
2992
+ const templateContent = fileName === "http-client.ejs" && httpClientTemplateContent || this.fixTemplateContent(this.getTemplateContent(`${this.paths.baseTemplates}/${fileName}`));
2993
+ outputFiles.push({
2994
+ name: fileName,
2995
+ content: templateContent
2996
+ });
2997
+ }
2998
+ for (const fileName of apiTemplates) outputFiles.push({
2999
+ name: fileName,
3000
+ content: this.fixTemplateContent(this.getTemplateContent(`${apiTemplatesPath}/${fileName}`))
3001
+ });
3002
+ return outputFiles;
3003
+ };
3004
+ this.fixTemplateContent = (content) => {
3005
+ const importsRegExp1 = new RegExp(`includeFile\\("(${this.importTemplatePrefixes.map((v) => `(${v})`).join("|")})/`, "g");
3006
+ const importsRegExp2 = new RegExp(`includeFile\\(\`(${this.importTemplatePrefixes.map((v) => `(${v})`).join("|")})/`, "g");
3007
+ const importsRegExp3 = new RegExp(`includeFile\\('(${this.importTemplatePrefixes.map((v) => `(${v})`).join("|")})/`, "g");
3008
+ return content.replace(importsRegExp1, "includeFile(\"./").replace(importsRegExp2, "includeFile(`./").replace(importsRegExp3, "includeFile('./");
3009
+ };
3010
+ this.getTemplateNamesFromDir = (dir) => {
3011
+ return this.fileSystem.readDir(node_path.default.resolve(this.rootDir, dir)).filter((file) => file.endsWith(".ejs"));
3012
+ };
3013
+ this.getTemplateContent = (pathToFile) => {
3014
+ return this.fileSystem.getFileContent(node_path.default.resolve(this.rootDir, pathToFile));
3015
+ };
3016
+ this.config = new TemplatesGenConfig(config);
3017
+ this.fileSystem = new FileSystem();
3018
+ }
3019
+ async start() {
3020
+ consola.consola.info("start generating source templates \".ejs\" for code generator");
3021
+ const templates = this.getTemplates();
3022
+ if (this.config.output) {
3023
+ consola.consola.info("preparing output directory for source templates");
3024
+ const outputPath = node_path.default.resolve(process.cwd(), this.config.output);
3025
+ if (this.fileSystem.pathIsExist(outputPath)) {
3026
+ if (this.config.cleanOutput) this.fileSystem.cleanDir(outputPath);
3027
+ } else this.fileSystem.createDir(outputPath);
3028
+ for (const template of templates) {
3029
+ const templateName = this.fileSystem.cropExtension(template.name);
3030
+ const templateEjsPath = node_path.default.resolve(outputPath, `${templateName}.ejs`);
3031
+ const templateEtaPath = node_path.default.resolve(outputPath, `${templateName}.eta`);
3032
+ const templateEjsPathExist = this.fileSystem.pathIsExist(templateEjsPath);
3033
+ const templateEtaPathExist = this.fileSystem.pathIsExist(templateEtaPath);
3034
+ const templateNotExist = !templateEjsPathExist && !templateEtaPathExist;
3035
+ if (templateNotExist) this.fileSystem.createFile({
3036
+ path: outputPath,
3037
+ fileName: template.name,
3038
+ content: template.content,
3039
+ withPrefix: false
3040
+ });
3041
+ else if (this.config.rewrite) {
3042
+ if (templateEjsPathExist) this.fileSystem.createFile({
3043
+ path: outputPath,
3044
+ fileName: `${templateName}.ejs`,
3045
+ content: template.content,
3046
+ withPrefix: false
3047
+ });
3048
+ else if (templateEtaPathExist) this.fileSystem.createFile({
3049
+ path: outputPath,
3050
+ fileName: `${templateName}.eta`,
3051
+ content: template.content,
3052
+ withPrefix: false
3053
+ });
3054
+ }
3055
+ }
3056
+ consola.consola.success(`source templates has been successfully created in "${outputPath}"`);
3057
+ }
3058
+ return {
3059
+ files: templates,
3060
+ configuration: this.config,
3061
+ createFile: this.fileSystem.createFile
3062
+ };
3063
+ }
3064
+ };
3065
+
3066
+ //#endregion
3067
+ //#region src/commands/generate-templates/index.ts
3068
+ async function generateTemplates(config) {
3069
+ if (config.debug) consola.consola.level = Number.MAX_SAFE_INTEGER;
3070
+ if (config.silent) consola.consola.level = 0;
3071
+ const codeGenProcess = new TemplatesGenProcess(config);
3072
+ return await codeGenProcess.start();
3073
+ }
3074
+
3075
+ //#endregion
3076
+ //#region src/index.ts
3077
+ async function generateApi(config) {
3078
+ if (config.debug) consola.consola.level = Number.MAX_SAFE_INTEGER;
3079
+ if (config.silent) consola.consola.level = 0;
3080
+ const codeGenProcess = new CodeGenProcess(config);
3081
+ return await codeGenProcess.start();
3082
+ }
3083
+
3084
+ //#endregion
3085
+ Object.defineProperty(exports, 'CodeGenConfig', {
3086
+ enumerable: true,
3087
+ get: function () {
3088
+ return CodeGenConfig;
3089
+ }
3090
+ });
3091
+ Object.defineProperty(exports, 'HTTP_CLIENT', {
3092
+ enumerable: true,
3093
+ get: function () {
3094
+ return HTTP_CLIENT;
3095
+ }
3096
+ });
3097
+ Object.defineProperty(exports, 'TemplatesGenConfig', {
3098
+ enumerable: true,
3099
+ get: function () {
3100
+ return TemplatesGenConfig;
3101
+ }
3102
+ });
3103
+ Object.defineProperty(exports, '__toESM', {
3104
+ enumerable: true,
3105
+ get: function () {
3106
+ return __toESM;
3107
+ }
3108
+ });
3109
+ Object.defineProperty(exports, 'constants_exports', {
3110
+ enumerable: true,
3111
+ get: function () {
3112
+ return constants_exports;
3113
+ }
3114
+ });
3115
+ Object.defineProperty(exports, 'generateApi', {
3116
+ enumerable: true,
3117
+ get: function () {
3118
+ return generateApi;
3119
+ }
3120
+ });
3121
+ Object.defineProperty(exports, 'generateTemplates', {
3122
+ enumerable: true,
3123
+ get: function () {
3124
+ return generateTemplates;
3125
+ }
3126
+ });
3127
+ Object.defineProperty(exports, 'package_default', {
3128
+ enumerable: true,
3129
+ get: function () {
3130
+ return package_default;
3131
+ }
3132
+ });
3133
+ //# sourceMappingURL=src-D3nQpZ1i.cjs.map