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