swagger-typescript-api 13.1.2 → 13.2.0

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