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