ng-openapi 0.0.24 → 0.0.25-alpha.1

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 (4) hide show
  1. package/cli.cjs +417 -226
  2. package/index.d.ts +9 -1
  3. package/index.js +422 -222
  4. package/package.json +1 -1
package/index.js CHANGED
@@ -7,6 +7,9 @@ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
9
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
+ var __typeError = (msg) => {
11
+ throw TypeError(msg);
12
+ };
10
13
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
14
  var __spreadValues = (a, b) => {
12
15
  for (var prop in b || (b = {}))
@@ -42,6 +45,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
42
45
  ));
43
46
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
44
47
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
48
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
49
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
50
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
51
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
45
52
  var __async = (__this, __arguments, generator) => {
46
53
  return new Promise((resolve, reject) => {
47
54
  var fulfilled = (value) => {
@@ -100,7 +107,7 @@ __name(_SwaggerParser, "SwaggerParser");
100
107
  var SwaggerParser = _SwaggerParser;
101
108
 
102
109
  // src/lib/core/generator.ts
103
- var import_ts_morph4 = require("ts-morph");
110
+ var import_ts_morph5 = require("ts-morph");
104
111
 
105
112
  // src/lib/generators/type/type.generator.ts
106
113
  var import_ts_morph = require("ts-morph");
@@ -135,6 +142,10 @@ var PROVIDER_GENERATOR_HEADER_COMMENT = defaultHeaderComment + `* Generated prov
135
142
  * Do not edit this file manually
136
143
  */
137
144
  `;
145
+ var BASE_INTERCEPTOR_HEADER_COMMENT = /* @__PURE__ */ __name((clientName) => defaultHeaderComment + `* Generated Base Interceptor for client ${clientName}
146
+ * Do not edit this file manually
147
+ */
148
+ `, "BASE_INTERCEPTOR_HEADER_COMMENT");
138
149
 
139
150
  // src/lib/generators/type/type.generator.ts
140
151
  var _TypeGenerator = class _TypeGenerator {
@@ -441,9 +452,11 @@ var TypeGenerator = _TypeGenerator;
441
452
  var import_ts_morph2 = require("ts-morph");
442
453
  var path = __toESM(require("path"));
443
454
  var _TokenGenerator = class _TokenGenerator {
444
- constructor(project) {
455
+ constructor(project, clientName = "default") {
445
456
  __publicField(this, "project");
457
+ __publicField(this, "clientName");
446
458
  this.project = project;
459
+ this.clientName = clientName;
447
460
  }
448
461
  generate(outputDir) {
449
462
  const tokensDir = path.join(outputDir, "tokens");
@@ -453,29 +466,73 @@ var _TokenGenerator = class _TokenGenerator {
453
466
  });
454
467
  sourceFile.addImportDeclaration({
455
468
  namedImports: [
456
- "InjectionToken"
469
+ "InjectionToken",
470
+ "HttpInterceptor"
457
471
  ],
458
472
  moduleSpecifier: "@angular/core"
459
473
  });
474
+ const basePathTokenName = this.getBasePathTokenName();
475
+ const interceptorsTokenName = this.getInterceptorsTokenName();
460
476
  sourceFile.addVariableStatement({
461
477
  isExported: true,
462
478
  declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
463
479
  declarations: [
464
480
  {
465
- name: "BASE_PATH",
466
- initializer: `new InjectionToken<string>('BASE_PATH', {
481
+ name: basePathTokenName,
482
+ initializer: `new InjectionToken<string>('${basePathTokenName}', {
467
483
  providedIn: 'root',
468
484
  factory: () => '/api', // Default fallback
469
485
  })`
470
486
  }
471
487
  ],
472
488
  leadingTrivia: `/**
473
- * Injection token for the base API path
489
+ * Injection token for the ${this.clientName} client base API path
474
490
  */
475
491
  `
476
492
  });
493
+ sourceFile.addVariableStatement({
494
+ isExported: true,
495
+ declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
496
+ declarations: [
497
+ {
498
+ name: interceptorsTokenName,
499
+ initializer: `new InjectionToken<HttpInterceptor[]>('${interceptorsTokenName}', {
500
+ providedIn: 'root',
501
+ factory: () => [], // Default empty array
502
+ })`
503
+ }
504
+ ],
505
+ leadingTrivia: `/**
506
+ * Injection token for the ${this.clientName} client HTTP interceptors
507
+ */
508
+ `
509
+ });
510
+ if (this.clientName === "default") {
511
+ sourceFile.addVariableStatement({
512
+ isExported: true,
513
+ declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
514
+ declarations: [
515
+ {
516
+ name: "BASE_PATH",
517
+ initializer: basePathTokenName
518
+ }
519
+ ],
520
+ leadingTrivia: `/**
521
+ * @deprecated Use ${basePathTokenName} instead
522
+ */
523
+ `
524
+ });
525
+ }
477
526
  sourceFile.saveSync();
478
527
  }
528
+ getBasePathTokenName() {
529
+ const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
530
+ return `BASE_PATH_${clientSuffix}`;
531
+ }
532
+ getInterceptorsTokenName() {
533
+ const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
534
+ return `HTTP_INTERCEPTORS_${clientSuffix}`;
535
+ }
479
536
  };
480
537
  __name(_TokenGenerator, "TokenGenerator");
481
538
  var TokenGenerator = _TokenGenerator;
@@ -796,9 +853,333 @@ var _MainIndexGenerator = class _MainIndexGenerator {
796
853
  __name(_MainIndexGenerator, "MainIndexGenerator");
797
854
  var MainIndexGenerator = _MainIndexGenerator;
798
855
 
799
- // src/lib/generators/service/service.generator.ts
800
- var import_ts_morph3 = require("ts-morph");
856
+ // src/lib/generators/utility/provider.generator.ts
801
857
  var path5 = __toESM(require("path"));
858
+ var _ProviderGenerator = class _ProviderGenerator {
859
+ constructor(project, config) {
860
+ __publicField(this, "project");
861
+ __publicField(this, "config");
862
+ __publicField(this, "clientName");
863
+ this.project = project;
864
+ this.config = config;
865
+ this.clientName = config.clientName || "default";
866
+ }
867
+ generate(outputDir) {
868
+ const filePath = path5.join(outputDir, "providers.ts");
869
+ const sourceFile = this.project.createSourceFile(filePath, "", {
870
+ overwrite: true
871
+ });
872
+ sourceFile.insertText(0, PROVIDER_GENERATOR_HEADER_COMMENT);
873
+ const basePathTokenName = this.getBasePathTokenName();
874
+ const interceptorsTokenName = this.getInterceptorsTokenName();
875
+ const baseInterceptorClassName = `${this.capitalizeFirst(this.clientName)}BaseInterceptor`;
876
+ sourceFile.addImportDeclarations([
877
+ {
878
+ namedImports: [
879
+ "EnvironmentProviders",
880
+ "Provider",
881
+ "makeEnvironmentProviders"
882
+ ],
883
+ moduleSpecifier: "@angular/core"
884
+ },
885
+ {
886
+ namedImports: [
887
+ "HTTP_INTERCEPTORS",
888
+ "HttpInterceptor"
889
+ ],
890
+ moduleSpecifier: "@angular/common/http"
891
+ },
892
+ {
893
+ namedImports: [
894
+ basePathTokenName,
895
+ interceptorsTokenName
896
+ ],
897
+ moduleSpecifier: "./tokens"
898
+ },
899
+ {
900
+ namedImports: [
901
+ baseInterceptorClassName
902
+ ],
903
+ moduleSpecifier: "./utils/base-interceptor"
904
+ }
905
+ ]);
906
+ if (this.config.options.dateType === "Date") {
907
+ sourceFile.addImportDeclaration({
908
+ namedImports: [
909
+ "DateInterceptor"
910
+ ],
911
+ moduleSpecifier: "./utils/date-transformer"
912
+ });
913
+ }
914
+ sourceFile.addInterface({
915
+ name: `${this.capitalizeFirst(this.clientName)}Config`,
916
+ isExported: true,
917
+ docs: [
918
+ `Configuration options for ${this.clientName} client`
919
+ ],
920
+ properties: [
921
+ {
922
+ name: "basePath",
923
+ type: "string",
924
+ docs: [
925
+ "Base API URL"
926
+ ]
927
+ },
928
+ {
929
+ name: "enableDateTransform",
930
+ type: "boolean",
931
+ hasQuestionToken: true,
932
+ docs: [
933
+ "Enable automatic date transformation (default: true)"
934
+ ]
935
+ },
936
+ {
937
+ name: "interceptors",
938
+ type: "HttpInterceptor[]",
939
+ hasQuestionToken: true,
940
+ docs: [
941
+ "Array of HTTP interceptors to apply to this client"
942
+ ]
943
+ }
944
+ ]
945
+ });
946
+ this.addMainProviderFunction(sourceFile, basePathTokenName, interceptorsTokenName, baseInterceptorClassName);
947
+ sourceFile.saveSync();
948
+ }
949
+ addMainProviderFunction(sourceFile, basePathTokenName, interceptorsTokenName, baseInterceptorClassName) {
950
+ const hasDateInterceptor = this.config.options.dateType === "Date";
951
+ const functionName = `provide${this.capitalizeFirst(this.clientName)}Client`;
952
+ const configTypeName = `${this.capitalizeFirst(this.clientName)}Config`;
953
+ const functionBody = `
954
+ const providers: Provider[] = [
955
+ // Base path token for this client
956
+ {
957
+ provide: ${basePathTokenName},
958
+ useValue: config.basePath
959
+ },
960
+ // Client-specific interceptors token
961
+ {
962
+ provide: ${interceptorsTokenName},
963
+ useValue: config.interceptors || []
964
+ },
965
+ // Base interceptor that handles client-specific interceptors
966
+ {
967
+ provide: HTTP_INTERCEPTORS,
968
+ useClass: ${baseInterceptorClassName},
969
+ multi: true
970
+ }
971
+ ];
972
+
973
+ ${hasDateInterceptor ? `// Add date interceptor to client-specific interceptors if enabled
974
+ if (config.enableDateTransform !== false) {
975
+ const currentInterceptors = config.interceptors || [];
976
+ providers.push({
977
+ provide: ${interceptorsTokenName},
978
+ useValue: [new DateInterceptor(), ...currentInterceptors]
979
+ });
980
+ }` : `// Date transformation not available (dateType: 'string' was used in generation)`}
981
+
982
+ return makeEnvironmentProviders(providers);`;
983
+ sourceFile.addFunction({
984
+ name: functionName,
985
+ isExported: true,
986
+ docs: [
987
+ `Provides configuration for ${this.clientName} client`,
988
+ "",
989
+ "@example",
990
+ "```typescript",
991
+ "// In your app.config.ts",
992
+ `import { ${functionName} } from './api/providers';`,
993
+ "",
994
+ "export const appConfig: ApplicationConfig = {",
995
+ " providers: [",
996
+ ` ${functionName}({`,
997
+ " basePath: 'https://api.example.com',",
998
+ " interceptors: [new LoggingInterceptor(), new AuthInterceptor()]",
999
+ " }),",
1000
+ " // other providers...",
1001
+ " ]",
1002
+ "};",
1003
+ "```"
1004
+ ],
1005
+ parameters: [
1006
+ {
1007
+ name: "config",
1008
+ type: configTypeName
1009
+ }
1010
+ ],
1011
+ returnType: "EnvironmentProviders",
1012
+ statements: functionBody
1013
+ });
1014
+ if (this.clientName === "default") {
1015
+ sourceFile.addFunction({
1016
+ name: "provideNgOpenapi",
1017
+ isExported: true,
1018
+ docs: [
1019
+ "@deprecated Use provideDefaultClient instead for better clarity",
1020
+ "Provides configuration for the default client"
1021
+ ],
1022
+ parameters: [
1023
+ {
1024
+ name: "config",
1025
+ type: configTypeName
1026
+ }
1027
+ ],
1028
+ returnType: "EnvironmentProviders",
1029
+ statements: `return ${functionName}(config);`
1030
+ });
1031
+ }
1032
+ }
1033
+ getBasePathTokenName() {
1034
+ const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
1035
+ return `BASE_PATH_${clientSuffix}`;
1036
+ }
1037
+ getInterceptorsTokenName() {
1038
+ const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
1039
+ return `HTTP_INTERCEPTORS_${clientSuffix}`;
1040
+ }
1041
+ capitalizeFirst(str) {
1042
+ return str.charAt(0).toUpperCase() + str.slice(1);
1043
+ }
1044
+ };
1045
+ __name(_ProviderGenerator, "ProviderGenerator");
1046
+ var ProviderGenerator = _ProviderGenerator;
1047
+
1048
+ // src/lib/generators/utility/base-interceptor.generator.ts
1049
+ var import_ts_morph3 = require("ts-morph");
1050
+ var path6 = __toESM(require("path"));
1051
+ var _project, _clientName;
1052
+ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
1053
+ constructor(project, clientName = "default") {
1054
+ __privateAdd(this, _project);
1055
+ __privateAdd(this, _clientName);
1056
+ __privateSet(this, _project, project);
1057
+ __privateSet(this, _clientName, clientName);
1058
+ }
1059
+ generate(outputDir) {
1060
+ const utilsDir = path6.join(outputDir, "utils");
1061
+ const filePath = path6.join(utilsDir, "base-interceptor.ts");
1062
+ const sourceFile = __privateGet(this, _project).createSourceFile(filePath, "", {
1063
+ overwrite: true
1064
+ });
1065
+ sourceFile.insertText(0, BASE_INTERCEPTOR_HEADER_COMMENT(__privateGet(this, _clientName)));
1066
+ const basePathTokenName = this.getBasePathTokenName();
1067
+ const interceptorsTokenName = this.getInterceptorsTokenName();
1068
+ sourceFile.addImportDeclarations([
1069
+ {
1070
+ namedImports: [
1071
+ "HttpEvent",
1072
+ "HttpHandler",
1073
+ "HttpInterceptor",
1074
+ "HttpRequest"
1075
+ ],
1076
+ moduleSpecifier: "@angular/common/http"
1077
+ },
1078
+ {
1079
+ namedImports: [
1080
+ "inject",
1081
+ "Injectable"
1082
+ ],
1083
+ moduleSpecifier: "@angular/core"
1084
+ },
1085
+ {
1086
+ namedImports: [
1087
+ "Observable"
1088
+ ],
1089
+ moduleSpecifier: "rxjs"
1090
+ },
1091
+ {
1092
+ namedImports: [
1093
+ basePathTokenName,
1094
+ interceptorsTokenName
1095
+ ],
1096
+ moduleSpecifier: "../tokens"
1097
+ }
1098
+ ]);
1099
+ sourceFile.addClass({
1100
+ name: `${this.capitalizeFirst(__privateGet(this, _clientName))}BaseInterceptor`,
1101
+ isExported: true,
1102
+ decorators: [
1103
+ {
1104
+ name: "Injectable",
1105
+ arguments: []
1106
+ }
1107
+ ],
1108
+ implements: [
1109
+ "HttpInterceptor"
1110
+ ],
1111
+ properties: [
1112
+ {
1113
+ name: "basePath",
1114
+ type: "string",
1115
+ scope: import_ts_morph3.Scope.Private,
1116
+ isReadonly: true,
1117
+ initializer: `inject(${basePathTokenName})`
1118
+ },
1119
+ {
1120
+ name: "httpInterceptors",
1121
+ type: "HttpInterceptor[]",
1122
+ scope: import_ts_morph3.Scope.Private,
1123
+ isReadonly: true,
1124
+ initializer: `inject(${interceptorsTokenName})`
1125
+ }
1126
+ ],
1127
+ methods: [
1128
+ {
1129
+ name: "intercept",
1130
+ parameters: [
1131
+ {
1132
+ name: "req",
1133
+ type: "HttpRequest<any>"
1134
+ },
1135
+ {
1136
+ name: "next",
1137
+ type: "HttpHandler"
1138
+ }
1139
+ ],
1140
+ returnType: "Observable<HttpEvent<any>>",
1141
+ statements: `
1142
+ // Only intercept requests to this client's base path
1143
+ if (!req.url.startsWith(this.#basePath)) {
1144
+ return next.handle(req);
1145
+ }
1146
+
1147
+ // Apply client-specific interceptors in reverse order
1148
+ let handler = next;
1149
+
1150
+ handler = this.#httpInterceptors.reduceRight(
1151
+ (next, interceptor) => ({
1152
+ handle: (request: HttpRequest<any>) => interceptor.intercept(request, next)
1153
+ }),
1154
+ handler
1155
+ );
1156
+
1157
+ return handler.handle(req);`
1158
+ }
1159
+ ]
1160
+ });
1161
+ sourceFile.saveSync();
1162
+ }
1163
+ getBasePathTokenName() {
1164
+ const clientSuffix = __privateGet(this, _clientName).toUpperCase().replace(/[^A-Z0-9]/g, "_");
1165
+ return `BASE_PATH_${clientSuffix}`;
1166
+ }
1167
+ getInterceptorsTokenName() {
1168
+ const clientSuffix = __privateGet(this, _clientName).toUpperCase().replace(/[^A-Z0-9]/g, "_");
1169
+ return `HTTP_INTERCEPTORS_${clientSuffix}`;
1170
+ }
1171
+ capitalizeFirst(str) {
1172
+ return str.charAt(0).toUpperCase() + str.slice(1);
1173
+ }
1174
+ };
1175
+ _project = new WeakMap();
1176
+ _clientName = new WeakMap();
1177
+ __name(_BaseInterceptorGenerator, "BaseInterceptorGenerator");
1178
+ var BaseInterceptorGenerator = _BaseInterceptorGenerator;
1179
+
1180
+ // src/lib/generators/service/service.generator.ts
1181
+ var import_ts_morph4 = require("ts-morph");
1182
+ var path7 = __toESM(require("path"));
802
1183
 
803
1184
  // src/lib/utils/string.utils.ts
804
1185
  function camelCase(str) {
@@ -1594,7 +1975,7 @@ var _ServiceGenerator = class _ServiceGenerator {
1594
1975
  this.methodGenerator = new ServiceMethodGenerator(config);
1595
1976
  }
1596
1977
  generate(outputRoot) {
1597
- const outputDir = path5.join(outputRoot, "services");
1978
+ const outputDir = path7.join(outputRoot, "services");
1598
1979
  const paths = this.extractPaths();
1599
1980
  const controllerGroups = this.groupPathsByController(paths);
1600
1981
  Object.entries(controllerGroups).forEach(([controllerName, operations]) => {
@@ -1604,7 +1985,7 @@ var _ServiceGenerator = class _ServiceGenerator {
1604
1985
  extractPaths() {
1605
1986
  const paths = [];
1606
1987
  const swaggerPaths = this.spec.paths || {};
1607
- Object.entries(swaggerPaths).forEach(([path8, pathItem]) => {
1988
+ Object.entries(swaggerPaths).forEach(([path9, pathItem]) => {
1608
1989
  const methods = [
1609
1990
  "get",
1610
1991
  "post",
@@ -1618,7 +1999,7 @@ var _ServiceGenerator = class _ServiceGenerator {
1618
1999
  if (pathItem[method]) {
1619
2000
  const operation = pathItem[method];
1620
2001
  paths.push({
1621
- path: path8,
2002
+ path: path9,
1622
2003
  method: method.toUpperCase(),
1623
2004
  operationId: operation.operationId,
1624
2005
  summary: operation.summary,
@@ -1650,12 +2031,12 @@ var _ServiceGenerator = class _ServiceGenerator {
1650
2031
  }
1651
2032
  groupPathsByController(paths) {
1652
2033
  const groups = {};
1653
- paths.forEach((path8) => {
2034
+ paths.forEach((path9) => {
1654
2035
  let controllerName = "Default";
1655
- if (path8.tags && path8.tags.length > 0) {
1656
- controllerName = path8.tags[0];
2036
+ if (path9.tags && path9.tags.length > 0) {
2037
+ controllerName = path9.tags[0];
1657
2038
  } else {
1658
- const pathParts = path8.path.split("/").filter((p) => p && !p.startsWith("{"));
2039
+ const pathParts = path9.path.split("/").filter((p) => p && !p.startsWith("{"));
1659
2040
  if (pathParts.length > 1) {
1660
2041
  controllerName = pascalCase(pathParts[1]);
1661
2042
  }
@@ -1664,13 +2045,13 @@ var _ServiceGenerator = class _ServiceGenerator {
1664
2045
  if (!groups[controllerName]) {
1665
2046
  groups[controllerName] = [];
1666
2047
  }
1667
- groups[controllerName].push(path8);
2048
+ groups[controllerName].push(path9);
1668
2049
  });
1669
2050
  return groups;
1670
2051
  }
1671
2052
  generateServiceFile(controllerName, operations, outputDir) {
1672
2053
  const fileName = `${camelCase(controllerName)}.service.ts`;
1673
- const filePath = path5.join(outputDir, fileName);
2054
+ const filePath = path7.join(outputDir, fileName);
1674
2055
  const sourceFile = this.project.createSourceFile(filePath, "", {
1675
2056
  overwrite: true
1676
2057
  });
@@ -1746,6 +2127,7 @@ var _ServiceGenerator = class _ServiceGenerator {
1746
2127
  });
1747
2128
  }
1748
2129
  addImports(sourceFile, usedTypes) {
2130
+ const basePathTokenName = this.getBasePathTokenName();
1749
2131
  sourceFile.addImportDeclarations([
1750
2132
  {
1751
2133
  namedImports: [
@@ -1773,7 +2155,7 @@ var _ServiceGenerator = class _ServiceGenerator {
1773
2155
  },
1774
2156
  {
1775
2157
  namedImports: [
1776
- "BASE_PATH"
2158
+ basePathTokenName
1777
2159
  ],
1778
2160
  moduleSpecifier: "../tokens"
1779
2161
  }
@@ -1787,6 +2169,7 @@ var _ServiceGenerator = class _ServiceGenerator {
1787
2169
  }
1788
2170
  addServiceClass(sourceFile, controllerName, operations) {
1789
2171
  const className = `${controllerName}Service`;
2172
+ const basePathTokenName = this.getBasePathTokenName();
1790
2173
  sourceFile.insertText(0, SERVICE_GENERATOR_HEADER_COMMENT(controllerName));
1791
2174
  const serviceClass = sourceFile.addClass({
1792
2175
  name: className,
@@ -1803,16 +2186,16 @@ var _ServiceGenerator = class _ServiceGenerator {
1803
2186
  serviceClass.addProperty({
1804
2187
  name: "httpClient",
1805
2188
  type: "HttpClient",
1806
- scope: import_ts_morph3.Scope.Private,
2189
+ scope: import_ts_morph4.Scope.Private,
1807
2190
  isReadonly: true,
1808
2191
  initializer: "inject(HttpClient)"
1809
2192
  });
1810
2193
  serviceClass.addProperty({
1811
2194
  name: "basePath",
1812
2195
  type: "string",
1813
- scope: import_ts_morph3.Scope.Private,
2196
+ scope: import_ts_morph4.Scope.Private,
1814
2197
  isReadonly: true,
1815
- initializer: "inject(BASE_PATH)"
2198
+ initializer: `inject(${basePathTokenName})`
1816
2199
  });
1817
2200
  operations.forEach((operation) => {
1818
2201
  this.methodGenerator.addServiceMethod(serviceClass, operation);
@@ -1821,6 +2204,11 @@ var _ServiceGenerator = class _ServiceGenerator {
1821
2204
  throw new Error(`Duplicate method names found in service class ${className}. Please ensure unique method names for each operation.`);
1822
2205
  }
1823
2206
  }
2207
+ getBasePathTokenName() {
2208
+ const clientName = this.config.clientName || "default";
2209
+ const clientSuffix = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
2210
+ return `BASE_PATH_${clientSuffix}`;
2211
+ }
1824
2212
  hasDuplicateMethodNames(arr) {
1825
2213
  return new Set(arr.map((method) => method.getName())).size !== arr.length;
1826
2214
  }
@@ -1830,15 +2218,15 @@ var ServiceGenerator = _ServiceGenerator;
1830
2218
 
1831
2219
  // src/lib/generators/service/service-index.generator.ts
1832
2220
  var fs2 = __toESM(require("fs"));
1833
- var path6 = __toESM(require("path"));
2221
+ var path8 = __toESM(require("path"));
1834
2222
  var _ServiceIndexGenerator = class _ServiceIndexGenerator {
1835
2223
  constructor(project) {
1836
2224
  __publicField(this, "project");
1837
2225
  this.project = project;
1838
2226
  }
1839
2227
  generateIndex(outputRoot) {
1840
- const servicesDir = path6.join(outputRoot, "services");
1841
- const indexPath = path6.join(servicesDir, "index.ts");
2228
+ const servicesDir = path8.join(outputRoot, "services");
2229
+ const indexPath = path8.join(servicesDir, "index.ts");
1842
2230
  const sourceFile = this.project.createSourceFile(indexPath, "", {
1843
2231
  overwrite: true
1844
2232
  });
@@ -1859,197 +2247,6 @@ var _ServiceIndexGenerator = class _ServiceIndexGenerator {
1859
2247
  __name(_ServiceIndexGenerator, "ServiceIndexGenerator");
1860
2248
  var ServiceIndexGenerator = _ServiceIndexGenerator;
1861
2249
 
1862
- // src/lib/generators/utility/provider.generator.ts
1863
- var path7 = __toESM(require("path"));
1864
- var _ProviderGenerator = class _ProviderGenerator {
1865
- constructor(project, config) {
1866
- __publicField(this, "project");
1867
- __publicField(this, "config");
1868
- this.project = project;
1869
- this.config = config;
1870
- }
1871
- generate(outputDir) {
1872
- const filePath = path7.join(outputDir, "providers.ts");
1873
- const sourceFile = this.project.createSourceFile(filePath, "", {
1874
- overwrite: true
1875
- });
1876
- sourceFile.insertText(0, PROVIDER_GENERATOR_HEADER_COMMENT);
1877
- sourceFile.addImportDeclarations([
1878
- {
1879
- namedImports: [
1880
- "EnvironmentProviders",
1881
- "Provider",
1882
- "makeEnvironmentProviders"
1883
- ],
1884
- moduleSpecifier: "@angular/core"
1885
- },
1886
- {
1887
- namedImports: [
1888
- "HTTP_INTERCEPTORS"
1889
- ],
1890
- moduleSpecifier: "@angular/common/http"
1891
- },
1892
- {
1893
- namedImports: [
1894
- "BASE_PATH"
1895
- ],
1896
- moduleSpecifier: "./tokens"
1897
- }
1898
- ]);
1899
- if (this.config.options.dateType === "Date") {
1900
- sourceFile.addImportDeclaration({
1901
- namedImports: [
1902
- "DateInterceptor"
1903
- ],
1904
- moduleSpecifier: "./utils/date-transformer"
1905
- });
1906
- }
1907
- sourceFile.addInterface({
1908
- name: "NgOpenapiConfig",
1909
- isExported: true,
1910
- docs: [
1911
- "Configuration options for ng-openapi providers"
1912
- ],
1913
- properties: [
1914
- {
1915
- name: "basePath",
1916
- type: "string",
1917
- docs: [
1918
- "Base API URL"
1919
- ]
1920
- },
1921
- {
1922
- name: "enableDateTransform",
1923
- type: "boolean",
1924
- hasQuestionToken: true,
1925
- docs: [
1926
- "Enable automatic date transformation (default: true)"
1927
- ]
1928
- }
1929
- ]
1930
- });
1931
- this.addMainProviderFunction(sourceFile);
1932
- this.addAsyncProviderFunction(sourceFile);
1933
- sourceFile.saveSync();
1934
- }
1935
- addMainProviderFunction(sourceFile) {
1936
- const hasDateInterceptor = this.config.options.dateType === "Date";
1937
- const functionBody = `
1938
- const providers: Provider[] = [
1939
- // Base path token
1940
- {
1941
- provide: BASE_PATH,
1942
- useValue: config.basePath
1943
- }
1944
- ];
1945
-
1946
- ${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
1947
- if (config.enableDateTransform !== false) {
1948
- providers.push({
1949
- provide: HTTP_INTERCEPTORS,
1950
- useClass: DateInterceptor,
1951
- multi: true
1952
- });
1953
- }` : `// Date transformation not available (dateType: 'string' was used in generation)`}
1954
-
1955
- return makeEnvironmentProviders(providers);`;
1956
- sourceFile.addFunction({
1957
- name: "provideNgOpenapi",
1958
- isExported: true,
1959
- docs: [
1960
- "Provides all necessary configuration for ng-openapi generated services",
1961
- "",
1962
- "@example",
1963
- "```typescript",
1964
- "// In your app.config.ts",
1965
- "import { provideNgOpenapi } from './api/providers';",
1966
- "",
1967
- "export const appConfig: ApplicationConfig = {",
1968
- " providers: [",
1969
- " provideNgOpenapi({",
1970
- " basePath: 'https://api.example.com'",
1971
- " }),",
1972
- " // other providers...",
1973
- " ]",
1974
- "};",
1975
- "```"
1976
- ],
1977
- parameters: [
1978
- {
1979
- name: "config",
1980
- type: "NgOpenapiConfig"
1981
- }
1982
- ],
1983
- returnType: "EnvironmentProviders",
1984
- statements: functionBody
1985
- });
1986
- }
1987
- addAsyncProviderFunction(sourceFile) {
1988
- const hasDateInterceptor = this.config.options.dateType === "Date";
1989
- const functionBody = `
1990
- const providers: Provider[] = [];
1991
-
1992
- // Handle async base path
1993
- if (typeof config.basePath === 'string') {
1994
- providers.push({
1995
- provide: BASE_PATH,
1996
- useValue: config.basePath
1997
- });
1998
- } else {
1999
- providers.push({
2000
- provide: BASE_PATH,
2001
- useFactory: config.basePath
2002
- });
2003
- }
2004
-
2005
- ${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
2006
- if (config.enableDateTransform !== false) {
2007
- providers.push({
2008
- provide: HTTP_INTERCEPTORS,
2009
- useClass: DateInterceptor,
2010
- multi: true
2011
- });
2012
- }` : `// Date transformation not available (dateType: 'string' was used in generation)`}
2013
-
2014
- return makeEnvironmentProviders(providers);`;
2015
- sourceFile.addFunction({
2016
- name: "provideNgOpenapiAsync",
2017
- isExported: true,
2018
- docs: [
2019
- "Alternative function for cases where you need to handle async configuration",
2020
- "",
2021
- "@example",
2022
- "```typescript",
2023
- "// In your app.config.ts",
2024
- "import { provideNgOpenapiAsync } from './api/providers';",
2025
- "",
2026
- "export const appConfig: ApplicationConfig = {",
2027
- " providers: [",
2028
- " provideNgOpenapiAsync({",
2029
- " basePath: () => import('./config').then(c => c.apiConfig.baseUrl)",
2030
- " }),",
2031
- " // other providers...",
2032
- " ]",
2033
- "};",
2034
- "```"
2035
- ],
2036
- parameters: [
2037
- {
2038
- name: "config",
2039
- type: `{
2040
- basePath: string | (() => Promise<string>);
2041
- enableDateTransform?: boolean;
2042
- }`
2043
- }
2044
- ],
2045
- returnType: "EnvironmentProviders",
2046
- statements: functionBody
2047
- });
2048
- }
2049
- };
2050
- __name(_ProviderGenerator, "ProviderGenerator");
2051
- var ProviderGenerator = _ProviderGenerator;
2052
-
2053
2250
  // src/lib/core/generator.ts
2054
2251
  var fs3 = __toESM(require("fs"));
2055
2252
  function generateFromConfig(config) {
@@ -2066,11 +2263,11 @@ function generateFromConfig(config) {
2066
2263
  });
2067
2264
  }
2068
2265
  try {
2069
- const project = new import_ts_morph4.Project({
2266
+ const project = new import_ts_morph5.Project({
2070
2267
  compilerOptions: __spreadValues({
2071
2268
  declaration: true,
2072
- target: import_ts_morph4.ScriptTarget.ES2022,
2073
- module: import_ts_morph4.ModuleKind.Preserve,
2269
+ target: import_ts_morph5.ScriptTarget.ES2022,
2270
+ module: import_ts_morph5.ModuleKind.Preserve,
2074
2271
  strict: true
2075
2272
  }, config.compilerOptions)
2076
2273
  });
@@ -2083,11 +2280,9 @@ function generateFromConfig(config) {
2083
2280
  if (config.options.dateType === "Date") {
2084
2281
  const dateTransformer = new DateTransformerGenerator(project);
2085
2282
  dateTransformer.generate(outputPath);
2086
- console.log(`\u2705 Date transformer generated`);
2087
2283
  }
2088
2284
  const fileDownloadHelper = new FileDownloadGenerator(project);
2089
2285
  fileDownloadHelper.generate(outputPath);
2090
- console.log(`\u2705 File download helper generated`);
2091
2286
  const serviceGenerator = new ServiceGenerator(config.input, project, config);
2092
2287
  serviceGenerator.generate(outputPath);
2093
2288
  const indexGenerator = new ServiceIndexGenerator(project);
@@ -2095,11 +2290,16 @@ function generateFromConfig(config) {
2095
2290
  console.log(`\u2705 Angular services generated`);
2096
2291
  const providerGenerator = new ProviderGenerator(project, config);
2097
2292
  providerGenerator.generate(outputPath);
2098
- console.log(`\u2705 Provider functions generated`);
2293
+ const baseInterceptorGenerator = new BaseInterceptorGenerator(project, config.clientName);
2294
+ baseInterceptorGenerator.generate(outputPath);
2099
2295
  }
2100
2296
  const mainIndexGenerator = new MainIndexGenerator(project, config);
2101
2297
  mainIndexGenerator.generateMainIndex(outputPath);
2102
- console.log("\u{1F389} Generation completed successfully at:", outputPath);
2298
+ if (config.clientName) {
2299
+ console.log(`\u{1F389} ${config.clientName} Generation completed successfully at: ${outputPath}`);
2300
+ } else {
2301
+ console.log("\u{1F389} Generation completed successfully at:", outputPath);
2302
+ }
2103
2303
  } catch (error) {
2104
2304
  if (error instanceof Error) {
2105
2305
  console.error("\u274C Error during generation:", error.message);