ng-openapi 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (6) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +188 -0
  3. package/cli.cjs +1827 -0
  4. package/index.d.ts +169 -0
  5. package/index.js +1807 -0
  6. package/package.json +86 -0
package/index.js ADDED
@@ -0,0 +1,1807 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __spreadValues = (a, b) => {
12
+ for (var prop in b || (b = {}))
13
+ if (__hasOwnProp.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ if (__getOwnPropSymbols)
16
+ for (var prop of __getOwnPropSymbols(b)) {
17
+ if (__propIsEnum.call(b, prop))
18
+ __defNormalProp(a, prop, b[prop]);
19
+ }
20
+ return a;
21
+ };
22
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
23
+ var __export = (target, all) => {
24
+ for (var name in all)
25
+ __defProp(target, name, { get: all[name], enumerable: true });
26
+ };
27
+ var __copyProps = (to, from, except, desc) => {
28
+ if (from && typeof from === "object" || typeof from === "function") {
29
+ for (let key of __getOwnPropNames(from))
30
+ if (!__hasOwnProp.call(to, key) && key !== except)
31
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
32
+ }
33
+ return to;
34
+ };
35
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
36
+ // If the importer is in node compatibility mode or this is not an ESM
37
+ // file that has been converted to a CommonJS file using a Babel-
38
+ // compatible transform (i.e. "__esModule" has not been set), then set
39
+ // "default" to the CommonJS "module.exports" for node compatibility.
40
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
41
+ mod
42
+ ));
43
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
44
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
45
+ var __async = (__this, __arguments, generator) => {
46
+ return new Promise((resolve, reject) => {
47
+ var fulfilled = (value) => {
48
+ try {
49
+ step(generator.next(value));
50
+ } catch (e) {
51
+ reject(e);
52
+ }
53
+ };
54
+ var rejected = (value) => {
55
+ try {
56
+ step(generator.throw(value));
57
+ } catch (e) {
58
+ reject(e);
59
+ }
60
+ };
61
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
62
+ step((generator = generator.apply(__this, __arguments)).next());
63
+ });
64
+ };
65
+
66
+ // src/index.ts
67
+ var index_exports = {};
68
+ __export(index_exports, {
69
+ SwaggerParser: () => SwaggerParser,
70
+ generateFromConfig: () => generateFromConfig
71
+ });
72
+ module.exports = __toCommonJS(index_exports);
73
+
74
+ // src/lib/core/swagger-parser.ts
75
+ var fs = __toESM(require("fs"));
76
+ var _SwaggerParser = class _SwaggerParser {
77
+ constructor(swaggerPath) {
78
+ __publicField(this, "spec");
79
+ const swaggerContent = fs.readFileSync(swaggerPath, "utf8");
80
+ this.spec = JSON.parse(swaggerContent);
81
+ }
82
+ getDefinitions() {
83
+ var _a;
84
+ return this.spec.definitions || ((_a = this.spec.components) == null ? void 0 : _a.schemas) || {};
85
+ }
86
+ getDefinition(name) {
87
+ const definitions = this.getDefinitions();
88
+ return definitions[name];
89
+ }
90
+ resolveReference(ref) {
91
+ const parts = ref.split("/");
92
+ const definitionName = parts[parts.length - 1];
93
+ return this.getDefinition(definitionName);
94
+ }
95
+ getAllDefinitionNames() {
96
+ return Object.keys(this.getDefinitions());
97
+ }
98
+ };
99
+ __name(_SwaggerParser, "SwaggerParser");
100
+ var SwaggerParser = _SwaggerParser;
101
+
102
+ // src/lib/core/generator.ts
103
+ var import_ts_morph4 = require("ts-morph");
104
+
105
+ // src/lib/generators/type/type.generator.ts
106
+ var import_ts_morph = require("ts-morph");
107
+
108
+ // src/lib/config/constants.ts
109
+ var disableLinting = `/* @ts-nocheck */
110
+ /* eslint-disable */
111
+ /* @noformat */
112
+ /* @formatter:off */
113
+ `;
114
+ var authorComment = `/**
115
+ * Generated by ng-openapi
116
+ `;
117
+ var defaultHeaderComment = disableLinting + authorComment;
118
+ var TYPE_GENERATOR_HEADER_COMMENT = defaultHeaderComment + `* Generated TypeScript interfaces from Swagger specification
119
+ * Do not edit this file manually
120
+ */
121
+ `;
122
+ var SERVICE_INDEX_GENERATOR_HEADER_COMMENT = defaultHeaderComment + `* Generated service exports
123
+ * Do not edit this file manually
124
+ */
125
+ `;
126
+ var SERVICE_GENERATOR_HEADER_COMMENT = /* @__PURE__ */ __name((controllerName) => defaultHeaderComment + `* Generated Angular service for ${controllerName} controller
127
+ * Do not edit this file manually
128
+ */
129
+ `, "SERVICE_GENERATOR_HEADER_COMMENT");
130
+
131
+ // src/lib/generators/type/type.generator.ts
132
+ var _TypeGenerator = class _TypeGenerator {
133
+ constructor(swaggerPath, outputRoot, config) {
134
+ __publicField(this, "project");
135
+ __publicField(this, "parser");
136
+ __publicField(this, "sourceFile");
137
+ __publicField(this, "generatedTypes", /* @__PURE__ */ new Set());
138
+ __publicField(this, "config");
139
+ this.config = config;
140
+ const outputPath = outputRoot + "/models/index.ts";
141
+ this.project = new import_ts_morph.Project({
142
+ compilerOptions: __spreadValues({
143
+ declaration: true,
144
+ target: import_ts_morph.ScriptTarget.ES2022,
145
+ module: import_ts_morph.ModuleKind.Preserve,
146
+ strict: true
147
+ }, this.config.compilerOptions)
148
+ });
149
+ try {
150
+ this.parser = new SwaggerParser(swaggerPath);
151
+ this.sourceFile = this.project.createSourceFile(outputPath, "", {
152
+ overwrite: true
153
+ });
154
+ } catch (error) {
155
+ console.error("Error initializing TypeGenerator:", error);
156
+ throw error;
157
+ }
158
+ }
159
+ generate() {
160
+ try {
161
+ const definitions = this.parser.getDefinitions();
162
+ if (!definitions || Object.keys(definitions).length === 0) {
163
+ console.warn("No definitions found in swagger file");
164
+ return;
165
+ }
166
+ this.sourceFile.insertText(0, TYPE_GENERATOR_HEADER_COMMENT);
167
+ Object.entries(definitions).forEach(([name, definition]) => {
168
+ this.generateInterface(name, definition);
169
+ });
170
+ this.sourceFile.saveSync();
171
+ } catch (error) {
172
+ console.error("Error in generate():", error);
173
+ throw new Error(`Failed to generate types: ${error instanceof Error ? error.message : "Unknown error"}`);
174
+ }
175
+ }
176
+ generateInterface(name, definition) {
177
+ const interfaceName = this.pascalCaseForEnums(name);
178
+ if (this.generatedTypes.has(interfaceName)) {
179
+ return;
180
+ }
181
+ this.generatedTypes.add(interfaceName);
182
+ if (definition.enum) {
183
+ this.generateEnum(interfaceName, definition);
184
+ return;
185
+ }
186
+ if (definition.allOf) {
187
+ this.generateCompositeType(interfaceName, definition);
188
+ return;
189
+ }
190
+ const interfaceDeclaration = this.sourceFile.addInterface({
191
+ name: interfaceName,
192
+ isExported: true,
193
+ docs: definition.description ? [
194
+ definition.description
195
+ ] : void 0
196
+ });
197
+ this.addInterfaceProperties(interfaceDeclaration, definition);
198
+ }
199
+ generateEnum(name, definition) {
200
+ var _a;
201
+ if (!((_a = definition.enum) == null ? void 0 : _a.length)) return;
202
+ const isStringEnum = definition.enum.some((value) => typeof value === "string");
203
+ if (isStringEnum) {
204
+ const unionType = definition.enum.map((value) => typeof value === "string" ? `'${this.escapeString(value)}'` : String(value)).join(" | ");
205
+ this.sourceFile.addTypeAlias({
206
+ name,
207
+ type: unionType,
208
+ isExported: true,
209
+ docs: definition.description ? [
210
+ definition.description
211
+ ] : void 0
212
+ });
213
+ } else if (definition.description && this.config.options.generateEnumBasedOnDescription) {
214
+ const enumDeclaration = this.sourceFile.addEnum({
215
+ name,
216
+ isExported: true
217
+ });
218
+ try {
219
+ const enumValueObjects = JSON.parse(definition.description);
220
+ enumValueObjects.forEach((enumValueObject) => {
221
+ enumDeclaration.addMember({
222
+ name: enumValueObject.Name,
223
+ value: enumValueObject.Value
224
+ });
225
+ });
226
+ } catch (e) {
227
+ console.error(`Failed to parse enum description for ${name}`);
228
+ definition.enum.forEach((value) => {
229
+ const enumKey = this.toEnumKey(value);
230
+ enumDeclaration.addMember({
231
+ name: enumKey,
232
+ value
233
+ });
234
+ });
235
+ }
236
+ } else {
237
+ const enumDeclaration = this.sourceFile.addEnum({
238
+ name,
239
+ isExported: true,
240
+ docs: definition.description ? [
241
+ definition.description
242
+ ] : void 0
243
+ });
244
+ definition.enum.forEach((value) => {
245
+ const enumKey = this.toEnumKey(value);
246
+ enumDeclaration.addMember({
247
+ name: enumKey,
248
+ value
249
+ });
250
+ });
251
+ }
252
+ }
253
+ generateCompositeType(name, definition) {
254
+ let typeExpression = "";
255
+ if (definition.allOf) {
256
+ const types = definition.allOf.map((def) => this.resolveSwaggerType(def)).filter((type) => type !== "any" && type !== "unknown");
257
+ typeExpression = types.length > 0 ? types.join(" & ") : "Record<string, unknown>";
258
+ }
259
+ this.sourceFile.addTypeAlias({
260
+ name,
261
+ type: typeExpression,
262
+ isExported: true,
263
+ docs: definition.description ? [
264
+ definition.description
265
+ ] : void 0
266
+ });
267
+ }
268
+ addInterfaceProperties(interfaceDeclaration, definition) {
269
+ if (!definition.properties && definition.additionalProperties === false) {
270
+ interfaceDeclaration.addIndexSignature({
271
+ keyName: "key",
272
+ keyType: "string",
273
+ returnType: "never"
274
+ });
275
+ return;
276
+ }
277
+ if (!definition.properties && definition.additionalProperties === true) {
278
+ interfaceDeclaration.addIndexSignature({
279
+ keyName: "key",
280
+ keyType: "string",
281
+ returnType: "any"
282
+ });
283
+ return;
284
+ }
285
+ if (!definition.properties) {
286
+ console.warn(`No properties found for interface ${interfaceDeclaration.getName()}`);
287
+ return;
288
+ }
289
+ Object.entries(definition.properties).forEach(([propertyName, property]) => {
290
+ var _a, _b;
291
+ const isRequired = (_b = (_a = definition.required) == null ? void 0 : _a.includes(propertyName)) != null ? _b : false;
292
+ const isReadOnly = property.readOnly;
293
+ const propertyType = this.resolveSwaggerType(property);
294
+ const sanitizedName = this.sanitizePropertyName(propertyName);
295
+ interfaceDeclaration.addProperty({
296
+ name: sanitizedName,
297
+ type: propertyType,
298
+ isReadonly: isReadOnly,
299
+ hasQuestionToken: !isRequired,
300
+ docs: property.description ? [
301
+ property.description
302
+ ] : void 0
303
+ });
304
+ });
305
+ }
306
+ resolveSwaggerType(schema) {
307
+ if (schema.$ref) {
308
+ return this.resolveReference(schema.$ref);
309
+ }
310
+ if (schema.enum) {
311
+ return schema.enum.map((value) => typeof value === "string" ? `'${this.escapeString(value)}'` : String(value)).join(" | ");
312
+ }
313
+ if (schema.allOf) {
314
+ return schema.allOf.map((def) => this.resolveSwaggerType(def)).filter((type) => type !== "any" && type !== "unknown").join(" & ") || "Record";
315
+ }
316
+ if (schema.oneOf) {
317
+ return schema.oneOf.map((def) => this.resolveSwaggerType(def)).filter((type) => type !== "any" && type !== "unknown").join(" | ") || "unknown";
318
+ }
319
+ if (schema.anyOf) {
320
+ return schema.anyOf.map((def) => this.resolveSwaggerType(def)).filter((type) => type !== "any" && type !== "unknown").join(" | ") || "unknown";
321
+ }
322
+ if (schema.type === "array") {
323
+ const itemType = schema.items ? this.getArrayItemType(schema.items) : "unknown";
324
+ return `${itemType}[]`;
325
+ }
326
+ if (schema.type === "object") {
327
+ if (schema.properties) {
328
+ return this.generateInlineObjectType(schema);
329
+ }
330
+ if (schema.additionalProperties) {
331
+ const valueType = typeof schema.additionalProperties === "object" ? this.resolveSwaggerType(schema.additionalProperties) : "unknown";
332
+ return `Record<string, ${valueType}>`;
333
+ }
334
+ return "Record<string, unknown>";
335
+ }
336
+ return this.mapSwaggerTypeToTypeScript(schema.type, schema.format, schema.nullable);
337
+ }
338
+ generateInlineObjectType(definition) {
339
+ if (!definition.properties) {
340
+ if (definition.additionalProperties) {
341
+ const additionalType = typeof definition.additionalProperties === "object" ? this.resolveSwaggerType(definition.additionalProperties) : "unknown";
342
+ return `Record<string, ${additionalType}>`;
343
+ }
344
+ return "Record<string, unknown>";
345
+ }
346
+ const properties = Object.entries(definition.properties).map(([key, prop]) => {
347
+ var _a, _b;
348
+ const isRequired = (_b = (_a = definition.required) == null ? void 0 : _a.includes(key)) != null ? _b : false;
349
+ const questionMark = isRequired ? "" : "?";
350
+ const sanitizedKey = this.sanitizePropertyName(key);
351
+ return `${sanitizedKey}${questionMark}: ${this.resolveSwaggerType(prop)}`;
352
+ }).join("; ");
353
+ return `{ ${properties} }`;
354
+ }
355
+ resolveReference(ref) {
356
+ try {
357
+ const refDefinition = this.parser.resolveReference(ref);
358
+ const refName = ref.split("/").pop();
359
+ if (!refName) {
360
+ console.warn(`Invalid reference format: ${ref}`);
361
+ return "unknown";
362
+ }
363
+ const typeName = this.pascalCaseForEnums(refName);
364
+ if (refDefinition && !this.generatedTypes.has(typeName)) {
365
+ this.generateInterface(refName, refDefinition);
366
+ }
367
+ return typeName;
368
+ } catch (error) {
369
+ console.warn(`Failed to resolve reference ${ref}:`, error);
370
+ return "unknown";
371
+ }
372
+ }
373
+ mapSwaggerTypeToTypeScript(type, format, isNullable) {
374
+ if (!type) return "unknown";
375
+ switch (type) {
376
+ case "string":
377
+ if (format === "date" || format === "date-time") {
378
+ const dateType = this.config.options.dateType === "Date" ? "Date" : "string";
379
+ return this.nullableType(dateType, isNullable);
380
+ }
381
+ if (format === "binary") return "Blob";
382
+ if (format === "uuid") return "string";
383
+ if (format === "email") return "string";
384
+ if (format === "uri") return "string";
385
+ return this.nullableType("string", isNullable);
386
+ case "number":
387
+ case "integer":
388
+ return this.nullableType("number", isNullable);
389
+ case "boolean":
390
+ return this.nullableType("boolean", isNullable);
391
+ case "array":
392
+ return this.nullableType("unknown[]", isNullable);
393
+ case "object":
394
+ return this.nullableType("Record<string, unknown>", isNullable);
395
+ case "null":
396
+ return this.nullableType("null", isNullable);
397
+ default:
398
+ console.warn(`Unknown swagger type: ${type}`);
399
+ return this.nullableType("unknown", isNullable);
400
+ }
401
+ }
402
+ nullableType(type, isNullable) {
403
+ return type + (isNullable ? " | null" : "");
404
+ }
405
+ pascalCaseForEnums(str) {
406
+ return str.replace(/[^a-zA-Z0-9]/g, "_").replace(/(?:^|_)([a-z])/g, (_, char) => char.toUpperCase()).replace(/^([0-9])/, "_$1");
407
+ }
408
+ sanitizePropertyName(name) {
409
+ if (!/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name)) {
410
+ return `"${name}"`;
411
+ }
412
+ return name;
413
+ }
414
+ toEnumKey(value) {
415
+ return value.toString().replace(/[^a-zA-Z0-9]/g, "_").replace(/^([0-9])/, "_$1").toUpperCase();
416
+ }
417
+ getArrayItemType(items) {
418
+ if (Array.isArray(items)) {
419
+ const types = items.map((item) => this.resolveSwaggerType(item));
420
+ return `[${types.join(", ")}]`;
421
+ } else {
422
+ return this.resolveSwaggerType(items);
423
+ }
424
+ }
425
+ escapeString(str) {
426
+ return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
427
+ }
428
+ };
429
+ __name(_TypeGenerator, "TypeGenerator");
430
+ var TypeGenerator = _TypeGenerator;
431
+
432
+ // src/lib/generators/utility/token.generator.ts
433
+ var import_ts_morph2 = require("ts-morph");
434
+ var path = __toESM(require("path"));
435
+ var _TokenGenerator = class _TokenGenerator {
436
+ constructor(project) {
437
+ __publicField(this, "project");
438
+ this.project = project;
439
+ }
440
+ generate(outputDir) {
441
+ const tokensDir = path.join(outputDir, "tokens");
442
+ const filePath = path.join(tokensDir, "index.ts");
443
+ const sourceFile = this.project.createSourceFile(filePath, "", {
444
+ overwrite: true
445
+ });
446
+ sourceFile.addImportDeclaration({
447
+ namedImports: [
448
+ "InjectionToken"
449
+ ],
450
+ moduleSpecifier: "@angular/core"
451
+ });
452
+ sourceFile.addVariableStatement({
453
+ isExported: true,
454
+ declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
455
+ declarations: [
456
+ {
457
+ name: "BASE_PATH",
458
+ initializer: `new InjectionToken<string>('BASE_PATH', {
459
+ providedIn: 'root',
460
+ factory: () => '/api', // Default fallback
461
+ })`
462
+ }
463
+ ],
464
+ leadingTrivia: `/**
465
+ * Injection token for the base API path
466
+ */
467
+ `
468
+ });
469
+ sourceFile.saveSync();
470
+ }
471
+ };
472
+ __name(_TokenGenerator, "TokenGenerator");
473
+ var TokenGenerator = _TokenGenerator;
474
+
475
+ // src/lib/generators/utility/file-download.generator.ts
476
+ var path2 = __toESM(require("path"));
477
+ var _FileDownloadGenerator = class _FileDownloadGenerator {
478
+ constructor(project) {
479
+ __publicField(this, "project");
480
+ this.project = project;
481
+ }
482
+ generate(outputDir) {
483
+ const utilsDir = path2.join(outputDir, "utils");
484
+ const filePath = path2.join(utilsDir, "file-download.ts");
485
+ const sourceFile = this.project.createSourceFile(filePath, "", {
486
+ overwrite: true
487
+ });
488
+ sourceFile.addImportDeclaration({
489
+ namedImports: [
490
+ "Observable"
491
+ ],
492
+ moduleSpecifier: "rxjs"
493
+ });
494
+ sourceFile.addImportDeclaration({
495
+ namedImports: [
496
+ "tap"
497
+ ],
498
+ moduleSpecifier: "rxjs/operators"
499
+ });
500
+ sourceFile.addFunction({
501
+ name: "downloadFile",
502
+ isExported: true,
503
+ parameters: [
504
+ {
505
+ name: "blob",
506
+ type: "Blob"
507
+ },
508
+ {
509
+ name: "filename",
510
+ type: "string"
511
+ },
512
+ {
513
+ name: "mimeType",
514
+ type: "string",
515
+ hasQuestionToken: true
516
+ }
517
+ ],
518
+ returnType: "void",
519
+ statements: `
520
+ // Create a temporary URL for the blob
521
+ const url = window.URL.createObjectURL(blob);
522
+
523
+ // Create a temporary anchor element and trigger download
524
+ const link = document.createElement('a');
525
+ link.href = url;
526
+ link.download = filename;
527
+
528
+ // Append to body, click, and remove
529
+ document.body.appendChild(link);
530
+ link.click();
531
+ document.body.removeChild(link);
532
+
533
+ // Clean up the URL
534
+ window.URL.revokeObjectURL(url);`
535
+ });
536
+ sourceFile.addFunction({
537
+ name: "downloadFileOperator",
538
+ isExported: true,
539
+ typeParameters: [
540
+ {
541
+ name: "T",
542
+ constraint: "Blob"
543
+ }
544
+ ],
545
+ parameters: [
546
+ {
547
+ name: "filename",
548
+ type: "string | ((blob: T) => string)"
549
+ },
550
+ {
551
+ name: "mimeType",
552
+ type: "string",
553
+ hasQuestionToken: true
554
+ }
555
+ ],
556
+ returnType: "(source: Observable<T>) => Observable<T>",
557
+ statements: `
558
+ return (source: Observable<T>) => {
559
+ return source.pipe(
560
+ tap((blob: T) => {
561
+ const actualFilename = typeof filename === 'function' ? filename(blob) : filename;
562
+ downloadFile(blob, actualFilename, mimeType);
563
+ })
564
+ );
565
+ };`
566
+ });
567
+ sourceFile.addFunction({
568
+ name: "extractFilenameFromContentDisposition",
569
+ isExported: true,
570
+ parameters: [
571
+ {
572
+ name: "contentDisposition",
573
+ type: "string | null"
574
+ },
575
+ {
576
+ name: "fallbackFilename",
577
+ type: "string",
578
+ initializer: '"download"'
579
+ }
580
+ ],
581
+ returnType: "string",
582
+ statements: `
583
+ if (!contentDisposition) {
584
+ return fallbackFilename;
585
+ }
586
+
587
+ // Try to extract filename from Content-Disposition header
588
+ // Supports both "filename=" and "filename*=" formats
589
+ const filenameMatch = contentDisposition.match(/filename\\*?=['"]?([^'"\\n;]+)['"]?/i);
590
+
591
+ if (filenameMatch && filenameMatch[1]) {
592
+ // Decode if it's RFC 5987 encoded (filename*=UTF-8''...)
593
+ const filename = filenameMatch[1];
594
+ if (filename.includes("''")) {
595
+ const parts = filename.split("''");
596
+ if (parts.length === 2) {
597
+ try {
598
+ return decodeURIComponent(parts[1]);
599
+ } catch {
600
+ return parts[1];
601
+ }
602
+ }
603
+ }
604
+ return filename;
605
+ }
606
+
607
+ return fallbackFilename;`
608
+ });
609
+ sourceFile.saveSync();
610
+ }
611
+ };
612
+ __name(_FileDownloadGenerator, "FileDownloadGenerator");
613
+ var FileDownloadGenerator = _FileDownloadGenerator;
614
+
615
+ // src/lib/generators/utility/date-transformer.generator.ts
616
+ var path3 = __toESM(require("path"));
617
+ var _DateTransformerGenerator = class _DateTransformerGenerator {
618
+ constructor(project) {
619
+ __publicField(this, "project");
620
+ this.project = project;
621
+ }
622
+ generate(outputDir) {
623
+ const utilsDir = path3.join(outputDir, "utils");
624
+ const filePath = path3.join(utilsDir, "date-transformer.ts");
625
+ const sourceFile = this.project.createSourceFile(filePath, "", {
626
+ overwrite: true
627
+ });
628
+ sourceFile.addImportDeclaration({
629
+ namedImports: [
630
+ "HttpInterceptor",
631
+ "HttpRequest",
632
+ "HttpHandler",
633
+ "HttpEvent",
634
+ "HttpResponse"
635
+ ],
636
+ moduleSpecifier: "@angular/common/http"
637
+ });
638
+ sourceFile.addImportDeclaration({
639
+ namedImports: [
640
+ "Injectable"
641
+ ],
642
+ moduleSpecifier: "@angular/core"
643
+ });
644
+ sourceFile.addImportDeclaration({
645
+ namedImports: [
646
+ "Observable"
647
+ ],
648
+ moduleSpecifier: "rxjs"
649
+ });
650
+ sourceFile.addImportDeclaration({
651
+ namedImports: [
652
+ "map"
653
+ ],
654
+ moduleSpecifier: "rxjs/operators"
655
+ });
656
+ sourceFile.addVariableStatement({
657
+ isExported: true,
658
+ declarationKind: "const",
659
+ declarations: [
660
+ {
661
+ name: "ISO_DATE_REGEX",
662
+ initializer: "/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z?$/"
663
+ }
664
+ ]
665
+ });
666
+ sourceFile.addFunction({
667
+ name: "transformDates",
668
+ isExported: true,
669
+ parameters: [
670
+ {
671
+ name: "obj",
672
+ type: "any"
673
+ }
674
+ ],
675
+ returnType: "any",
676
+ statements: `
677
+ if (obj === null || obj === undefined || typeof obj !== 'object') {
678
+ return obj;
679
+ }
680
+
681
+ if (obj instanceof Date) {
682
+ return obj;
683
+ }
684
+
685
+ if (Array.isArray(obj)) {
686
+ return obj.map(item => transformDates(item));
687
+ }
688
+
689
+ if (typeof obj === 'object') {
690
+ const transformed: any = {};
691
+ for (const key of Object.keys(obj)) {
692
+ const value = obj[key];
693
+ if (typeof value === 'string' && ISO_DATE_REGEX.test(value)) {
694
+ transformed[key] = new Date(value);
695
+ } else {
696
+ transformed[key] = transformDates(value);
697
+ }
698
+ }
699
+ return transformed;
700
+ }
701
+
702
+ return obj;`
703
+ });
704
+ sourceFile.addClass({
705
+ name: "DateInterceptor",
706
+ isExported: true,
707
+ decorators: [
708
+ {
709
+ name: "Injectable",
710
+ arguments: []
711
+ }
712
+ ],
713
+ implements: [
714
+ "HttpInterceptor"
715
+ ],
716
+ methods: [
717
+ {
718
+ name: "intercept",
719
+ parameters: [
720
+ {
721
+ name: "req",
722
+ type: "HttpRequest<any>"
723
+ },
724
+ {
725
+ name: "next",
726
+ type: "HttpHandler"
727
+ }
728
+ ],
729
+ returnType: "Observable<HttpEvent<any>>",
730
+ statements: `
731
+ return next.handle(req).pipe(
732
+ map(event => {
733
+ if (event instanceof HttpResponse && event.body) {
734
+ return event.clone({ body: transformDates(event.body) });
735
+ }
736
+ return event;
737
+ })
738
+ );`
739
+ }
740
+ ]
741
+ });
742
+ sourceFile.saveSync();
743
+ }
744
+ };
745
+ __name(_DateTransformerGenerator, "DateTransformerGenerator");
746
+ var DateTransformerGenerator = _DateTransformerGenerator;
747
+
748
+ // src/lib/generators/service/service.generator.ts
749
+ var import_ts_morph3 = require("ts-morph");
750
+ var path4 = __toESM(require("path"));
751
+
752
+ // src/lib/utils/string.utils.ts
753
+ function camelCase(str) {
754
+ const cleaned = str.replace(/[-_](\w)/g, (_, c) => c.toUpperCase());
755
+ return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);
756
+ }
757
+ __name(camelCase, "camelCase");
758
+ function kebabCase(str) {
759
+ return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
760
+ }
761
+ __name(kebabCase, "kebabCase");
762
+ function pascalCase(str) {
763
+ return str.replace(/(?:^|[-_])([a-z])/g, (_, char) => char.toUpperCase());
764
+ }
765
+ __name(pascalCase, "pascalCase");
766
+
767
+ // src/lib/utils/type.utils.ts
768
+ function getTypeScriptType(schemaOrType, config, formatOrNullable, isNullable, context = "type") {
769
+ let schema;
770
+ let nullable;
771
+ if (typeof schemaOrType === "string" || schemaOrType === void 0) {
772
+ schema = {
773
+ type: schemaOrType,
774
+ format: typeof formatOrNullable === "string" ? formatOrNullable : void 0
775
+ };
776
+ nullable = typeof formatOrNullable === "boolean" ? formatOrNullable : isNullable;
777
+ } else {
778
+ schema = schemaOrType;
779
+ nullable = typeof formatOrNullable === "boolean" ? formatOrNullable : schema.nullable;
780
+ }
781
+ if (!schema) {
782
+ return "any";
783
+ }
784
+ if (schema.$ref) {
785
+ const refName = schema.$ref.split("/").pop();
786
+ return nullableType(pascalCase(refName), nullable);
787
+ }
788
+ if (schema.type === "array") {
789
+ const itemType = schema.items ? getTypeScriptType(schema.items, config, void 0, void 0, context) : "unknown";
790
+ return nullable ? `(${itemType}[] | null)` : `${itemType}[]`;
791
+ }
792
+ switch (schema.type) {
793
+ case "string":
794
+ if (schema.format === "date" || schema.format === "date-time") {
795
+ const dateType = config.options.dateType === "Date" ? "Date" : "string";
796
+ return nullableType(dateType, nullable);
797
+ }
798
+ if (schema.format === "binary") {
799
+ const binaryType = context === "type" ? "Blob" : "File";
800
+ return nullableType(binaryType, nullable);
801
+ }
802
+ if (schema.format === "uuid" || schema.format === "email" || schema.format === "uri" || schema.format === "hostname" || schema.format === "ipv4" || schema.format === "ipv6") {
803
+ return nullableType("string", nullable);
804
+ }
805
+ return nullableType("string", nullable);
806
+ case "number":
807
+ case "integer":
808
+ return nullableType("number", nullable);
809
+ case "boolean":
810
+ return nullableType("boolean", nullable);
811
+ case "object":
812
+ return nullableType(context === "type" ? "Record<string, unknown>" : "any", nullable);
813
+ case "null":
814
+ return "null";
815
+ default:
816
+ console.warn(`Unknown swagger type: ${schema.type}`);
817
+ return nullableType("any", nullable);
818
+ }
819
+ }
820
+ __name(getTypeScriptType, "getTypeScriptType");
821
+ function nullableType(type, isNullable) {
822
+ return type + (isNullable ? " | null" : "");
823
+ }
824
+ __name(nullableType, "nullableType");
825
+
826
+ // src/lib/generators/service/service-method/service-method-body.generator.ts
827
+ var _ServiceMethodBodyGenerator = class _ServiceMethodBodyGenerator {
828
+ constructor(config) {
829
+ __publicField(this, "config");
830
+ this.config = config;
831
+ }
832
+ generateMethodBody(operation) {
833
+ const context = this.createGenerationContext(operation);
834
+ const bodyParts = [
835
+ this.generateUrlConstruction(operation, context),
836
+ this.generateQueryParams(context),
837
+ this.generateHeaders(context),
838
+ this.generateMultipartFormData(operation, context),
839
+ this.generateRequestOptions(context),
840
+ this.generateHttpRequest(operation, context)
841
+ ];
842
+ return bodyParts.filter(Boolean).join("\n");
843
+ }
844
+ getRequestBodyType(requestBody) {
845
+ const content = requestBody.content || {};
846
+ const jsonContent = content["application/json"];
847
+ if (jsonContent == null ? void 0 : jsonContent.schema) {
848
+ return getTypeScriptType(jsonContent.schema, this.config, jsonContent.schema.nullable);
849
+ }
850
+ return "any";
851
+ }
852
+ isMultipartFormData(operation) {
853
+ var _a, _b;
854
+ return !!((_b = (_a = operation.requestBody) == null ? void 0 : _a.content) == null ? void 0 : _b["multipart/form-data"]);
855
+ }
856
+ getFormDataFields(operation) {
857
+ var _a, _b, _c, _d;
858
+ if (!this.isMultipartFormData(operation)) {
859
+ return [];
860
+ }
861
+ const properties = ((_d = (_c = (_b = (_a = operation.requestBody) == null ? void 0 : _a.content) == null ? void 0 : _b["multipart/form-data"]) == null ? void 0 : _c.schema) == null ? void 0 : _d.properties) || {};
862
+ return Object.keys(properties);
863
+ }
864
+ getResponseTypeFromResponse(response) {
865
+ var _a, _b, _c;
866
+ const content = response.content || {};
867
+ if (Object.keys(content).length === 0) {
868
+ return "json";
869
+ }
870
+ const responseTypes = [];
871
+ for (const [contentType, mediaType] of Object.entries(content)) {
872
+ const schema = mediaType == null ? void 0 : mediaType.schema;
873
+ const mapping = ((_b = (_a = this.config) == null ? void 0 : _a.options) == null ? void 0 : _b.responseTypeMapping) || {};
874
+ if (mapping[contentType]) {
875
+ responseTypes.push({
876
+ type: mapping[contentType],
877
+ priority: 1,
878
+ contentType
879
+ });
880
+ continue;
881
+ }
882
+ if ((schema == null ? void 0 : schema.format) === "binary" || (schema == null ? void 0 : schema.format) === "byte") {
883
+ responseTypes.push({
884
+ type: "blob",
885
+ priority: 2,
886
+ contentType
887
+ });
888
+ continue;
889
+ }
890
+ if ((schema == null ? void 0 : schema.type) === "string" && ((schema == null ? void 0 : schema.format) === "binary" || (schema == null ? void 0 : schema.format) === "byte")) {
891
+ responseTypes.push({
892
+ type: "blob",
893
+ priority: 2,
894
+ contentType
895
+ });
896
+ continue;
897
+ }
898
+ const inferredType = this.inferResponseTypeFromContentType(contentType);
899
+ let priority = 3;
900
+ if (inferredType === "json") {
901
+ priority = 2;
902
+ }
903
+ responseTypes.push({
904
+ type: inferredType,
905
+ priority,
906
+ contentType
907
+ });
908
+ }
909
+ responseTypes.sort((a, b) => a.priority - b.priority);
910
+ return ((_c = responseTypes[0]) == null ? void 0 : _c.type) || "json";
911
+ }
912
+ createGenerationContext(operation) {
913
+ var _a, _b;
914
+ return {
915
+ pathParams: ((_a = operation.parameters) == null ? void 0 : _a.filter((p) => p.in === "path")) || [],
916
+ queryParams: ((_b = operation.parameters) == null ? void 0 : _b.filter((p) => p.in === "query")) || [],
917
+ hasBody: !!operation.requestBody,
918
+ isMultipart: this.isMultipartFormData(operation),
919
+ formDataFields: this.getFormDataFields(operation),
920
+ responseType: this.determineResponseType(operation)
921
+ };
922
+ }
923
+ generateUrlConstruction(operation, context) {
924
+ let urlExpression = `\`\${this.basePath}${operation.path}\``;
925
+ if (context.pathParams.length > 0) {
926
+ context.pathParams.forEach((param) => {
927
+ urlExpression = urlExpression.replace(`{${param.name}}`, `\${${param.name}}`);
928
+ });
929
+ }
930
+ return `const url = ${urlExpression};`;
931
+ }
932
+ generateQueryParams(context) {
933
+ if (context.queryParams.length === 0) {
934
+ return "";
935
+ }
936
+ const paramMappings = context.queryParams.map((param) => `if (${param.name} !== undefined) {
937
+ params = params.set('${param.name}', String(${param.name}));
938
+ }`).join("\n");
939
+ return `
940
+ let params = new HttpParams();
941
+ ${paramMappings}`;
942
+ }
943
+ generateHeaders(context) {
944
+ const hasCustomHeaders = this.config.options.customHeaders;
945
+ if (!hasCustomHeaders && !context.isMultipart) {
946
+ return "";
947
+ }
948
+ let headerCode = `
949
+ let headers: HttpHeaders;
950
+ if (options?.headers instanceof HttpHeaders) {
951
+ headers = options.headers;
952
+ } else {
953
+ headers = new HttpHeaders(options?.headers);
954
+ }`;
955
+ if (hasCustomHeaders) {
956
+ headerCode += `
957
+ // Add default headers if not already present
958
+ ${Object.entries(this.config.options.customHeaders || {}).map(([key, value]) => `if (!headers.has('${key}')) {
959
+ headers = headers.set('${key}', '${value}');
960
+ }`).join("\n")}`;
961
+ }
962
+ if (context.isMultipart) {
963
+ headerCode += `
964
+ // Remove Content-Type for multipart (browser will set it with boundary)
965
+ headers = headers.delete('Content-Type');`;
966
+ } else if (!context.isMultipart) {
967
+ headerCode += `
968
+ // Set Content-Type for JSON requests if not already set
969
+ if (!headers.has('Content-Type')) {
970
+ headers = headers.set('Content-Type', 'application/json');
971
+ }`;
972
+ }
973
+ return headerCode;
974
+ }
975
+ generateMultipartFormData(operation, context) {
976
+ if (!context.isMultipart || context.formDataFields.length === 0) {
977
+ return "";
978
+ }
979
+ const formDataAppends = context.formDataFields.map((field) => {
980
+ var _a, _b, _c, _d, _e;
981
+ const fieldSchema = (_e = (_d = (_c = (_b = (_a = operation.requestBody) == null ? void 0 : _a.content) == null ? void 0 : _b["multipart/form-data"]) == null ? void 0 : _c.schema) == null ? void 0 : _d.properties) == null ? void 0 : _e[field];
982
+ const isFile = (fieldSchema == null ? void 0 : fieldSchema.type) === "string" && (fieldSchema == null ? void 0 : fieldSchema.format) === "binary";
983
+ const valueExpression = isFile ? field : `String(${field})`;
984
+ return `if (${field} !== undefined) {
985
+ formData.append('${field}', ${valueExpression});
986
+ }`;
987
+ }).join("\n");
988
+ return `
989
+ const formData = new FormData();
990
+ ${formDataAppends}`;
991
+ }
992
+ generateRequestOptions(context) {
993
+ const options = [];
994
+ options.push("observe: observe as any");
995
+ const hasHeaders = this.config.options.customHeaders || context.isMultipart;
996
+ if (hasHeaders) {
997
+ options.push("headers");
998
+ }
999
+ if (context.queryParams.length > 0) {
1000
+ options.push("params");
1001
+ }
1002
+ if (context.responseType !== "json") {
1003
+ options.push(`responseType: '${context.responseType}' as '${context.responseType}'`);
1004
+ }
1005
+ options.push("reportProgress: options?.reportProgress");
1006
+ options.push("withCredentials: options?.withCredentials");
1007
+ if (options.length > 0) {
1008
+ options.push("context: options?.context");
1009
+ }
1010
+ const formattedOptions = options.filter((opt) => opt && !opt.includes("undefined")).join(",\n ");
1011
+ return `
1012
+ const requestOptions: any = {
1013
+ ${formattedOptions}
1014
+ };`;
1015
+ }
1016
+ generateHttpRequest(operation, context) {
1017
+ var _a, _b;
1018
+ const httpMethod = operation.method.toLowerCase();
1019
+ let bodyParam = "";
1020
+ if (context.hasBody) {
1021
+ if (context.isMultipart) {
1022
+ bodyParam = "formData";
1023
+ } else if ((_b = (_a = operation.requestBody) == null ? void 0 : _a.content) == null ? void 0 : _b["application/json"]) {
1024
+ const bodyType = this.getRequestBodyType(operation.requestBody);
1025
+ const isInterface = this.isDataTypeInterface(bodyType);
1026
+ bodyParam = isInterface ? camelCase(bodyType) : "requestBody";
1027
+ }
1028
+ }
1029
+ const methodsWithBody = [
1030
+ "post",
1031
+ "put",
1032
+ "patch"
1033
+ ];
1034
+ if (methodsWithBody.includes(httpMethod)) {
1035
+ return `
1036
+ return this.httpClient.${httpMethod}(url, ${bodyParam || "null"}, requestOptions);`;
1037
+ } else {
1038
+ return `
1039
+ return this.httpClient.${httpMethod}(url, requestOptions);`;
1040
+ }
1041
+ }
1042
+ determineResponseType(operation) {
1043
+ var _a;
1044
+ const successResponses = [
1045
+ "200",
1046
+ "201",
1047
+ "202",
1048
+ "204",
1049
+ "206"
1050
+ ];
1051
+ for (const statusCode of successResponses) {
1052
+ const response = (_a = operation.responses) == null ? void 0 : _a[statusCode];
1053
+ if (!response) continue;
1054
+ return this.getResponseTypeFromResponse(response);
1055
+ }
1056
+ return "json";
1057
+ }
1058
+ isDataTypeInterface(type) {
1059
+ const invalidTypes = [
1060
+ "any",
1061
+ "File",
1062
+ "string",
1063
+ "number",
1064
+ "boolean",
1065
+ "object",
1066
+ "unknown",
1067
+ "[]",
1068
+ "Array"
1069
+ ];
1070
+ return !invalidTypes.some((invalidType) => type.includes(invalidType));
1071
+ }
1072
+ inferResponseTypeFromContentType(contentType) {
1073
+ const normalizedType = contentType.split(";")[0].trim().toLowerCase();
1074
+ if (normalizedType.includes("json") || normalizedType === "application/ld+json" || normalizedType === "application/hal+json" || normalizedType === "application/vnd.api+json") {
1075
+ return "json";
1076
+ }
1077
+ if (normalizedType.includes("xml") || normalizedType === "application/soap+xml" || normalizedType === "application/atom+xml" || normalizedType === "application/rss+xml") {
1078
+ return "text";
1079
+ }
1080
+ if (normalizedType.startsWith("text/")) {
1081
+ const binaryTextTypes = [
1082
+ "text/rtf",
1083
+ "text/cache-manifest",
1084
+ "text/vcard",
1085
+ "text/calendar"
1086
+ ];
1087
+ if (binaryTextTypes.includes(normalizedType)) {
1088
+ return "blob";
1089
+ }
1090
+ return "text";
1091
+ }
1092
+ if (normalizedType === "application/x-www-form-urlencoded" || normalizedType === "multipart/form-data") {
1093
+ return "text";
1094
+ }
1095
+ if (normalizedType === "application/javascript" || normalizedType === "application/typescript" || normalizedType === "application/css" || normalizedType === "application/yaml" || normalizedType === "application/x-yaml" || normalizedType === "application/toml") {
1096
+ return "text";
1097
+ }
1098
+ if (normalizedType.startsWith("image/") || normalizedType.startsWith("audio/") || normalizedType.startsWith("video/") || normalizedType === "application/pdf" || normalizedType === "application/zip" || normalizedType.includes("octet-stream")) {
1099
+ return "arraybuffer";
1100
+ }
1101
+ return "blob";
1102
+ }
1103
+ };
1104
+ __name(_ServiceMethodBodyGenerator, "ServiceMethodBodyGenerator");
1105
+ var ServiceMethodBodyGenerator = _ServiceMethodBodyGenerator;
1106
+
1107
+ // src/lib/generators/service/service-method/service-method-params.generator.ts
1108
+ var _ServiceMethodParamsGenerator = class _ServiceMethodParamsGenerator {
1109
+ constructor(config) {
1110
+ __publicField(this, "config");
1111
+ this.config = config;
1112
+ }
1113
+ generateMethodParameters(operation) {
1114
+ const params = this.generateApiParameters(operation);
1115
+ const optionsParam = this.addOptionsParameter();
1116
+ const combined = [
1117
+ ...params,
1118
+ ...optionsParam
1119
+ ];
1120
+ const seen = /* @__PURE__ */ new Set();
1121
+ const uniqueParams = [];
1122
+ for (const param of combined) {
1123
+ if (!seen.has(param.name)) {
1124
+ seen.add(param.name);
1125
+ uniqueParams.push(param);
1126
+ }
1127
+ }
1128
+ return uniqueParams;
1129
+ }
1130
+ generateApiParameters(operation) {
1131
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1132
+ const params = [];
1133
+ const pathParams = ((_a = operation.parameters) == null ? void 0 : _a.filter((p) => p.in === "path")) || [];
1134
+ pathParams.forEach((param) => {
1135
+ params.push({
1136
+ name: param.name,
1137
+ type: getTypeScriptType(param.schema || param, this.config),
1138
+ hasQuestionToken: !param.required
1139
+ });
1140
+ });
1141
+ if (operation.requestBody && ((_c = (_b = operation.requestBody) == null ? void 0 : _b.content) == null ? void 0 : _c["multipart/form-data"])) {
1142
+ Object.entries((_g = (_f = (_e = (_d = operation.requestBody) == null ? void 0 : _d.content) == null ? void 0 : _e["multipart/form-data"].schema) == null ? void 0 : _f.properties) != null ? _g : {}).forEach(([key, value]) => {
1143
+ params.push({
1144
+ name: key,
1145
+ type: getTypeScriptType(value, this.config, value.nullable),
1146
+ hasQuestionToken: !value.required
1147
+ });
1148
+ });
1149
+ }
1150
+ if (operation.requestBody && ((_i = (_h = operation.requestBody) == null ? void 0 : _h.content) == null ? void 0 : _i["application/json"])) {
1151
+ const bodyType = this.getRequestBodyType(operation.requestBody);
1152
+ const isInterface = this.isDataTypeInterface(bodyType);
1153
+ params.push({
1154
+ name: isInterface ? camelCase(bodyType) : "requestBody",
1155
+ type: bodyType,
1156
+ hasQuestionToken: !operation.requestBody.required
1157
+ });
1158
+ }
1159
+ const queryParams = ((_j = operation.parameters) == null ? void 0 : _j.filter((p) => p.in === "query")) || [];
1160
+ queryParams.forEach((param) => {
1161
+ params.push({
1162
+ name: param.name,
1163
+ type: getTypeScriptType(param.schema || param, this.config),
1164
+ hasQuestionToken: !param.required
1165
+ });
1166
+ });
1167
+ return params;
1168
+ }
1169
+ addOptionsParameter() {
1170
+ return [
1171
+ {
1172
+ name: "observe",
1173
+ type: `'body' | 'events' | 'response'`,
1174
+ hasQuestionToken: true
1175
+ },
1176
+ {
1177
+ name: "options",
1178
+ type: `{ headers?: HttpHeaders; params?: HttpParams; reportProgress?: boolean; responseType?: 'arraybuffer' | 'blob' | 'json' | 'text'; withCredentials?: boolean; context?: HttpContext; }`,
1179
+ hasQuestionToken: true
1180
+ }
1181
+ ];
1182
+ }
1183
+ isDataTypeInterface(type) {
1184
+ const invalidTypes = [
1185
+ "any",
1186
+ "File",
1187
+ "string",
1188
+ "number",
1189
+ "boolean",
1190
+ "object",
1191
+ "unknown",
1192
+ "[]",
1193
+ "Array"
1194
+ ];
1195
+ return !invalidTypes.some((invalidType) => type.includes(invalidType));
1196
+ }
1197
+ getRequestBodyType(requestBody) {
1198
+ const content = requestBody.content || {};
1199
+ const jsonContent = content["application/json"];
1200
+ if (jsonContent == null ? void 0 : jsonContent.schema) {
1201
+ return getTypeScriptType(jsonContent.schema, this.config, jsonContent.schema.nullable);
1202
+ }
1203
+ return "any";
1204
+ }
1205
+ };
1206
+ __name(_ServiceMethodParamsGenerator, "ServiceMethodParamsGenerator");
1207
+ var ServiceMethodParamsGenerator = _ServiceMethodParamsGenerator;
1208
+
1209
+ // src/lib/generators/service/service-method/service-method-overloads.generator.ts
1210
+ var _ServiceMethodOverloadsGenerator = class _ServiceMethodOverloadsGenerator {
1211
+ constructor(config) {
1212
+ __publicField(this, "config");
1213
+ __publicField(this, "paramsGenerator");
1214
+ this.config = config;
1215
+ this.paramsGenerator = new ServiceMethodParamsGenerator(config);
1216
+ }
1217
+ generateMethodOverloads(operation) {
1218
+ const observeTypes = [
1219
+ "body",
1220
+ "response",
1221
+ "events"
1222
+ ];
1223
+ const overloads = [];
1224
+ const responseType = this.determineResponseTypeForOperation(operation);
1225
+ observeTypes.forEach((observe) => {
1226
+ const overload = this.generateMethodOverload(operation, observe, responseType);
1227
+ if (overload) {
1228
+ overloads.push(overload);
1229
+ }
1230
+ });
1231
+ return overloads;
1232
+ }
1233
+ generateMethodOverload(operation, observe, responseType) {
1234
+ const responseDataType = this.generateOverloadResponseType(operation);
1235
+ const params = this.generateOverloadParameters(operation, observe, responseType);
1236
+ const returnType = this.generateOverloadReturnType(responseDataType, observe);
1237
+ return {
1238
+ parameters: params,
1239
+ returnType
1240
+ };
1241
+ }
1242
+ generateOverloadParameters(operation, observe, responseType) {
1243
+ const params = this.paramsGenerator.generateApiParameters(operation);
1244
+ const optionsParam = this.addOverloadOptionsParameter(observe, responseType);
1245
+ const combined = [
1246
+ ...params,
1247
+ ...optionsParam
1248
+ ];
1249
+ const seen = /* @__PURE__ */ new Set();
1250
+ const uniqueParams = [];
1251
+ for (const param of combined) {
1252
+ if (!seen.has(param.name)) {
1253
+ seen.add(param.name);
1254
+ uniqueParams.push(param);
1255
+ }
1256
+ }
1257
+ return uniqueParams;
1258
+ }
1259
+ addOverloadOptionsParameter(observe, responseType) {
1260
+ return [
1261
+ {
1262
+ name: "observe",
1263
+ type: `'${observe}'`,
1264
+ hasQuestionToken: true
1265
+ },
1266
+ {
1267
+ name: "options",
1268
+ type: `{ headers?: HttpHeaders; reportProgress?: boolean; responseType?: '${responseType}'; withCredentials?: boolean; context?: HttpContext; }`,
1269
+ hasQuestionToken: true
1270
+ }
1271
+ ];
1272
+ }
1273
+ generateOverloadResponseType(operation) {
1274
+ var _a, _b, _c;
1275
+ const response = ((_a = operation.responses) == null ? void 0 : _a["200"]) || ((_b = operation.responses) == null ? void 0 : _b["201"]) || ((_c = operation.responses) == null ? void 0 : _c["204"]);
1276
+ if (!response) {
1277
+ return "any";
1278
+ }
1279
+ return this.getResponseType(response);
1280
+ }
1281
+ generateOverloadReturnType(responseType, observe) {
1282
+ switch (observe) {
1283
+ case "body":
1284
+ return `Observable<${responseType}>`;
1285
+ case "response":
1286
+ return `Observable<HttpResponse<${responseType}>>`;
1287
+ case "events":
1288
+ return `Observable<HttpEvent<${responseType}>>`;
1289
+ default:
1290
+ throw new Error(`Unsupported observe type: ${observe}`);
1291
+ }
1292
+ }
1293
+ getResponseTypeFromResponse(response) {
1294
+ var _a, _b, _c;
1295
+ const content = response.content || {};
1296
+ if (Object.keys(content).length === 0) {
1297
+ return "json";
1298
+ }
1299
+ const responseTypes = [];
1300
+ for (const [contentType, mediaType] of Object.entries(content)) {
1301
+ const schema = mediaType == null ? void 0 : mediaType.schema;
1302
+ const mapping = ((_b = (_a = this.config) == null ? void 0 : _a.options) == null ? void 0 : _b.responseTypeMapping) || {};
1303
+ if (mapping[contentType]) {
1304
+ responseTypes.push({
1305
+ type: mapping[contentType],
1306
+ priority: 1,
1307
+ contentType
1308
+ });
1309
+ continue;
1310
+ }
1311
+ if ((schema == null ? void 0 : schema.format) === "binary" || (schema == null ? void 0 : schema.format) === "byte") {
1312
+ responseTypes.push({
1313
+ type: "blob",
1314
+ priority: 2,
1315
+ contentType
1316
+ });
1317
+ continue;
1318
+ }
1319
+ if ((schema == null ? void 0 : schema.type) === "string" && ((schema == null ? void 0 : schema.format) === "binary" || (schema == null ? void 0 : schema.format) === "byte")) {
1320
+ responseTypes.push({
1321
+ type: "blob",
1322
+ priority: 2,
1323
+ contentType
1324
+ });
1325
+ continue;
1326
+ }
1327
+ const inferredType = this.inferResponseTypeFromContentType(contentType);
1328
+ let priority = 3;
1329
+ if (inferredType === "json") {
1330
+ priority = 2;
1331
+ }
1332
+ responseTypes.push({
1333
+ type: inferredType,
1334
+ priority,
1335
+ contentType
1336
+ });
1337
+ }
1338
+ responseTypes.sort((a, b) => a.priority - b.priority);
1339
+ return ((_c = responseTypes[0]) == null ? void 0 : _c.type) || "json";
1340
+ }
1341
+ getResponseType(response) {
1342
+ const responseType = this.getResponseTypeFromResponse(response);
1343
+ switch (responseType) {
1344
+ case "blob":
1345
+ return "Blob";
1346
+ case "arraybuffer":
1347
+ return "ArrayBuffer";
1348
+ case "text":
1349
+ return "string";
1350
+ case "json": {
1351
+ const content = response.content || {};
1352
+ for (const [contentType, mediaType] of Object.entries(content)) {
1353
+ if (this.inferResponseTypeFromContentType(contentType) === "json" && (mediaType == null ? void 0 : mediaType.schema)) {
1354
+ return getTypeScriptType(mediaType.schema, this.config, mediaType.schema.nullable);
1355
+ }
1356
+ }
1357
+ return "any";
1358
+ }
1359
+ default:
1360
+ return "any";
1361
+ }
1362
+ }
1363
+ determineResponseTypeForOperation(operation) {
1364
+ var _a;
1365
+ const successResponses = [
1366
+ "200",
1367
+ "201",
1368
+ "202",
1369
+ "204",
1370
+ "206"
1371
+ ];
1372
+ for (const statusCode of successResponses) {
1373
+ const response = (_a = operation.responses) == null ? void 0 : _a[statusCode];
1374
+ if (!response) continue;
1375
+ return this.getResponseTypeFromResponse(response);
1376
+ }
1377
+ return "json";
1378
+ }
1379
+ inferResponseTypeFromContentType(contentType) {
1380
+ const normalizedType = contentType.split(";")[0].trim().toLowerCase();
1381
+ if (normalizedType.includes("json") || normalizedType === "application/ld+json" || normalizedType === "application/hal+json" || normalizedType === "application/vnd.api+json") {
1382
+ return "json";
1383
+ }
1384
+ if (normalizedType.includes("xml") || normalizedType === "application/soap+xml" || normalizedType === "application/atom+xml" || normalizedType === "application/rss+xml") {
1385
+ return "text";
1386
+ }
1387
+ if (normalizedType.startsWith("text/")) {
1388
+ const binaryTextTypes = [
1389
+ "text/rtf",
1390
+ "text/cache-manifest",
1391
+ "text/vcard",
1392
+ "text/calendar"
1393
+ ];
1394
+ if (binaryTextTypes.includes(normalizedType)) {
1395
+ return "blob";
1396
+ }
1397
+ return "text";
1398
+ }
1399
+ if (normalizedType === "application/x-www-form-urlencoded" || normalizedType === "multipart/form-data") {
1400
+ return "text";
1401
+ }
1402
+ if (normalizedType === "application/javascript" || normalizedType === "application/typescript" || normalizedType === "application/css" || normalizedType === "application/yaml" || normalizedType === "application/x-yaml" || normalizedType === "application/toml") {
1403
+ return "text";
1404
+ }
1405
+ if (normalizedType.startsWith("image/") || normalizedType.startsWith("audio/") || normalizedType.startsWith("video/") || normalizedType === "application/pdf" || normalizedType === "application/zip" || normalizedType.includes("octet-stream")) {
1406
+ return "arraybuffer";
1407
+ }
1408
+ return "blob";
1409
+ }
1410
+ };
1411
+ __name(_ServiceMethodOverloadsGenerator, "ServiceMethodOverloadsGenerator");
1412
+ var ServiceMethodOverloadsGenerator = _ServiceMethodOverloadsGenerator;
1413
+
1414
+ // src/lib/generators/service/service-method.generator.ts
1415
+ var _ServiceMethodGenerator = class _ServiceMethodGenerator {
1416
+ constructor(config) {
1417
+ __publicField(this, "config");
1418
+ __publicField(this, "bodyGenerator");
1419
+ __publicField(this, "overloadsGenerator");
1420
+ __publicField(this, "paramsGenerator");
1421
+ this.config = config;
1422
+ this.bodyGenerator = new ServiceMethodBodyGenerator(config);
1423
+ this.overloadsGenerator = new ServiceMethodOverloadsGenerator(config);
1424
+ this.paramsGenerator = new ServiceMethodParamsGenerator(config);
1425
+ }
1426
+ addServiceMethod(serviceClass, operation) {
1427
+ const methodName = this.generateMethodName(operation);
1428
+ const parameters = this.paramsGenerator.generateMethodParameters(operation);
1429
+ const returnType = this.generateReturnType();
1430
+ const methodBody = this.bodyGenerator.generateMethodBody(operation);
1431
+ const methodOverLoads = this.overloadsGenerator.generateMethodOverloads(operation);
1432
+ serviceClass.addMethod({
1433
+ name: methodName,
1434
+ parameters,
1435
+ returnType,
1436
+ statements: methodBody,
1437
+ overloads: methodOverLoads
1438
+ });
1439
+ }
1440
+ generateMethodName(operation) {
1441
+ if (this.config.options.customizeMethodName) {
1442
+ if (operation.operationId == null) {
1443
+ throw new Error(`Operation ID is required for method name customization of operation: (${operation.method}) ${operation.path}`);
1444
+ }
1445
+ return this.config.options.customizeMethodName(operation.operationId);
1446
+ } else {
1447
+ return this.defaultNameGenerator(operation);
1448
+ }
1449
+ }
1450
+ generateReturnType() {
1451
+ return "Observable<any>";
1452
+ }
1453
+ defaultNameGenerator(operation) {
1454
+ if (operation.operationId) {
1455
+ return camelCase(operation.operationId);
1456
+ }
1457
+ const method = operation.method.toLowerCase();
1458
+ const pathParts = operation.path.split("/").filter((p) => p && !p.startsWith("{"));
1459
+ const resource = pathParts[pathParts.length - 1] || "resource";
1460
+ return `${method}${pascalCase(resource)}`;
1461
+ }
1462
+ };
1463
+ __name(_ServiceMethodGenerator, "ServiceMethodGenerator");
1464
+ var ServiceMethodGenerator = _ServiceMethodGenerator;
1465
+
1466
+ // src/lib/generators/service/service.generator.ts
1467
+ var _ServiceGenerator = class _ServiceGenerator {
1468
+ constructor(swaggerPath, project, config) {
1469
+ __publicField(this, "project");
1470
+ __publicField(this, "parser");
1471
+ __publicField(this, "spec");
1472
+ __publicField(this, "config");
1473
+ __publicField(this, "methodGenerator");
1474
+ this.config = config;
1475
+ this.project = project;
1476
+ this.parser = new SwaggerParser(swaggerPath);
1477
+ this.spec = JSON.parse(require("fs").readFileSync(swaggerPath, "utf8"));
1478
+ this.methodGenerator = new ServiceMethodGenerator(config);
1479
+ }
1480
+ generate(outputRoot) {
1481
+ const outputDir = path4.join(outputRoot, "services");
1482
+ const paths = this.extractPaths();
1483
+ const controllerGroups = this.groupPathsByController(paths);
1484
+ Object.entries(controllerGroups).forEach(([controllerName, operations]) => {
1485
+ this.generateServiceFile(controllerName, operations, outputDir);
1486
+ });
1487
+ }
1488
+ extractPaths() {
1489
+ const paths = [];
1490
+ const swaggerPaths = this.spec.paths || {};
1491
+ Object.entries(swaggerPaths).forEach(([path6, pathItem]) => {
1492
+ const methods = [
1493
+ "get",
1494
+ "post",
1495
+ "put",
1496
+ "patch",
1497
+ "delete",
1498
+ "options",
1499
+ "head"
1500
+ ];
1501
+ methods.forEach((method) => {
1502
+ if (pathItem[method]) {
1503
+ const operation = pathItem[method];
1504
+ paths.push({
1505
+ path: path6,
1506
+ method: method.toUpperCase(),
1507
+ operationId: operation.operationId,
1508
+ summary: operation.summary,
1509
+ description: operation.description,
1510
+ tags: operation.tags || [],
1511
+ parameters: this.parseParameters(operation.parameters || [], pathItem.parameters || []),
1512
+ requestBody: operation.requestBody,
1513
+ responses: operation.responses || {}
1514
+ });
1515
+ }
1516
+ });
1517
+ });
1518
+ return paths;
1519
+ }
1520
+ parseParameters(operationParams, pathParams) {
1521
+ const allParams = [
1522
+ ...pathParams,
1523
+ ...operationParams
1524
+ ];
1525
+ return allParams.map((param) => ({
1526
+ name: param.name,
1527
+ in: param.in,
1528
+ required: param.required || param.in === "path",
1529
+ schema: param.schema,
1530
+ type: param.type,
1531
+ format: param.format,
1532
+ description: param.description
1533
+ }));
1534
+ }
1535
+ groupPathsByController(paths) {
1536
+ const groups = {};
1537
+ paths.forEach((path6) => {
1538
+ let controllerName = "Default";
1539
+ if (path6.tags && path6.tags.length > 0) {
1540
+ controllerName = path6.tags[0];
1541
+ } else {
1542
+ const pathParts = path6.path.split("/").filter((p) => p && !p.startsWith("{"));
1543
+ if (pathParts.length > 1) {
1544
+ controllerName = pascalCase(pathParts[1]);
1545
+ }
1546
+ }
1547
+ controllerName = pascalCase(controllerName);
1548
+ if (!groups[controllerName]) {
1549
+ groups[controllerName] = [];
1550
+ }
1551
+ groups[controllerName].push(path6);
1552
+ });
1553
+ return groups;
1554
+ }
1555
+ generateServiceFile(controllerName, operations, outputDir) {
1556
+ const fileName = `${kebabCase(controllerName)}.service.ts`;
1557
+ const filePath = path4.join(outputDir, fileName);
1558
+ const sourceFile = this.project.createSourceFile(filePath, "", {
1559
+ overwrite: true
1560
+ });
1561
+ const usedTypes = this.collectUsedTypes(operations);
1562
+ this.addImports(sourceFile, usedTypes);
1563
+ this.addServiceClass(sourceFile, controllerName, operations);
1564
+ sourceFile.saveSync();
1565
+ }
1566
+ collectUsedTypes(operations) {
1567
+ const usedTypes = /* @__PURE__ */ new Set();
1568
+ operations.forEach((operation) => {
1569
+ var _a;
1570
+ (_a = operation.parameters) == null ? void 0 : _a.forEach((param) => {
1571
+ this.collectTypesFromSchema(param.schema || param, usedTypes);
1572
+ });
1573
+ if (operation.requestBody) {
1574
+ this.collectTypesFromRequestBody(operation.requestBody, usedTypes);
1575
+ }
1576
+ if (operation.responses) {
1577
+ Object.values(operation.responses).forEach((response) => {
1578
+ this.collectTypesFromResponse(response, usedTypes);
1579
+ });
1580
+ }
1581
+ });
1582
+ return usedTypes;
1583
+ }
1584
+ collectTypesFromSchema(schema, usedTypes) {
1585
+ if (!schema) return;
1586
+ if (schema.$ref) {
1587
+ const refName = schema.$ref.split("/").pop();
1588
+ if (refName) {
1589
+ usedTypes.add(pascalCase(refName));
1590
+ }
1591
+ }
1592
+ if (schema.type === "array" && schema.items) {
1593
+ this.collectTypesFromSchema(schema.items, usedTypes);
1594
+ }
1595
+ if (schema.type === "object" && schema.properties) {
1596
+ Object.values(schema.properties).forEach((prop) => {
1597
+ this.collectTypesFromSchema(prop, usedTypes);
1598
+ });
1599
+ }
1600
+ if (schema.allOf) {
1601
+ schema.allOf.forEach((subSchema) => {
1602
+ this.collectTypesFromSchema(subSchema, usedTypes);
1603
+ });
1604
+ }
1605
+ if (schema.oneOf) {
1606
+ schema.oneOf.forEach((subSchema) => {
1607
+ this.collectTypesFromSchema(subSchema, usedTypes);
1608
+ });
1609
+ }
1610
+ if (schema.anyOf) {
1611
+ schema.anyOf.forEach((subSchema) => {
1612
+ this.collectTypesFromSchema(subSchema, usedTypes);
1613
+ });
1614
+ }
1615
+ }
1616
+ collectTypesFromRequestBody(requestBody, usedTypes) {
1617
+ const content = requestBody.content || {};
1618
+ Object.values(content).forEach((mediaType) => {
1619
+ if (mediaType.schema) {
1620
+ this.collectTypesFromSchema(mediaType.schema, usedTypes);
1621
+ }
1622
+ });
1623
+ }
1624
+ collectTypesFromResponse(response, usedTypes) {
1625
+ const content = response.content || {};
1626
+ Object.values(content).forEach((mediaType) => {
1627
+ if (mediaType.schema) {
1628
+ this.collectTypesFromSchema(mediaType.schema, usedTypes);
1629
+ }
1630
+ });
1631
+ }
1632
+ addImports(sourceFile, usedTypes) {
1633
+ sourceFile.addImportDeclarations([
1634
+ {
1635
+ namedImports: [
1636
+ "Injectable",
1637
+ "inject"
1638
+ ],
1639
+ moduleSpecifier: "@angular/core"
1640
+ },
1641
+ {
1642
+ namedImports: [
1643
+ "HttpClient",
1644
+ "HttpParams",
1645
+ "HttpHeaders",
1646
+ "HttpContext",
1647
+ "HttpResponse",
1648
+ "HttpEvent"
1649
+ ],
1650
+ moduleSpecifier: "@angular/common/http"
1651
+ },
1652
+ {
1653
+ namedImports: [
1654
+ "Observable"
1655
+ ],
1656
+ moduleSpecifier: "rxjs"
1657
+ },
1658
+ {
1659
+ namedImports: [
1660
+ "BASE_PATH"
1661
+ ],
1662
+ moduleSpecifier: "../tokens"
1663
+ }
1664
+ ]);
1665
+ if (usedTypes.size > 0) {
1666
+ sourceFile.addImportDeclaration({
1667
+ namedImports: Array.from(usedTypes).sort(),
1668
+ moduleSpecifier: "../models"
1669
+ });
1670
+ }
1671
+ }
1672
+ addServiceClass(sourceFile, controllerName, operations) {
1673
+ const className = `${controllerName}Service`;
1674
+ sourceFile.insertText(0, SERVICE_GENERATOR_HEADER_COMMENT(controllerName));
1675
+ const serviceClass = sourceFile.addClass({
1676
+ name: className,
1677
+ isExported: true,
1678
+ decorators: [
1679
+ {
1680
+ name: "Injectable",
1681
+ arguments: [
1682
+ '{ providedIn: "root" }'
1683
+ ]
1684
+ }
1685
+ ]
1686
+ });
1687
+ serviceClass.addProperty({
1688
+ name: "httpClient",
1689
+ type: "HttpClient",
1690
+ scope: import_ts_morph3.Scope.Private,
1691
+ isReadonly: true,
1692
+ initializer: "inject(HttpClient)"
1693
+ });
1694
+ serviceClass.addProperty({
1695
+ name: "basePath",
1696
+ type: "string",
1697
+ scope: import_ts_morph3.Scope.Private,
1698
+ isReadonly: true,
1699
+ initializer: "inject(BASE_PATH)"
1700
+ });
1701
+ operations.forEach((operation) => {
1702
+ this.methodGenerator.addServiceMethod(serviceClass, operation);
1703
+ });
1704
+ if (this.hasDuplicateMethodNames(serviceClass.getMethods())) {
1705
+ throw new Error(`Duplicate method names found in service class ${className}. Please ensure unique method names for each operation.`);
1706
+ }
1707
+ }
1708
+ hasDuplicateMethodNames(arr) {
1709
+ return new Set(arr.map((method) => method.getName())).size !== arr.length;
1710
+ }
1711
+ };
1712
+ __name(_ServiceGenerator, "ServiceGenerator");
1713
+ var ServiceGenerator = _ServiceGenerator;
1714
+
1715
+ // src/lib/generators/service/service-index.generator.ts
1716
+ var fs2 = __toESM(require("fs"));
1717
+ var path5 = __toESM(require("path"));
1718
+ var _ServiceIndexGenerator = class _ServiceIndexGenerator {
1719
+ constructor(project) {
1720
+ __publicField(this, "project");
1721
+ this.project = project;
1722
+ }
1723
+ generateIndex(outputRoot) {
1724
+ const servicesDir = path5.join(outputRoot, "services");
1725
+ const indexPath = path5.join(servicesDir, "index.ts");
1726
+ const sourceFile = this.project.createSourceFile(indexPath, "", {
1727
+ overwrite: true
1728
+ });
1729
+ sourceFile.insertText(0, SERVICE_INDEX_GENERATOR_HEADER_COMMENT);
1730
+ const serviceFiles = fs2.readdirSync(servicesDir).filter((file) => file.endsWith(".service.ts")).map((file) => file.replace(".service.ts", ""));
1731
+ serviceFiles.forEach((serviceName) => {
1732
+ const className = pascalCase(serviceName) + "Service";
1733
+ sourceFile.addExportDeclaration({
1734
+ namedExports: [
1735
+ className
1736
+ ],
1737
+ moduleSpecifier: `./${serviceName}.service`
1738
+ });
1739
+ });
1740
+ sourceFile.saveSync();
1741
+ }
1742
+ };
1743
+ __name(_ServiceIndexGenerator, "ServiceIndexGenerator");
1744
+ var ServiceIndexGenerator = _ServiceIndexGenerator;
1745
+
1746
+ // src/lib/core/generator.ts
1747
+ var fs3 = __toESM(require("fs"));
1748
+ function generateFromConfig(config) {
1749
+ return __async(this, null, function* () {
1750
+ var _a;
1751
+ if (!fs3.existsSync(config.input)) {
1752
+ throw new Error(`Input file not found: ${config.input}`);
1753
+ }
1754
+ const outputPath = config.output;
1755
+ const generateServices = (_a = config.options.generateServices) != null ? _a : true;
1756
+ if (!fs3.existsSync(outputPath)) {
1757
+ fs3.mkdirSync(outputPath, {
1758
+ recursive: true
1759
+ });
1760
+ }
1761
+ try {
1762
+ const project = new import_ts_morph4.Project({
1763
+ compilerOptions: __spreadValues({
1764
+ declaration: true,
1765
+ target: import_ts_morph4.ScriptTarget.ES2022,
1766
+ module: import_ts_morph4.ModuleKind.Preserve,
1767
+ strict: true
1768
+ }, config.compilerOptions)
1769
+ });
1770
+ const typeGenerator = new TypeGenerator(config.input, outputPath, config);
1771
+ typeGenerator.generate();
1772
+ console.log(`\u2705 TypeScript interfaces generated`);
1773
+ if (generateServices) {
1774
+ const tokenGenerator = new TokenGenerator(project);
1775
+ tokenGenerator.generate(outputPath);
1776
+ if (config.options.dateType === "Date") {
1777
+ const dateTransformer = new DateTransformerGenerator(project);
1778
+ dateTransformer.generate(outputPath);
1779
+ console.log(`\u2705 Date transformer generated`);
1780
+ }
1781
+ const fileDownloadHelper = new FileDownloadGenerator(project);
1782
+ fileDownloadHelper.generate(outputPath);
1783
+ console.log(`\u2705 File download helper generated`);
1784
+ const serviceGenerator = new ServiceGenerator(config.input, project, config);
1785
+ serviceGenerator.generate(outputPath);
1786
+ const indexGenerator = new ServiceIndexGenerator(project);
1787
+ indexGenerator.generateIndex(outputPath);
1788
+ console.log(`\u2705 Angular services generated`);
1789
+ }
1790
+ console.log("\u{1F389} Generation completed successfully at:", outputPath);
1791
+ } catch (error) {
1792
+ if (error instanceof Error) {
1793
+ console.error("\u274C Error during generation:", error.message);
1794
+ } else {
1795
+ console.error("\u274C Unknown error during generation:", error);
1796
+ }
1797
+ throw error;
1798
+ }
1799
+ });
1800
+ }
1801
+ __name(generateFromConfig, "generateFromConfig");
1802
+ // Annotate the CommonJS export names for ESM import in node:
1803
+ 0 && (module.exports = {
1804
+ SwaggerParser,
1805
+ generateFromConfig
1806
+ });
1807
+ //# sourceMappingURL=index.js.map