ng-openapi 0.0.25-alpha.3 → 0.0.25-alpha.5

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 +111 -24
  2. package/index.d.ts +1 -1
  3. package/index.js +111 -24
  4. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -425,12 +425,14 @@ var TokenGenerator = class {
425
425
  });
426
426
  sourceFile.addImportDeclaration({
427
427
  namedImports: [
428
- "HttpInterceptor"
428
+ "HttpInterceptor",
429
+ "HttpContextToken"
429
430
  ],
430
431
  moduleSpecifier: "@angular/common/http"
431
432
  });
432
433
  const basePathTokenName = this.getBasePathTokenName();
433
434
  const interceptorsTokenName = this.getInterceptorsTokenName();
435
+ const clientContextTokenName = this.getClientContextTokenName();
434
436
  sourceFile.addVariableStatement({
435
437
  isExported: true,
436
438
  declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
@@ -461,7 +463,21 @@ var TokenGenerator = class {
461
463
  }
462
464
  ],
463
465
  leadingTrivia: `/**
464
- * Injection token for the ${this.clientName} client HTTP interceptors
466
+ * Injection token for the ${this.clientName} client HTTP interceptor instances
467
+ */
468
+ `
469
+ });
470
+ sourceFile.addVariableStatement({
471
+ isExported: true,
472
+ declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
473
+ declarations: [
474
+ {
475
+ name: clientContextTokenName,
476
+ initializer: `new HttpContextToken<string>(() => '${this.clientName}')`
477
+ }
478
+ ],
479
+ leadingTrivia: `/**
480
+ * HttpContext token to identify requests belonging to the ${this.clientName} client
465
481
  */
466
482
  `
467
483
  });
@@ -478,6 +494,20 @@ var TokenGenerator = class {
478
494
  leadingTrivia: `/**
479
495
  * @deprecated Use ${basePathTokenName} instead
480
496
  */
497
+ `
498
+ });
499
+ sourceFile.addVariableStatement({
500
+ isExported: true,
501
+ declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
502
+ declarations: [
503
+ {
504
+ name: "CLIENT_CONTEXT_TOKEN",
505
+ initializer: clientContextTokenName
506
+ }
507
+ ],
508
+ leadingTrivia: `/**
509
+ * @deprecated Use ${clientContextTokenName} instead
510
+ */
481
511
  `
482
512
  });
483
513
  }
@@ -491,6 +521,10 @@ var TokenGenerator = class {
491
521
  const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
492
522
  return `HTTP_INTERCEPTORS_${clientSuffix}`;
493
523
  }
524
+ getClientContextTokenName() {
525
+ const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
526
+ return `CLIENT_CONTEXT_TOKEN_${clientSuffix}`;
527
+ }
494
528
  };
495
529
 
496
530
  // src/lib/generators/utility/file-download.generator.ts
@@ -897,10 +931,10 @@ var ProviderGenerator = class {
897
931
  },
898
932
  {
899
933
  name: "interceptors",
900
- type: "HttpInterceptor[]",
934
+ type: "(new (...args: HttpInterceptor[]) => HttpInterceptor)[]",
901
935
  hasQuestionToken: true,
902
936
  docs: [
903
- "Array of HTTP interceptors to apply to this client"
937
+ "Array of HTTP interceptor classes to apply to this client"
904
938
  ]
905
939
  }
906
940
  ]
@@ -919,11 +953,6 @@ const providers: Provider[] = [
919
953
  provide: ${basePathTokenName},
920
954
  useValue: config.basePath
921
955
  },
922
- // Client-specific interceptors token
923
- {
924
- provide: ${interceptorsTokenName},
925
- useValue: config.interceptors || []
926
- },
927
956
  // Base interceptor that handles client-specific interceptors
928
957
  {
929
958
  provide: HTTP_INTERCEPTORS,
@@ -932,14 +961,32 @@ const providers: Provider[] = [
932
961
  }
933
962
  ];
934
963
 
935
- ${hasDateInterceptor ? `// Add date interceptor to client-specific interceptors if enabled
936
- if (config.enableDateTransform !== false) {
937
- const currentInterceptors = config.interceptors || [];
964
+ // Add client-specific interceptor instances
965
+ if (config.interceptors && config.interceptors.length > 0) {
966
+ const interceptorInstances = config.interceptors.map(InterceptorClass => new InterceptorClass());
967
+
968
+ ${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
969
+ if (config.enableDateTransform !== false) {
970
+ interceptorInstances.unshift(new DateInterceptor());
971
+ }` : `// Date transformation not available (dateType: 'string' was used in generation)`}
972
+
973
+ providers.push({
974
+ provide: ${interceptorsTokenName},
975
+ useValue: interceptorInstances
976
+ });
977
+ } ${hasDateInterceptor ? `else if (config.enableDateTransform !== false) {
978
+ // Only date interceptor enabled
938
979
  providers.push({
939
980
  provide: ${interceptorsTokenName},
940
- useValue: [new DateInterceptor(), ...currentInterceptors]
981
+ useValue: [new DateInterceptor()]
941
982
  });
942
- }` : `// Date transformation not available (dateType: 'string' was used in generation)`}
983
+ }` : ``} else {
984
+ // No interceptors
985
+ providers.push({
986
+ provide: ${interceptorsTokenName},
987
+ useValue: []
988
+ });
989
+ }
943
990
 
944
991
  return makeEnvironmentProviders(providers);`;
945
992
  sourceFile.addFunction({
@@ -957,7 +1004,7 @@ return makeEnvironmentProviders(providers);`;
957
1004
  " providers: [",
958
1005
  ` ${functionName}({`,
959
1006
  " basePath: 'https://api.example.com',",
960
- " interceptors: [new LoggingInterceptor(), new AuthInterceptor()]",
1007
+ " interceptors: [AuthInterceptor, LoggingInterceptor] // Classes, not instances",
961
1008
  " }),",
962
1009
  " // other providers...",
963
1010
  " ]",
@@ -1027,6 +1074,7 @@ var BaseInterceptorGenerator = class {
1027
1074
  sourceFile.insertText(0, BASE_INTERCEPTOR_HEADER_COMMENT(this.#clientName));
1028
1075
  const basePathTokenName = this.getBasePathTokenName();
1029
1076
  const interceptorsTokenName = this.getInterceptorsTokenName();
1077
+ const clientContextTokenName = this.getClientContextTokenName();
1030
1078
  sourceFile.addImportDeclarations([
1031
1079
  {
1032
1080
  namedImports: [
@@ -1053,7 +1101,8 @@ var BaseInterceptorGenerator = class {
1053
1101
  {
1054
1102
  namedImports: [
1055
1103
  basePathTokenName,
1056
- interceptorsTokenName
1104
+ interceptorsTokenName,
1105
+ clientContextTokenName
1057
1106
  ],
1058
1107
  moduleSpecifier: "../tokens"
1059
1108
  }
@@ -1072,11 +1121,11 @@ var BaseInterceptorGenerator = class {
1072
1121
  ],
1073
1122
  properties: [
1074
1123
  {
1075
- name: "basePath",
1124
+ name: "clientName",
1076
1125
  type: "string",
1077
1126
  scope: import_ts_morph3.Scope.Private,
1078
1127
  isReadonly: true,
1079
- initializer: `inject(${basePathTokenName})`
1128
+ initializer: `'${this.#clientName}'`
1080
1129
  },
1081
1130
  {
1082
1131
  name: "httpInterceptors",
@@ -1084,6 +1133,13 @@ var BaseInterceptorGenerator = class {
1084
1133
  scope: import_ts_morph3.Scope.Private,
1085
1134
  isReadonly: true,
1086
1135
  initializer: `inject(${interceptorsTokenName})`
1136
+ },
1137
+ {
1138
+ name: "clientContextToken",
1139
+ type: "any",
1140
+ scope: import_ts_morph3.Scope.Private,
1141
+ isReadonly: true,
1142
+ initializer: clientContextTokenName
1087
1143
  }
1088
1144
  ],
1089
1145
  methods: [
@@ -1101,8 +1157,11 @@ var BaseInterceptorGenerator = class {
1101
1157
  ],
1102
1158
  returnType: "Observable<HttpEvent<any>>",
1103
1159
  statements: `
1104
- // Only intercept requests to this client's base path
1105
- if (!req.url.startsWith(this.basePath)) {
1160
+ // Check if this request belongs to this client using HttpContext
1161
+ const requestClientName = req.context.get(this.clientContextToken);
1162
+
1163
+ if (requestClientName !== this.clientName) {
1164
+ // This request doesn't belong to this client, pass it through
1106
1165
  return next.handle(req);
1107
1166
  }
1108
1167
 
@@ -1130,6 +1189,10 @@ var BaseInterceptorGenerator = class {
1130
1189
  const clientSuffix = this.#clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
1131
1190
  return `HTTP_INTERCEPTORS_${clientSuffix}`;
1132
1191
  }
1192
+ getClientContextTokenName() {
1193
+ const clientSuffix = this.#clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
1194
+ return `CLIENT_CONTEXT_TOKEN_${clientSuffix}`;
1195
+ }
1133
1196
  capitalizeFirst(str) {
1134
1197
  return str.charAt(0).toUpperCase() + str.slice(1);
1135
1198
  }
@@ -1232,6 +1295,7 @@ var ServiceMethodBodyGenerator = class {
1232
1295
  this.generateQueryParams(context),
1233
1296
  this.generateHeaders(context),
1234
1297
  this.generateMultipartFormData(operation, context),
1298
+ this.generateContextHelper(),
1235
1299
  this.generateRequestOptions(context),
1236
1300
  this.generateHttpRequest(operation, context)
1237
1301
  ];
@@ -1426,9 +1490,7 @@ ${formDataAppends}`;
1426
1490
  }
1427
1491
  options.push("reportProgress: options?.reportProgress");
1428
1492
  options.push("withCredentials: options?.withCredentials");
1429
- if (options.length > 0) {
1430
- options.push("context: options?.context");
1431
- }
1493
+ options.push("context: this.createContextWithClientId(options?.context)");
1432
1494
  const formattedOptions = options.filter((opt) => opt && !opt.includes("undefined")).join(",\n ");
1433
1495
  return `
1434
1496
  const requestOptions: any = {
@@ -1520,6 +1582,16 @@ return this.httpClient.${httpMethod}(url, requestOptions);`;
1520
1582
  }
1521
1583
  return "blob";
1522
1584
  }
1585
+ generateContextHelper() {
1586
+ return `
1587
+ /**
1588
+ * Creates HttpContext with client identification
1589
+ */
1590
+ private createContextWithClientId(existingContext?: HttpContext): HttpContext {
1591
+ const context = existingContext || new HttpContext();
1592
+ return context.set(this.clientContextToken, '${this.config.clientName || "default"}');
1593
+ }`;
1594
+ }
1523
1595
  };
1524
1596
 
1525
1597
  // src/lib/generators/service/service-method/service-method-params.generator.ts
@@ -2081,6 +2153,7 @@ var ServiceGenerator = class {
2081
2153
  }
2082
2154
  addImports(sourceFile, usedTypes) {
2083
2155
  const basePathTokenName = this.getBasePathTokenName();
2156
+ const clientContextTokenName = this.getClientContextTokenName();
2084
2157
  sourceFile.addImportDeclarations([
2085
2158
  {
2086
2159
  namedImports: [
@@ -2108,7 +2181,8 @@ var ServiceGenerator = class {
2108
2181
  },
2109
2182
  {
2110
2183
  namedImports: [
2111
- basePathTokenName
2184
+ basePathTokenName,
2185
+ clientContextTokenName
2112
2186
  ],
2113
2187
  moduleSpecifier: "../tokens"
2114
2188
  }
@@ -2123,6 +2197,7 @@ var ServiceGenerator = class {
2123
2197
  addServiceClass(sourceFile, controllerName, operations) {
2124
2198
  const className = `${controllerName}Service`;
2125
2199
  const basePathTokenName = this.getBasePathTokenName();
2200
+ const clientContextTokenName = this.getClientContextTokenName();
2126
2201
  sourceFile.insertText(0, SERVICE_GENERATOR_HEADER_COMMENT(controllerName));
2127
2202
  const serviceClass = sourceFile.addClass({
2128
2203
  name: className,
@@ -2150,6 +2225,13 @@ var ServiceGenerator = class {
2150
2225
  isReadonly: true,
2151
2226
  initializer: `inject(${basePathTokenName})`
2152
2227
  });
2228
+ serviceClass.addProperty({
2229
+ name: "clientContextToken",
2230
+ type: "any",
2231
+ scope: import_ts_morph4.Scope.Private,
2232
+ isReadonly: true,
2233
+ initializer: clientContextTokenName
2234
+ });
2153
2235
  operations.forEach((operation) => {
2154
2236
  this.methodGenerator.addServiceMethod(serviceClass, operation);
2155
2237
  });
@@ -2157,6 +2239,11 @@ var ServiceGenerator = class {
2157
2239
  throw new Error(`Duplicate method names found in service class ${className}. Please ensure unique method names for each operation.`);
2158
2240
  }
2159
2241
  }
2242
+ getClientContextTokenName() {
2243
+ const clientName = this.config.clientName || "default";
2244
+ const clientSuffix = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
2245
+ return `CLIENT_CONTEXT_TOKEN_${clientSuffix}`;
2246
+ }
2160
2247
  getBasePathTokenName() {
2161
2248
  const clientName = this.config.clientName || "default";
2162
2249
  const clientSuffix = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
package/index.d.ts CHANGED
@@ -52,7 +52,7 @@ interface NgOpenapiClientConfig {
52
52
  clientName: string;
53
53
  basePath: string;
54
54
  enableDateTransform?: boolean;
55
- interceptors?: HttpInterceptor[];
55
+ interceptors?: (new (...args: HttpInterceptor[]) => HttpInterceptor)[];
56
56
  }
57
57
 
58
58
  interface Parameter {
package/index.js CHANGED
@@ -472,12 +472,14 @@ var _TokenGenerator = class _TokenGenerator {
472
472
  });
473
473
  sourceFile.addImportDeclaration({
474
474
  namedImports: [
475
- "HttpInterceptor"
475
+ "HttpInterceptor",
476
+ "HttpContextToken"
476
477
  ],
477
478
  moduleSpecifier: "@angular/common/http"
478
479
  });
479
480
  const basePathTokenName = this.getBasePathTokenName();
480
481
  const interceptorsTokenName = this.getInterceptorsTokenName();
482
+ const clientContextTokenName = this.getClientContextTokenName();
481
483
  sourceFile.addVariableStatement({
482
484
  isExported: true,
483
485
  declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
@@ -508,7 +510,21 @@ var _TokenGenerator = class _TokenGenerator {
508
510
  }
509
511
  ],
510
512
  leadingTrivia: `/**
511
- * Injection token for the ${this.clientName} client HTTP interceptors
513
+ * Injection token for the ${this.clientName} client HTTP interceptor instances
514
+ */
515
+ `
516
+ });
517
+ sourceFile.addVariableStatement({
518
+ isExported: true,
519
+ declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
520
+ declarations: [
521
+ {
522
+ name: clientContextTokenName,
523
+ initializer: `new HttpContextToken<string>(() => '${this.clientName}')`
524
+ }
525
+ ],
526
+ leadingTrivia: `/**
527
+ * HttpContext token to identify requests belonging to the ${this.clientName} client
512
528
  */
513
529
  `
514
530
  });
@@ -525,6 +541,20 @@ var _TokenGenerator = class _TokenGenerator {
525
541
  leadingTrivia: `/**
526
542
  * @deprecated Use ${basePathTokenName} instead
527
543
  */
544
+ `
545
+ });
546
+ sourceFile.addVariableStatement({
547
+ isExported: true,
548
+ declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
549
+ declarations: [
550
+ {
551
+ name: "CLIENT_CONTEXT_TOKEN",
552
+ initializer: clientContextTokenName
553
+ }
554
+ ],
555
+ leadingTrivia: `/**
556
+ * @deprecated Use ${clientContextTokenName} instead
557
+ */
528
558
  `
529
559
  });
530
560
  }
@@ -538,6 +568,10 @@ var _TokenGenerator = class _TokenGenerator {
538
568
  const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
539
569
  return `HTTP_INTERCEPTORS_${clientSuffix}`;
540
570
  }
571
+ getClientContextTokenName() {
572
+ const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
573
+ return `CLIENT_CONTEXT_TOKEN_${clientSuffix}`;
574
+ }
541
575
  };
542
576
  __name(_TokenGenerator, "TokenGenerator");
543
577
  var TokenGenerator = _TokenGenerator;
@@ -940,10 +974,10 @@ var _ProviderGenerator = class _ProviderGenerator {
940
974
  },
941
975
  {
942
976
  name: "interceptors",
943
- type: "HttpInterceptor[]",
977
+ type: "(new (...args: HttpInterceptor[]) => HttpInterceptor)[]",
944
978
  hasQuestionToken: true,
945
979
  docs: [
946
- "Array of HTTP interceptors to apply to this client"
980
+ "Array of HTTP interceptor classes to apply to this client"
947
981
  ]
948
982
  }
949
983
  ]
@@ -962,11 +996,6 @@ const providers: Provider[] = [
962
996
  provide: ${basePathTokenName},
963
997
  useValue: config.basePath
964
998
  },
965
- // Client-specific interceptors token
966
- {
967
- provide: ${interceptorsTokenName},
968
- useValue: config.interceptors || []
969
- },
970
999
  // Base interceptor that handles client-specific interceptors
971
1000
  {
972
1001
  provide: HTTP_INTERCEPTORS,
@@ -975,14 +1004,32 @@ const providers: Provider[] = [
975
1004
  }
976
1005
  ];
977
1006
 
978
- ${hasDateInterceptor ? `// Add date interceptor to client-specific interceptors if enabled
979
- if (config.enableDateTransform !== false) {
980
- const currentInterceptors = config.interceptors || [];
1007
+ // Add client-specific interceptor instances
1008
+ if (config.interceptors && config.interceptors.length > 0) {
1009
+ const interceptorInstances = config.interceptors.map(InterceptorClass => new InterceptorClass());
1010
+
1011
+ ${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
1012
+ if (config.enableDateTransform !== false) {
1013
+ interceptorInstances.unshift(new DateInterceptor());
1014
+ }` : `// Date transformation not available (dateType: 'string' was used in generation)`}
1015
+
1016
+ providers.push({
1017
+ provide: ${interceptorsTokenName},
1018
+ useValue: interceptorInstances
1019
+ });
1020
+ } ${hasDateInterceptor ? `else if (config.enableDateTransform !== false) {
1021
+ // Only date interceptor enabled
981
1022
  providers.push({
982
1023
  provide: ${interceptorsTokenName},
983
- useValue: [new DateInterceptor(), ...currentInterceptors]
1024
+ useValue: [new DateInterceptor()]
984
1025
  });
985
- }` : `// Date transformation not available (dateType: 'string' was used in generation)`}
1026
+ }` : ``} else {
1027
+ // No interceptors
1028
+ providers.push({
1029
+ provide: ${interceptorsTokenName},
1030
+ useValue: []
1031
+ });
1032
+ }
986
1033
 
987
1034
  return makeEnvironmentProviders(providers);`;
988
1035
  sourceFile.addFunction({
@@ -1000,7 +1047,7 @@ return makeEnvironmentProviders(providers);`;
1000
1047
  " providers: [",
1001
1048
  ` ${functionName}({`,
1002
1049
  " basePath: 'https://api.example.com',",
1003
- " interceptors: [new LoggingInterceptor(), new AuthInterceptor()]",
1050
+ " interceptors: [AuthInterceptor, LoggingInterceptor] // Classes, not instances",
1004
1051
  " }),",
1005
1052
  " // other providers...",
1006
1053
  " ]",
@@ -1070,6 +1117,7 @@ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
1070
1117
  sourceFile.insertText(0, BASE_INTERCEPTOR_HEADER_COMMENT(__privateGet(this, _clientName)));
1071
1118
  const basePathTokenName = this.getBasePathTokenName();
1072
1119
  const interceptorsTokenName = this.getInterceptorsTokenName();
1120
+ const clientContextTokenName = this.getClientContextTokenName();
1073
1121
  sourceFile.addImportDeclarations([
1074
1122
  {
1075
1123
  namedImports: [
@@ -1096,7 +1144,8 @@ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
1096
1144
  {
1097
1145
  namedImports: [
1098
1146
  basePathTokenName,
1099
- interceptorsTokenName
1147
+ interceptorsTokenName,
1148
+ clientContextTokenName
1100
1149
  ],
1101
1150
  moduleSpecifier: "../tokens"
1102
1151
  }
@@ -1115,11 +1164,11 @@ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
1115
1164
  ],
1116
1165
  properties: [
1117
1166
  {
1118
- name: "basePath",
1167
+ name: "clientName",
1119
1168
  type: "string",
1120
1169
  scope: import_ts_morph3.Scope.Private,
1121
1170
  isReadonly: true,
1122
- initializer: `inject(${basePathTokenName})`
1171
+ initializer: `'${__privateGet(this, _clientName)}'`
1123
1172
  },
1124
1173
  {
1125
1174
  name: "httpInterceptors",
@@ -1127,6 +1176,13 @@ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
1127
1176
  scope: import_ts_morph3.Scope.Private,
1128
1177
  isReadonly: true,
1129
1178
  initializer: `inject(${interceptorsTokenName})`
1179
+ },
1180
+ {
1181
+ name: "clientContextToken",
1182
+ type: "any",
1183
+ scope: import_ts_morph3.Scope.Private,
1184
+ isReadonly: true,
1185
+ initializer: clientContextTokenName
1130
1186
  }
1131
1187
  ],
1132
1188
  methods: [
@@ -1144,8 +1200,11 @@ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
1144
1200
  ],
1145
1201
  returnType: "Observable<HttpEvent<any>>",
1146
1202
  statements: `
1147
- // Only intercept requests to this client's base path
1148
- if (!req.url.startsWith(this.basePath)) {
1203
+ // Check if this request belongs to this client using HttpContext
1204
+ const requestClientName = req.context.get(this.clientContextToken);
1205
+
1206
+ if (requestClientName !== this.clientName) {
1207
+ // This request doesn't belong to this client, pass it through
1149
1208
  return next.handle(req);
1150
1209
  }
1151
1210
 
@@ -1173,6 +1232,10 @@ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
1173
1232
  const clientSuffix = __privateGet(this, _clientName).toUpperCase().replace(/[^A-Z0-9]/g, "_");
1174
1233
  return `HTTP_INTERCEPTORS_${clientSuffix}`;
1175
1234
  }
1235
+ getClientContextTokenName() {
1236
+ const clientSuffix = __privateGet(this, _clientName).toUpperCase().replace(/[^A-Z0-9]/g, "_");
1237
+ return `CLIENT_CONTEXT_TOKEN_${clientSuffix}`;
1238
+ }
1176
1239
  capitalizeFirst(str) {
1177
1240
  return str.charAt(0).toUpperCase() + str.slice(1);
1178
1241
  }
@@ -1276,6 +1339,7 @@ var _ServiceMethodBodyGenerator = class _ServiceMethodBodyGenerator {
1276
1339
  this.generateQueryParams(context),
1277
1340
  this.generateHeaders(context),
1278
1341
  this.generateMultipartFormData(operation, context),
1342
+ this.generateContextHelper(),
1279
1343
  this.generateRequestOptions(context),
1280
1344
  this.generateHttpRequest(operation, context)
1281
1345
  ];
@@ -1475,9 +1539,7 @@ ${formDataAppends}`;
1475
1539
  }
1476
1540
  options.push("reportProgress: options?.reportProgress");
1477
1541
  options.push("withCredentials: options?.withCredentials");
1478
- if (options.length > 0) {
1479
- options.push("context: options?.context");
1480
- }
1542
+ options.push("context: this.createContextWithClientId(options?.context)");
1481
1543
  const formattedOptions = options.filter((opt) => opt && !opt.includes("undefined")).join(",\n ");
1482
1544
  return `
1483
1545
  const requestOptions: any = {
@@ -1571,6 +1633,16 @@ return this.httpClient.${httpMethod}(url, requestOptions);`;
1571
1633
  }
1572
1634
  return "blob";
1573
1635
  }
1636
+ generateContextHelper() {
1637
+ return `
1638
+ /**
1639
+ * Creates HttpContext with client identification
1640
+ */
1641
+ private createContextWithClientId(existingContext?: HttpContext): HttpContext {
1642
+ const context = existingContext || new HttpContext();
1643
+ return context.set(this.clientContextToken, '${this.config.clientName || "default"}');
1644
+ }`;
1645
+ }
1574
1646
  };
1575
1647
  __name(_ServiceMethodBodyGenerator, "ServiceMethodBodyGenerator");
1576
1648
  var ServiceMethodBodyGenerator = _ServiceMethodBodyGenerator;
@@ -2133,6 +2205,7 @@ var _ServiceGenerator = class _ServiceGenerator {
2133
2205
  }
2134
2206
  addImports(sourceFile, usedTypes) {
2135
2207
  const basePathTokenName = this.getBasePathTokenName();
2208
+ const clientContextTokenName = this.getClientContextTokenName();
2136
2209
  sourceFile.addImportDeclarations([
2137
2210
  {
2138
2211
  namedImports: [
@@ -2160,7 +2233,8 @@ var _ServiceGenerator = class _ServiceGenerator {
2160
2233
  },
2161
2234
  {
2162
2235
  namedImports: [
2163
- basePathTokenName
2236
+ basePathTokenName,
2237
+ clientContextTokenName
2164
2238
  ],
2165
2239
  moduleSpecifier: "../tokens"
2166
2240
  }
@@ -2175,6 +2249,7 @@ var _ServiceGenerator = class _ServiceGenerator {
2175
2249
  addServiceClass(sourceFile, controllerName, operations) {
2176
2250
  const className = `${controllerName}Service`;
2177
2251
  const basePathTokenName = this.getBasePathTokenName();
2252
+ const clientContextTokenName = this.getClientContextTokenName();
2178
2253
  sourceFile.insertText(0, SERVICE_GENERATOR_HEADER_COMMENT(controllerName));
2179
2254
  const serviceClass = sourceFile.addClass({
2180
2255
  name: className,
@@ -2202,6 +2277,13 @@ var _ServiceGenerator = class _ServiceGenerator {
2202
2277
  isReadonly: true,
2203
2278
  initializer: `inject(${basePathTokenName})`
2204
2279
  });
2280
+ serviceClass.addProperty({
2281
+ name: "clientContextToken",
2282
+ type: "any",
2283
+ scope: import_ts_morph4.Scope.Private,
2284
+ isReadonly: true,
2285
+ initializer: clientContextTokenName
2286
+ });
2205
2287
  operations.forEach((operation) => {
2206
2288
  this.methodGenerator.addServiceMethod(serviceClass, operation);
2207
2289
  });
@@ -2209,6 +2291,11 @@ var _ServiceGenerator = class _ServiceGenerator {
2209
2291
  throw new Error(`Duplicate method names found in service class ${className}. Please ensure unique method names for each operation.`);
2210
2292
  }
2211
2293
  }
2294
+ getClientContextTokenName() {
2295
+ const clientName = this.config.clientName || "default";
2296
+ const clientSuffix = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
2297
+ return `CLIENT_CONTEXT_TOKEN_${clientSuffix}`;
2298
+ }
2212
2299
  getBasePathTokenName() {
2213
2300
  const clientName = this.config.clientName || "default";
2214
2301
  const clientSuffix = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ng-openapi",
3
- "version": "0.0.25-alpha.3",
3
+ "version": "0.0.25-alpha.5",
4
4
  "description": "Generate Angular services and TypeScript types from OpenAPI/Swagger specifications",
5
5
  "keywords": [
6
6
  "angular",