ng-openapi 0.3.1-pr-114-feat-functional-client-interceptors-52e79cb.0 → 0.3.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.
- package/README.md +5 -9
- package/cli.cjs +99 -242
- package/index.d.ts +3 -11
- package/index.js +100 -247
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -151,13 +151,11 @@ The simplest way to integrate ng-openapi is using the provider function:
|
|
|
151
151
|
```typescript
|
|
152
152
|
// In your app.config.ts
|
|
153
153
|
import { ApplicationConfig } from "@angular/core";
|
|
154
|
-
import { provideHttpClient, withInterceptors } from "@angular/common/http";
|
|
155
154
|
import { provideDefaultClient } from "./api/providers";
|
|
156
|
-
import { defaultClientInterceptor } from "./api/utils/base-interceptor";
|
|
157
155
|
|
|
158
156
|
export const appConfig: ApplicationConfig = {
|
|
159
157
|
providers: [
|
|
160
|
-
|
|
158
|
+
// One-line setup with automatic interceptor configuration
|
|
161
159
|
provideDefaultClient({
|
|
162
160
|
basePath: "https://api.example.com",
|
|
163
161
|
}),
|
|
@@ -166,13 +164,12 @@ export const appConfig: ApplicationConfig = {
|
|
|
166
164
|
};
|
|
167
165
|
```
|
|
168
166
|
|
|
169
|
-
> The provider function is named after your `clientName` (e.g. `clientName: "PetStore"` → `providePetStoreClient`); without a `clientName` it is `provideDefaultClient`.
|
|
167
|
+
> The provider function is named after your `clientName` (e.g. `clientName: "PetStore"` → `providePetStoreClient`); without a `clientName` it is `provideDefaultClient`.
|
|
170
168
|
|
|
171
|
-
That's it! This configures:
|
|
169
|
+
That's it! This automatically configures:
|
|
172
170
|
|
|
173
171
|
- ✅ BASE_PATH token
|
|
174
|
-
- ✅
|
|
175
|
-
- ✅ Date transformation (if using Date type)
|
|
172
|
+
- ✅ Date transformation interceptor (if using Date type)
|
|
176
173
|
|
|
177
174
|
### Advanced Provider Options
|
|
178
175
|
|
|
@@ -183,11 +180,10 @@ provideDefaultClient({
|
|
|
183
180
|
enableDateTransform: false,
|
|
184
181
|
});
|
|
185
182
|
|
|
186
|
-
// Client-specific interceptors
|
|
183
|
+
// Client-specific interceptors (classes, not instances)
|
|
187
184
|
provideDefaultClient({
|
|
188
185
|
basePath: "https://api.example.com",
|
|
189
186
|
interceptors: [AuthInterceptor, LoggingInterceptor],
|
|
190
|
-
interceptorFns: [authInterceptorFn],
|
|
191
187
|
});
|
|
192
188
|
```
|
|
193
189
|
|
package/cli.cjs
CHANGED
|
@@ -260,14 +260,6 @@ function getServiceClassName(controllerName, naming) {
|
|
|
260
260
|
return decorate(pascalCase(controllerName), "Service", naming);
|
|
261
261
|
}
|
|
262
262
|
__name(getServiceClassName, "getServiceClassName");
|
|
263
|
-
function getBaseInterceptorClassName(clientName = "default") {
|
|
264
|
-
return `${clientName.charAt(0).toUpperCase()}${clientName.slice(1)}BaseInterceptor`;
|
|
265
|
-
}
|
|
266
|
-
__name(getBaseInterceptorClassName, "getBaseInterceptorClassName");
|
|
267
|
-
function getClientInterceptorFnName(clientName = "default") {
|
|
268
|
-
return `${clientName.charAt(0).toLowerCase()}${clientName.slice(1)}ClientInterceptor`;
|
|
269
|
-
}
|
|
270
|
-
__name(getClientInterceptorFnName, "getClientInterceptorFnName");
|
|
271
263
|
function getModelTypeName(rawName, naming) {
|
|
272
264
|
return decorate(pascalCaseForEnums(rawName), "", naming);
|
|
273
265
|
}
|
|
@@ -864,11 +856,11 @@ function getBasePathTokenName(clientName = "default") {
|
|
|
864
856
|
return `BASE_PATH_${clientSuffix}`;
|
|
865
857
|
}
|
|
866
858
|
__name(getBasePathTokenName, "getBasePathTokenName");
|
|
867
|
-
function
|
|
859
|
+
function getInterceptorsTokenName(clientName = "default") {
|
|
868
860
|
const clientSuffix = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
869
|
-
return `
|
|
861
|
+
return `HTTP_INTERCEPTORS_${clientSuffix}`;
|
|
870
862
|
}
|
|
871
|
-
__name(
|
|
863
|
+
__name(getInterceptorsTokenName, "getInterceptorsTokenName");
|
|
872
864
|
|
|
873
865
|
// ../shared/src/utils/functions/duplicate-function-name.ts
|
|
874
866
|
function hasDuplicateFunctionNames(arr) {
|
|
@@ -953,7 +945,7 @@ var fs3 = __toESM(require("fs"));
|
|
|
953
945
|
var path14 = __toESM(require("path"));
|
|
954
946
|
|
|
955
947
|
// package.json
|
|
956
|
-
var version = "0.3.
|
|
948
|
+
var version = "0.3.1";
|
|
957
949
|
|
|
958
950
|
// src/lib/core/generator.ts
|
|
959
951
|
var import_ts_morph10 = require("ts-morph");
|
|
@@ -1651,15 +1643,15 @@ var TokenGenerator = class {
|
|
|
1651
1643
|
},
|
|
1652
1644
|
{
|
|
1653
1645
|
namedImports: [
|
|
1654
|
-
"
|
|
1646
|
+
"HttpInterceptor",
|
|
1655
1647
|
"HttpContextToken"
|
|
1656
1648
|
],
|
|
1657
1649
|
moduleSpecifier: "@angular/common/http"
|
|
1658
1650
|
}
|
|
1659
1651
|
]);
|
|
1660
|
-
const basePathTokenName = getBasePathTokenName(
|
|
1661
|
-
const
|
|
1662
|
-
const clientContextTokenName = getClientContextTokenName(
|
|
1652
|
+
const basePathTokenName = this.getBasePathTokenName();
|
|
1653
|
+
const interceptorsTokenName = this.getInterceptorsTokenName();
|
|
1654
|
+
const clientContextTokenName = this.getClientContextTokenName();
|
|
1663
1655
|
sourceFile.addVariableStatement({
|
|
1664
1656
|
isExported: true,
|
|
1665
1657
|
declarationKind: import_ts_morph5.VariableDeclarationKind.Const,
|
|
@@ -1682,16 +1674,15 @@ var TokenGenerator = class {
|
|
|
1682
1674
|
declarationKind: import_ts_morph5.VariableDeclarationKind.Const,
|
|
1683
1675
|
declarations: [
|
|
1684
1676
|
{
|
|
1685
|
-
name:
|
|
1686
|
-
initializer: `new InjectionToken<
|
|
1677
|
+
name: interceptorsTokenName,
|
|
1678
|
+
initializer: `new InjectionToken<HttpInterceptor[]>('${interceptorsTokenName}', {
|
|
1687
1679
|
providedIn: 'root',
|
|
1688
1680
|
factory: () => [], // Default empty array
|
|
1689
1681
|
})`
|
|
1690
1682
|
}
|
|
1691
1683
|
],
|
|
1692
1684
|
leadingTrivia: `/**
|
|
1693
|
-
* Injection token
|
|
1694
|
-
* normalized to functional interceptors. Populated by the client's provide function.
|
|
1685
|
+
* Injection token for the ${this.clientName} client HTTP interceptor instances
|
|
1695
1686
|
*/
|
|
1696
1687
|
`
|
|
1697
1688
|
});
|
|
@@ -1742,6 +1733,18 @@ var TokenGenerator = class {
|
|
|
1742
1733
|
sourceFile.formatText();
|
|
1743
1734
|
sourceFile.saveSync();
|
|
1744
1735
|
}
|
|
1736
|
+
getBasePathTokenName() {
|
|
1737
|
+
const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
1738
|
+
return `BASE_PATH_${clientSuffix}`;
|
|
1739
|
+
}
|
|
1740
|
+
getInterceptorsTokenName() {
|
|
1741
|
+
const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
1742
|
+
return `HTTP_INTERCEPTORS_${clientSuffix}`;
|
|
1743
|
+
}
|
|
1744
|
+
getClientContextTokenName() {
|
|
1745
|
+
const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
1746
|
+
return `CLIENT_CONTEXT_TOKEN_${clientSuffix}`;
|
|
1747
|
+
}
|
|
1745
1748
|
};
|
|
1746
1749
|
|
|
1747
1750
|
// src/lib/generators/utility/file-download.generator.ts
|
|
@@ -1907,7 +1910,6 @@ var DateTransformerGenerator = class {
|
|
|
1907
1910
|
"HttpEvent",
|
|
1908
1911
|
"HttpHandler",
|
|
1909
1912
|
"HttpInterceptor",
|
|
1910
|
-
"HttpInterceptorFn",
|
|
1911
1913
|
"HttpRequest",
|
|
1912
1914
|
"HttpResponse"
|
|
1913
1915
|
],
|
|
@@ -1979,58 +1981,6 @@ var DateTransformerGenerator = class {
|
|
|
1979
1981
|
}
|
|
1980
1982
|
|
|
1981
1983
|
return obj;`
|
|
1982
|
-
});
|
|
1983
|
-
sourceFile.addFunction({
|
|
1984
|
-
name: "transformDateResponse",
|
|
1985
|
-
parameters: [
|
|
1986
|
-
{
|
|
1987
|
-
name: "event",
|
|
1988
|
-
type: "HttpEvent<any>"
|
|
1989
|
-
},
|
|
1990
|
-
{
|
|
1991
|
-
name: "dateRegex",
|
|
1992
|
-
type: "RegExp"
|
|
1993
|
-
}
|
|
1994
|
-
],
|
|
1995
|
-
returnType: "HttpEvent<any>",
|
|
1996
|
-
statements: `
|
|
1997
|
-
if (event instanceof HttpResponse && event.body) {
|
|
1998
|
-
return event.clone({ body: transformDates(event.body, dateRegex) });
|
|
1999
|
-
}
|
|
2000
|
-
return event;`
|
|
2001
|
-
});
|
|
2002
|
-
sourceFile.addFunction({
|
|
2003
|
-
name: "dateInterceptorWithRegex",
|
|
2004
|
-
isExported: true,
|
|
2005
|
-
docs: [
|
|
2006
|
-
"Builds a functional date interceptor for `provideHttpClient(withInterceptors([...]))`.\n@param dateRegex Optional override for the pattern used to detect ISO date strings."
|
|
2007
|
-
],
|
|
2008
|
-
parameters: [
|
|
2009
|
-
{
|
|
2010
|
-
name: "dateRegex",
|
|
2011
|
-
type: "RegExp",
|
|
2012
|
-
initializer: "ISO_DATE_REGEX"
|
|
2013
|
-
}
|
|
2014
|
-
],
|
|
2015
|
-
returnType: "HttpInterceptorFn",
|
|
2016
|
-
statements: `
|
|
2017
|
-
return (req, next) => next(req).pipe(map((event) => transformDateResponse(event, dateRegex)));`
|
|
2018
|
-
});
|
|
2019
|
-
sourceFile.addVariableStatement({
|
|
2020
|
-
isExported: true,
|
|
2021
|
-
declarationKind: import_ts_morph6.VariableDeclarationKind.Const,
|
|
2022
|
-
declarations: [
|
|
2023
|
-
{
|
|
2024
|
-
name: "dateInterceptor",
|
|
2025
|
-
type: "HttpInterceptorFn",
|
|
2026
|
-
initializer: "dateInterceptorWithRegex()"
|
|
2027
|
-
}
|
|
2028
|
-
],
|
|
2029
|
-
leadingTrivia: `/**
|
|
2030
|
-
* Functional date interceptor using the default ISO_DATE_REGEX.
|
|
2031
|
-
* Use dateInterceptorWithRegex(...) to customize the pattern.
|
|
2032
|
-
*/
|
|
2033
|
-
`
|
|
2034
1984
|
});
|
|
2035
1985
|
sourceFile.addClass({
|
|
2036
1986
|
name: "DateInterceptor",
|
|
@@ -2075,7 +2025,14 @@ var DateTransformerGenerator = class {
|
|
|
2075
2025
|
],
|
|
2076
2026
|
returnType: "Observable<HttpEvent<any>>",
|
|
2077
2027
|
statements: `
|
|
2078
|
-
return next.handle(req).pipe(
|
|
2028
|
+
return next.handle(req).pipe(
|
|
2029
|
+
map(event => {
|
|
2030
|
+
if (event instanceof HttpResponse && event.body) {
|
|
2031
|
+
return event.clone({ body: transformDates(event.body, this.dateRegex) });
|
|
2032
|
+
}
|
|
2033
|
+
return event;
|
|
2034
|
+
})
|
|
2035
|
+
);`
|
|
2079
2036
|
}
|
|
2080
2037
|
]
|
|
2081
2038
|
});
|
|
@@ -2156,14 +2113,13 @@ var ProviderGenerator = class {
|
|
|
2156
2113
|
});
|
|
2157
2114
|
sourceFile.insertText(0, PROVIDER_GENERATOR_HEADER_COMMENT);
|
|
2158
2115
|
const basePathTokenName = getBasePathTokenName(this.clientName);
|
|
2159
|
-
const
|
|
2160
|
-
const baseInterceptorClassName =
|
|
2116
|
+
const interceptorsTokenName = getInterceptorsTokenName(this.clientName);
|
|
2117
|
+
const baseInterceptorClassName = `${this.capitalizeFirst(this.clientName)}BaseInterceptor`;
|
|
2161
2118
|
sourceFile.addImportDeclarations([
|
|
2162
2119
|
{
|
|
2163
2120
|
namedImports: [
|
|
2164
2121
|
"EnvironmentProviders",
|
|
2165
2122
|
"Provider",
|
|
2166
|
-
"inject",
|
|
2167
2123
|
"makeEnvironmentProviders"
|
|
2168
2124
|
],
|
|
2169
2125
|
moduleSpecifier: "@angular/core"
|
|
@@ -2171,15 +2127,14 @@ var ProviderGenerator = class {
|
|
|
2171
2127
|
{
|
|
2172
2128
|
namedImports: [
|
|
2173
2129
|
"HTTP_INTERCEPTORS",
|
|
2174
|
-
"HttpInterceptor"
|
|
2175
|
-
"HttpInterceptorFn"
|
|
2130
|
+
"HttpInterceptor"
|
|
2176
2131
|
],
|
|
2177
2132
|
moduleSpecifier: "@angular/common/http"
|
|
2178
2133
|
},
|
|
2179
2134
|
{
|
|
2180
2135
|
namedImports: [
|
|
2181
2136
|
basePathTokenName,
|
|
2182
|
-
|
|
2137
|
+
interceptorsTokenName
|
|
2183
2138
|
],
|
|
2184
2139
|
moduleSpecifier: "./tokens"
|
|
2185
2140
|
},
|
|
@@ -2193,7 +2148,7 @@ var ProviderGenerator = class {
|
|
|
2193
2148
|
if (this.config.options.dateType === "Date") {
|
|
2194
2149
|
sourceFile.addImportDeclaration({
|
|
2195
2150
|
namedImports: [
|
|
2196
|
-
"
|
|
2151
|
+
"DateInterceptor"
|
|
2197
2152
|
],
|
|
2198
2153
|
moduleSpecifier: "./utils/date-transformer"
|
|
2199
2154
|
});
|
|
@@ -2207,50 +2162,24 @@ var ProviderGenerator = class {
|
|
|
2207
2162
|
]
|
|
2208
2163
|
},
|
|
2209
2164
|
{
|
|
2210
|
-
name: "
|
|
2211
|
-
type: "
|
|
2212
|
-
hasQuestionToken: true,
|
|
2213
|
-
docs: [
|
|
2214
|
-
"Class-based HTTP interceptors to apply to this client.",
|
|
2215
|
-
"Classes are resolved through DI when provided; classes that are not",
|
|
2216
|
-
"provided anywhere are instantiated without constructor arguments, so",
|
|
2217
|
-
"classes with required dependencies must be registered as providers."
|
|
2218
|
-
]
|
|
2219
|
-
},
|
|
2220
|
-
{
|
|
2221
|
-
name: "interceptorFns",
|
|
2222
|
-
type: "HttpInterceptorFn[]",
|
|
2165
|
+
name: "enableDateTransform",
|
|
2166
|
+
type: "boolean",
|
|
2223
2167
|
hasQuestionToken: true,
|
|
2224
2168
|
docs: [
|
|
2225
|
-
"
|
|
2169
|
+
"Enable automatic date transformation (default: true)"
|
|
2226
2170
|
]
|
|
2227
2171
|
},
|
|
2228
2172
|
{
|
|
2229
|
-
name: "
|
|
2230
|
-
type: "
|
|
2173
|
+
name: "interceptors",
|
|
2174
|
+
type: "(new (...args: HttpInterceptor[]) => HttpInterceptor)[]",
|
|
2231
2175
|
hasQuestionToken: true,
|
|
2232
2176
|
docs: [
|
|
2233
|
-
"
|
|
2234
|
-
"Set to false when your app needs withInterceptorsFromDi() for its own",
|
|
2235
|
-
"interceptors but this client's chain is registered functionally via",
|
|
2236
|
-
"withInterceptors([...]) \u2014 otherwise the chain would run twice.",
|
|
2237
|
-
"",
|
|
2238
|
-
"WARNING: with false you MUST register the functional interceptor yourself",
|
|
2239
|
-
"(provideHttpClient(withInterceptors([...]))); if neither variant is",
|
|
2240
|
-
"registered, this client's entire chain (date transform, interceptors,",
|
|
2241
|
-
"interceptorFns) silently does nothing."
|
|
2177
|
+
"Array of HTTP interceptor classes to apply to this client"
|
|
2242
2178
|
]
|
|
2243
2179
|
}
|
|
2244
2180
|
];
|
|
2245
2181
|
if (this.config.options.dateType === "Date") {
|
|
2246
2182
|
configProperties.push({
|
|
2247
|
-
name: "enableDateTransform",
|
|
2248
|
-
type: "boolean",
|
|
2249
|
-
hasQuestionToken: true,
|
|
2250
|
-
docs: [
|
|
2251
|
-
"Enable automatic date transformation (default: true)"
|
|
2252
|
-
]
|
|
2253
|
-
}, {
|
|
2254
2183
|
name: "dateTransformRegex",
|
|
2255
2184
|
type: "RegExp",
|
|
2256
2185
|
hasQuestionToken: true,
|
|
@@ -2268,25 +2197,14 @@ var ProviderGenerator = class {
|
|
|
2268
2197
|
],
|
|
2269
2198
|
properties: configProperties
|
|
2270
2199
|
});
|
|
2271
|
-
this.addMainProviderFunction(sourceFile, basePathTokenName,
|
|
2200
|
+
this.addMainProviderFunction(sourceFile, basePathTokenName, interceptorsTokenName, baseInterceptorClassName);
|
|
2272
2201
|
sourceFile.formatText();
|
|
2273
2202
|
sourceFile.saveSync();
|
|
2274
2203
|
}
|
|
2275
|
-
addMainProviderFunction(sourceFile, basePathTokenName,
|
|
2204
|
+
addMainProviderFunction(sourceFile, basePathTokenName, interceptorsTokenName, baseInterceptorClassName) {
|
|
2276
2205
|
const hasDateInterceptor = this.config.options.dateType === "Date";
|
|
2277
2206
|
const functionName = `provide${this.capitalizeFirst(this.clientName)}Client`;
|
|
2278
2207
|
const configTypeName = `${this.capitalizeFirst(this.clientName)}Config`;
|
|
2279
|
-
const interceptorFnName = getClientInterceptorFnName(this.clientName);
|
|
2280
|
-
const dateInterceptorBlock = hasDateInterceptor ? `
|
|
2281
|
-
// Date interceptor first: it runs first on requests (a no-op) and, being
|
|
2282
|
-
// outermost, its response transform applies last \u2014 the other client
|
|
2283
|
-
// interceptors see the raw body; only the service sees Date instances
|
|
2284
|
-
if (config.enableDateTransform !== false) {
|
|
2285
|
-
interceptorFns.push(dateInterceptorWithRegex(config.dateTransformRegex));
|
|
2286
|
-
}
|
|
2287
|
-
` : `
|
|
2288
|
-
// Date transformation not available (dateType: 'string' was used in generation)
|
|
2289
|
-
`;
|
|
2290
2208
|
const functionBody = `
|
|
2291
2209
|
const providers: Provider[] = [
|
|
2292
2210
|
// Base path token for this client
|
|
@@ -2294,36 +2212,38 @@ const providers: Provider[] = [
|
|
|
2294
2212
|
provide: ${basePathTokenName},
|
|
2295
2213
|
useValue: config.basePath
|
|
2296
2214
|
},
|
|
2297
|
-
//
|
|
2215
|
+
// Base interceptor that handles client-specific interceptors
|
|
2298
2216
|
{
|
|
2299
|
-
provide:
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
${dateInterceptorBlock}
|
|
2303
|
-
// Class-based interceptors are resolved through DI when provided,
|
|
2304
|
-
// otherwise instantiated directly, and adapted to functional form
|
|
2305
|
-
for (const interceptorClass of config.interceptors ?? []) {
|
|
2306
|
-
const instance = inject(interceptorClass, { optional: true }) ?? new interceptorClass();
|
|
2307
|
-
interceptorFns.push((req, next) => instance.intercept(req, { handle: next }));
|
|
2308
|
-
}
|
|
2309
|
-
|
|
2310
|
-
interceptorFns.push(...(config.interceptorFns ?? []));
|
|
2311
|
-
|
|
2312
|
-
return interceptorFns;
|
|
2313
|
-
}
|
|
2217
|
+
provide: HTTP_INTERCEPTORS,
|
|
2218
|
+
useClass: ${baseInterceptorClassName},
|
|
2219
|
+
multi: true
|
|
2314
2220
|
}
|
|
2315
2221
|
];
|
|
2316
2222
|
|
|
2317
|
-
//
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
if (config.
|
|
2223
|
+
// Add client-specific interceptor instances
|
|
2224
|
+
if (config.interceptors && config.interceptors.length > 0) {
|
|
2225
|
+
const interceptorInstances = config.interceptors.map(InterceptorClass => new InterceptorClass());
|
|
2226
|
+
|
|
2227
|
+
${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
|
|
2228
|
+
if (config.enableDateTransform !== false) {
|
|
2229
|
+
interceptorInstances.unshift(new DateInterceptor(config.dateTransformRegex));
|
|
2230
|
+
}` : `// Date transformation not available (dateType: 'string' was used in generation)`}
|
|
2231
|
+
|
|
2323
2232
|
providers.push({
|
|
2324
|
-
provide:
|
|
2325
|
-
|
|
2326
|
-
|
|
2233
|
+
provide: ${interceptorsTokenName},
|
|
2234
|
+
useValue: interceptorInstances
|
|
2235
|
+
});
|
|
2236
|
+
} ${hasDateInterceptor ? `else if (config.enableDateTransform !== false) {
|
|
2237
|
+
// Only date interceptor enabled
|
|
2238
|
+
providers.push({
|
|
2239
|
+
provide: ${interceptorsTokenName},
|
|
2240
|
+
useValue: [new DateInterceptor(config.dateTransformRegex)]
|
|
2241
|
+
});
|
|
2242
|
+
}` : ``} else {
|
|
2243
|
+
// No interceptors
|
|
2244
|
+
providers.push({
|
|
2245
|
+
provide: ${interceptorsTokenName},
|
|
2246
|
+
useValue: []
|
|
2327
2247
|
});
|
|
2328
2248
|
}
|
|
2329
2249
|
|
|
@@ -2337,17 +2257,13 @@ return makeEnvironmentProviders(providers);`;
|
|
|
2337
2257
|
"@example",
|
|
2338
2258
|
"```typescript",
|
|
2339
2259
|
"// In your app.config.ts",
|
|
2340
|
-
"import { provideHttpClient, withInterceptors } from '@angular/common/http';",
|
|
2341
2260
|
`import { ${functionName} } from './api/providers';`,
|
|
2342
|
-
`import { ${interceptorFnName} } from './api/utils/base-interceptor';`,
|
|
2343
2261
|
"",
|
|
2344
2262
|
"export const appConfig: ApplicationConfig = {",
|
|
2345
2263
|
" providers: [",
|
|
2346
|
-
` provideHttpClient(withInterceptors([${interceptorFnName}])),`,
|
|
2347
2264
|
` ${functionName}({`,
|
|
2348
2265
|
" basePath: 'https://api.example.com',",
|
|
2349
|
-
" interceptors: [AuthInterceptor
|
|
2350
|
-
" interceptorFns: [loggingInterceptor] // Functional interceptors",
|
|
2266
|
+
" interceptors: [AuthInterceptor, LoggingInterceptor] // Classes, not instances",
|
|
2351
2267
|
" }),",
|
|
2352
2268
|
" // other providers...",
|
|
2353
2269
|
" ]",
|
|
@@ -2407,28 +2323,23 @@ var BaseInterceptorGenerator = class {
|
|
|
2407
2323
|
overwrite: true
|
|
2408
2324
|
});
|
|
2409
2325
|
sourceFile.insertText(0, BASE_INTERCEPTOR_HEADER_COMMENT(this.#clientName));
|
|
2410
|
-
const
|
|
2326
|
+
const interceptorsTokenName = getInterceptorsTokenName(this.#clientName);
|
|
2411
2327
|
const clientContextTokenName = getClientContextTokenName(this.#clientName);
|
|
2412
|
-
const interceptorFnName = getClientInterceptorFnName(this.#clientName);
|
|
2413
2328
|
sourceFile.addImportDeclarations([
|
|
2414
2329
|
{
|
|
2415
2330
|
namedImports: [
|
|
2416
2331
|
"HttpContextToken",
|
|
2417
2332
|
"HttpEvent",
|
|
2418
2333
|
"HttpHandler",
|
|
2419
|
-
"HttpHandlerFn",
|
|
2420
2334
|
"HttpInterceptor",
|
|
2421
|
-
"HttpInterceptorFn",
|
|
2422
2335
|
"HttpRequest"
|
|
2423
2336
|
],
|
|
2424
2337
|
moduleSpecifier: "@angular/common/http"
|
|
2425
2338
|
},
|
|
2426
2339
|
{
|
|
2427
2340
|
namedImports: [
|
|
2428
|
-
"EnvironmentInjector",
|
|
2429
2341
|
"inject",
|
|
2430
|
-
"Injectable"
|
|
2431
|
-
"runInInjectionContext"
|
|
2342
|
+
"Injectable"
|
|
2432
2343
|
],
|
|
2433
2344
|
moduleSpecifier: "@angular/core"
|
|
2434
2345
|
},
|
|
@@ -2441,80 +2352,14 @@ var BaseInterceptorGenerator = class {
|
|
|
2441
2352
|
{
|
|
2442
2353
|
namedImports: [
|
|
2443
2354
|
clientContextTokenName,
|
|
2444
|
-
|
|
2355
|
+
interceptorsTokenName
|
|
2445
2356
|
],
|
|
2446
2357
|
moduleSpecifier: "../tokens"
|
|
2447
2358
|
}
|
|
2448
2359
|
]);
|
|
2449
|
-
sourceFile.addFunction({
|
|
2450
|
-
name: "interceptClientRequest",
|
|
2451
|
-
parameters: [
|
|
2452
|
-
{
|
|
2453
|
-
name: "req",
|
|
2454
|
-
type: "HttpRequest<any>"
|
|
2455
|
-
},
|
|
2456
|
-
{
|
|
2457
|
-
name: "next",
|
|
2458
|
-
type: "HttpHandlerFn"
|
|
2459
|
-
},
|
|
2460
|
-
{
|
|
2461
|
-
name: "interceptorFns",
|
|
2462
|
-
type: "HttpInterceptorFn[]"
|
|
2463
|
-
},
|
|
2464
|
-
{
|
|
2465
|
-
name: "clientContextToken",
|
|
2466
|
-
type: "HttpContextToken<string>"
|
|
2467
|
-
},
|
|
2468
|
-
{
|
|
2469
|
-
name: "injector",
|
|
2470
|
-
type: "EnvironmentInjector"
|
|
2471
|
-
}
|
|
2472
|
-
],
|
|
2473
|
-
returnType: "Observable<HttpEvent<any>>",
|
|
2474
|
-
statements: `
|
|
2475
|
-
// Check if this request belongs to this client using HttpContext
|
|
2476
|
-
if (!req.context.has(clientContextToken)) {
|
|
2477
|
-
// This request doesn't belong to this client, pass it through
|
|
2478
|
-
return next(req);
|
|
2479
|
-
}
|
|
2480
|
-
|
|
2481
|
-
// Compose right-to-left so the interceptors run in array order. Each fn is
|
|
2482
|
-
// invoked inside an injection context, mirroring Angular's own interceptor
|
|
2483
|
-
// chain, so client interceptors can use inject().
|
|
2484
|
-
const chain = interceptorFns.reduceRight<HttpHandlerFn>(
|
|
2485
|
-
(nextFn, interceptorFn) => (request) => runInInjectionContext(injector, () => interceptorFn(request, nextFn)),
|
|
2486
|
-
next
|
|
2487
|
-
);
|
|
2488
|
-
|
|
2489
|
-
return chain(req);`
|
|
2490
|
-
});
|
|
2491
|
-
sourceFile.addVariableStatement({
|
|
2492
|
-
isExported: true,
|
|
2493
|
-
declarationKind: import_ts_morph7.VariableDeclarationKind.Const,
|
|
2494
|
-
declarations: [
|
|
2495
|
-
{
|
|
2496
|
-
name: interceptorFnName,
|
|
2497
|
-
type: "HttpInterceptorFn",
|
|
2498
|
-
initializer: `(req, next) =>
|
|
2499
|
-
interceptClientRequest(req, next, inject(${interceptorFnsTokenName}), ${clientContextTokenName}, inject(EnvironmentInjector))`
|
|
2500
|
-
}
|
|
2501
|
-
],
|
|
2502
|
-
leadingTrivia: `/**
|
|
2503
|
-
* Functional interceptor running the ${this.#clientName} client's scoped interceptor chain.
|
|
2504
|
-
* Register it once with \`provideHttpClient(withInterceptors([${interceptorFnName}]))\`.
|
|
2505
|
-
* If your app also uses \`withInterceptorsFromDi()\`, pass \`registerDiInterceptor: false\`
|
|
2506
|
-
* to the client's provide function \u2014 otherwise the class-based registration it adds
|
|
2507
|
-
* would run the same chain twice.
|
|
2508
|
-
*/
|
|
2509
|
-
`
|
|
2510
|
-
});
|
|
2511
2360
|
sourceFile.addClass({
|
|
2512
|
-
name:
|
|
2361
|
+
name: `${this.capitalizeFirst(this.#clientName)}BaseInterceptor`,
|
|
2513
2362
|
isExported: true,
|
|
2514
|
-
docs: [
|
|
2515
|
-
`Class-based equivalent of \`${interceptorFnName}\` for DI registration via
|
|
2516
|
-
\`withInterceptorsFromDi()\`. Register exactly one of the two variants.`
|
|
2517
|
-
],
|
|
2518
2363
|
decorators: [
|
|
2519
2364
|
{
|
|
2520
2365
|
name: "Injectable",
|
|
@@ -2526,11 +2371,11 @@ var BaseInterceptorGenerator = class {
|
|
|
2526
2371
|
],
|
|
2527
2372
|
properties: [
|
|
2528
2373
|
{
|
|
2529
|
-
name: "
|
|
2530
|
-
type: "
|
|
2374
|
+
name: "httpInterceptors",
|
|
2375
|
+
type: "HttpInterceptor[]",
|
|
2531
2376
|
scope: import_ts_morph7.Scope.Private,
|
|
2532
2377
|
isReadonly: true,
|
|
2533
|
-
initializer: `inject(${
|
|
2378
|
+
initializer: `inject(${interceptorsTokenName})`
|
|
2534
2379
|
},
|
|
2535
2380
|
{
|
|
2536
2381
|
name: "clientContextToken",
|
|
@@ -2538,13 +2383,6 @@ var BaseInterceptorGenerator = class {
|
|
|
2538
2383
|
scope: import_ts_morph7.Scope.Private,
|
|
2539
2384
|
isReadonly: true,
|
|
2540
2385
|
initializer: clientContextTokenName
|
|
2541
|
-
},
|
|
2542
|
-
{
|
|
2543
|
-
name: "injector",
|
|
2544
|
-
type: "EnvironmentInjector",
|
|
2545
|
-
scope: import_ts_morph7.Scope.Private,
|
|
2546
|
-
isReadonly: true,
|
|
2547
|
-
initializer: "inject(EnvironmentInjector)"
|
|
2548
2386
|
}
|
|
2549
2387
|
],
|
|
2550
2388
|
methods: [
|
|
@@ -2562,13 +2400,32 @@ var BaseInterceptorGenerator = class {
|
|
|
2562
2400
|
],
|
|
2563
2401
|
returnType: "Observable<HttpEvent<any>>",
|
|
2564
2402
|
statements: `
|
|
2565
|
-
|
|
2403
|
+
// Check if this request belongs to this client using HttpContext
|
|
2404
|
+
if (!req.context.has(this.clientContextToken)) {
|
|
2405
|
+
// This request doesn't belong to this client, pass it through
|
|
2406
|
+
return next.handle(req);
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
// Apply client-specific interceptors in reverse order
|
|
2410
|
+
let handler = next;
|
|
2411
|
+
|
|
2412
|
+
handler = this.httpInterceptors.reduceRight(
|
|
2413
|
+
(next, interceptor) => ({
|
|
2414
|
+
handle: (request: HttpRequest<any>) => interceptor.intercept(request, next)
|
|
2415
|
+
}),
|
|
2416
|
+
handler
|
|
2417
|
+
);
|
|
2418
|
+
|
|
2419
|
+
return handler.handle(req);`
|
|
2566
2420
|
}
|
|
2567
2421
|
]
|
|
2568
2422
|
});
|
|
2569
2423
|
sourceFile.formatText();
|
|
2570
2424
|
sourceFile.saveSync();
|
|
2571
2425
|
}
|
|
2426
|
+
capitalizeFirst(str) {
|
|
2427
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
2428
|
+
}
|
|
2572
2429
|
};
|
|
2573
2430
|
|
|
2574
2431
|
// src/lib/generators/utility/http-params-builder.generator.ts
|
package/index.d.ts
CHANGED
|
@@ -685,21 +685,13 @@ declare function listGeneratedFileNames(project: Project, directoryPath: string,
|
|
|
685
685
|
declare function getClientContextTokenName(clientName?: string): string;
|
|
686
686
|
/** Token providing the API base path for the client. */
|
|
687
687
|
declare function getBasePathTokenName(clientName?: string): string;
|
|
688
|
-
/** Token carrying the client's interceptor chain
|
|
689
|
-
declare function
|
|
688
|
+
/** Token carrying the client's interceptor chain. */
|
|
689
|
+
declare function getInterceptorsTokenName(clientName?: string): string;
|
|
690
690
|
|
|
691
691
|
/** Class name of a generated service ("Role" → "RoleService", or decorated). */
|
|
692
692
|
declare function getServiceClassName(controllerName: string, naming?: NameDecoration): string;
|
|
693
693
|
/** Class name of a generated httpResource class ("Role" → "RoleResource", or decorated). */
|
|
694
694
|
declare function getResourceClassName(controllerName: string, naming?: NameDecoration): string;
|
|
695
|
-
/**
|
|
696
|
-
* Class name of the generated scoped interceptor ("users" → "UsersBaseInterceptor").
|
|
697
|
-
* Deliberately capitalizes only the first character (not pascalCase) to keep
|
|
698
|
-
* parity with the client-name handling of the token helpers.
|
|
699
|
-
*/
|
|
700
|
-
declare function getBaseInterceptorClassName(clientName?: string): string;
|
|
701
|
-
/** Identifier of the generated functional scoped interceptor ("users" → "usersClientInterceptor"). */
|
|
702
|
-
declare function getClientInterceptorFnName(clientName?: string): string;
|
|
703
695
|
/**
|
|
704
696
|
* TypeScript identifier of a schema-derived model type. Used both where
|
|
705
697
|
* models are declared (models/index.ts) and where they are referenced
|
|
@@ -880,4 +872,4 @@ declare class ConfigValidationError extends Error {
|
|
|
880
872
|
}
|
|
881
873
|
declare function validateGeneratorConfig(config: unknown): asserts config is GeneratorConfig;
|
|
882
874
|
|
|
883
|
-
export { BASE_INTERCEPTOR_HEADER_COMMENT, CONTENT_TYPES, ConfigValidationError, type EnumValueObject, type GenerationPhase, type GenerationResult, type GeneratorConfig, type GetMethodGenerationContext, HTTP_RESOURCE_GENERATOR_HEADER_COMMENT, type HeadersEmitOptions, type IPluginGenerator, type IPluginGeneratorClass, MAIN_INDEX_GENERATOR_HEADER_COMMENT, type MethodGenOptions, type MethodGenerationContext, type NameDecoration, type NamingOptions, NgOpenApiError, type NgOpenapiClientConfig, type NormalizedOperation, type NormalizedSpec, type OpenApiSecurityScheme, PROVIDER_GENERATOR_HEADER_COMMENT, type Parameter, type PathInfo, type PluginGeneratorContext, REQUEST_PARAMS_GENERATOR_HEADER_COMMENT, type Reporter, type RequestBody, type ResponseKind, type ResponseTypeInfo, SERVICE_GENERATOR_HEADER_COMMENT, SERVICE_INDEX_GENERATOR_HEADER_COMMENT, type ServiceDecoratorEmit, type ServiceDecoratorEmitOptions, SpecLoadError, SpecParseError, type SpecVersion, type SwaggerDefinition, SwaggerParser, type SwaggerResponse, type SwaggerSpec, TYPE_GENERATOR_HEADER_COMMENT, type TypeGenOptions, type TypeMappingConfig, type TypeSchema, ZOD_PLUGIN_GENERATOR_HEADER_COMMENT, ZOD_PLUGIN_INDEX_GENERATOR_HEADER_COMMENT, camelCase, defineConfig, emitDefaultHeadersMerge, emitHeaders, emitQueryParams, emitResponseTypeOption, emitServiceDecorator, emitSignalAwareQueryParams, emitUrlConstruction, emitUrlExpression, escapeString, extractPaths, generateFromConfig, generateParseRequestTypeParams,
|
|
875
|
+
export { BASE_INTERCEPTOR_HEADER_COMMENT, CONTENT_TYPES, ConfigValidationError, type EnumValueObject, type GenerationPhase, type GenerationResult, type GeneratorConfig, type GetMethodGenerationContext, HTTP_RESOURCE_GENERATOR_HEADER_COMMENT, type HeadersEmitOptions, type IPluginGenerator, type IPluginGeneratorClass, MAIN_INDEX_GENERATOR_HEADER_COMMENT, type MethodGenOptions, type MethodGenerationContext, type NameDecoration, type NamingOptions, NgOpenApiError, type NgOpenapiClientConfig, type NormalizedOperation, type NormalizedSpec, type OpenApiSecurityScheme, PROVIDER_GENERATOR_HEADER_COMMENT, type Parameter, type PathInfo, type PluginGeneratorContext, REQUEST_PARAMS_GENERATOR_HEADER_COMMENT, type Reporter, type RequestBody, type ResponseKind, type ResponseTypeInfo, SERVICE_GENERATOR_HEADER_COMMENT, SERVICE_INDEX_GENERATOR_HEADER_COMMENT, type ServiceDecoratorEmit, type ServiceDecoratorEmitOptions, SpecLoadError, SpecParseError, type SpecVersion, type SwaggerDefinition, SwaggerParser, type SwaggerResponse, type SwaggerSpec, TYPE_GENERATOR_HEADER_COMMENT, type TypeGenOptions, type TypeMappingConfig, type TypeSchema, ZOD_PLUGIN_GENERATOR_HEADER_COMMENT, ZOD_PLUGIN_INDEX_GENERATOR_HEADER_COMMENT, camelCase, defineConfig, emitDefaultHeadersMerge, emitHeaders, emitQueryParams, emitResponseTypeOption, emitServiceDecorator, emitSignalAwareQueryParams, emitUrlConstruction, emitUrlExpression, escapeString, extractPaths, generateFromConfig, generateParseRequestTypeParams, getBasePathTokenName, getClientContextTokenName, getInterceptorsTokenName, getModelTypeName, getRequestBodyType, getResourceClassName, getResponseInfoFromResponse, getResponseType, getResponseTypeFromResponse, getServiceClassName, getTypeScriptType, hasDuplicateFunctionNames, inferResponseTypeFromContentType, isDataTypeInterface, isPrimitiveType, isUrl, joinRequestOptionEntries, kebabCase, listGeneratedFileNames, normalizeSchema, normalizeSpec, nullableType, pascalCase, pascalCaseForEnums, plainParamValue, screamingSnakeCase, signalAwareParamValue, validateGeneratorConfig, validateInput };
|
package/index.js
CHANGED
|
@@ -106,11 +106,9 @@ __export(index_exports, {
|
|
|
106
106
|
extractPaths: () => extractPaths,
|
|
107
107
|
generateFromConfig: () => generateFromConfig,
|
|
108
108
|
generateParseRequestTypeParams: () => generateParseRequestTypeParams,
|
|
109
|
-
getBaseInterceptorClassName: () => getBaseInterceptorClassName,
|
|
110
109
|
getBasePathTokenName: () => getBasePathTokenName,
|
|
111
110
|
getClientContextTokenName: () => getClientContextTokenName,
|
|
112
|
-
|
|
113
|
-
getInterceptorFnsTokenName: () => getInterceptorFnsTokenName,
|
|
111
|
+
getInterceptorsTokenName: () => getInterceptorsTokenName,
|
|
114
112
|
getModelTypeName: () => getModelTypeName,
|
|
115
113
|
getRequestBodyType: () => getRequestBodyType,
|
|
116
114
|
getResourceClassName: () => getResourceClassName,
|
|
@@ -389,14 +387,6 @@ function getResourceClassName(controllerName, naming) {
|
|
|
389
387
|
return decorate(pascalCase(controllerName), "Resource", naming);
|
|
390
388
|
}
|
|
391
389
|
__name(getResourceClassName, "getResourceClassName");
|
|
392
|
-
function getBaseInterceptorClassName(clientName = "default") {
|
|
393
|
-
return `${clientName.charAt(0).toUpperCase()}${clientName.slice(1)}BaseInterceptor`;
|
|
394
|
-
}
|
|
395
|
-
__name(getBaseInterceptorClassName, "getBaseInterceptorClassName");
|
|
396
|
-
function getClientInterceptorFnName(clientName = "default") {
|
|
397
|
-
return `${clientName.charAt(0).toLowerCase()}${clientName.slice(1)}ClientInterceptor`;
|
|
398
|
-
}
|
|
399
|
-
__name(getClientInterceptorFnName, "getClientInterceptorFnName");
|
|
400
390
|
function getModelTypeName(rawName, naming) {
|
|
401
391
|
return decorate(pascalCaseForEnums(rawName), "", naming);
|
|
402
392
|
}
|
|
@@ -1025,11 +1015,11 @@ function getBasePathTokenName(clientName = "default") {
|
|
|
1025
1015
|
return `BASE_PATH_${clientSuffix}`;
|
|
1026
1016
|
}
|
|
1027
1017
|
__name(getBasePathTokenName, "getBasePathTokenName");
|
|
1028
|
-
function
|
|
1018
|
+
function getInterceptorsTokenName(clientName = "default") {
|
|
1029
1019
|
const clientSuffix = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
1030
|
-
return `
|
|
1020
|
+
return `HTTP_INTERCEPTORS_${clientSuffix}`;
|
|
1031
1021
|
}
|
|
1032
|
-
__name(
|
|
1022
|
+
__name(getInterceptorsTokenName, "getInterceptorsTokenName");
|
|
1033
1023
|
|
|
1034
1024
|
// ../shared/src/utils/functions/duplicate-function-name.ts
|
|
1035
1025
|
function hasDuplicateFunctionNames(arr) {
|
|
@@ -1836,15 +1826,15 @@ var _TokenGenerator = class _TokenGenerator {
|
|
|
1836
1826
|
},
|
|
1837
1827
|
{
|
|
1838
1828
|
namedImports: [
|
|
1839
|
-
"
|
|
1829
|
+
"HttpInterceptor",
|
|
1840
1830
|
"HttpContextToken"
|
|
1841
1831
|
],
|
|
1842
1832
|
moduleSpecifier: "@angular/common/http"
|
|
1843
1833
|
}
|
|
1844
1834
|
]);
|
|
1845
|
-
const basePathTokenName = getBasePathTokenName(
|
|
1846
|
-
const
|
|
1847
|
-
const clientContextTokenName = getClientContextTokenName(
|
|
1835
|
+
const basePathTokenName = this.getBasePathTokenName();
|
|
1836
|
+
const interceptorsTokenName = this.getInterceptorsTokenName();
|
|
1837
|
+
const clientContextTokenName = this.getClientContextTokenName();
|
|
1848
1838
|
sourceFile.addVariableStatement({
|
|
1849
1839
|
isExported: true,
|
|
1850
1840
|
declarationKind: import_ts_morph5.VariableDeclarationKind.Const,
|
|
@@ -1867,16 +1857,15 @@ var _TokenGenerator = class _TokenGenerator {
|
|
|
1867
1857
|
declarationKind: import_ts_morph5.VariableDeclarationKind.Const,
|
|
1868
1858
|
declarations: [
|
|
1869
1859
|
{
|
|
1870
|
-
name:
|
|
1871
|
-
initializer: `new InjectionToken<
|
|
1860
|
+
name: interceptorsTokenName,
|
|
1861
|
+
initializer: `new InjectionToken<HttpInterceptor[]>('${interceptorsTokenName}', {
|
|
1872
1862
|
providedIn: 'root',
|
|
1873
1863
|
factory: () => [], // Default empty array
|
|
1874
1864
|
})`
|
|
1875
1865
|
}
|
|
1876
1866
|
],
|
|
1877
1867
|
leadingTrivia: `/**
|
|
1878
|
-
* Injection token
|
|
1879
|
-
* normalized to functional interceptors. Populated by the client's provide function.
|
|
1868
|
+
* Injection token for the ${this.clientName} client HTTP interceptor instances
|
|
1880
1869
|
*/
|
|
1881
1870
|
`
|
|
1882
1871
|
});
|
|
@@ -1927,6 +1916,18 @@ var _TokenGenerator = class _TokenGenerator {
|
|
|
1927
1916
|
sourceFile.formatText();
|
|
1928
1917
|
sourceFile.saveSync();
|
|
1929
1918
|
}
|
|
1919
|
+
getBasePathTokenName() {
|
|
1920
|
+
const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
1921
|
+
return `BASE_PATH_${clientSuffix}`;
|
|
1922
|
+
}
|
|
1923
|
+
getInterceptorsTokenName() {
|
|
1924
|
+
const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
1925
|
+
return `HTTP_INTERCEPTORS_${clientSuffix}`;
|
|
1926
|
+
}
|
|
1927
|
+
getClientContextTokenName() {
|
|
1928
|
+
const clientSuffix = this.clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
1929
|
+
return `CLIENT_CONTEXT_TOKEN_${clientSuffix}`;
|
|
1930
|
+
}
|
|
1930
1931
|
};
|
|
1931
1932
|
__name(_TokenGenerator, "TokenGenerator");
|
|
1932
1933
|
var TokenGenerator = _TokenGenerator;
|
|
@@ -2090,7 +2091,6 @@ var _DateTransformerGenerator = class _DateTransformerGenerator {
|
|
|
2090
2091
|
"HttpEvent",
|
|
2091
2092
|
"HttpHandler",
|
|
2092
2093
|
"HttpInterceptor",
|
|
2093
|
-
"HttpInterceptorFn",
|
|
2094
2094
|
"HttpRequest",
|
|
2095
2095
|
"HttpResponse"
|
|
2096
2096
|
],
|
|
@@ -2162,58 +2162,6 @@ var _DateTransformerGenerator = class _DateTransformerGenerator {
|
|
|
2162
2162
|
}
|
|
2163
2163
|
|
|
2164
2164
|
return obj;`
|
|
2165
|
-
});
|
|
2166
|
-
sourceFile.addFunction({
|
|
2167
|
-
name: "transformDateResponse",
|
|
2168
|
-
parameters: [
|
|
2169
|
-
{
|
|
2170
|
-
name: "event",
|
|
2171
|
-
type: "HttpEvent<any>"
|
|
2172
|
-
},
|
|
2173
|
-
{
|
|
2174
|
-
name: "dateRegex",
|
|
2175
|
-
type: "RegExp"
|
|
2176
|
-
}
|
|
2177
|
-
],
|
|
2178
|
-
returnType: "HttpEvent<any>",
|
|
2179
|
-
statements: `
|
|
2180
|
-
if (event instanceof HttpResponse && event.body) {
|
|
2181
|
-
return event.clone({ body: transformDates(event.body, dateRegex) });
|
|
2182
|
-
}
|
|
2183
|
-
return event;`
|
|
2184
|
-
});
|
|
2185
|
-
sourceFile.addFunction({
|
|
2186
|
-
name: "dateInterceptorWithRegex",
|
|
2187
|
-
isExported: true,
|
|
2188
|
-
docs: [
|
|
2189
|
-
"Builds a functional date interceptor for `provideHttpClient(withInterceptors([...]))`.\n@param dateRegex Optional override for the pattern used to detect ISO date strings."
|
|
2190
|
-
],
|
|
2191
|
-
parameters: [
|
|
2192
|
-
{
|
|
2193
|
-
name: "dateRegex",
|
|
2194
|
-
type: "RegExp",
|
|
2195
|
-
initializer: "ISO_DATE_REGEX"
|
|
2196
|
-
}
|
|
2197
|
-
],
|
|
2198
|
-
returnType: "HttpInterceptorFn",
|
|
2199
|
-
statements: `
|
|
2200
|
-
return (req, next) => next(req).pipe(map((event) => transformDateResponse(event, dateRegex)));`
|
|
2201
|
-
});
|
|
2202
|
-
sourceFile.addVariableStatement({
|
|
2203
|
-
isExported: true,
|
|
2204
|
-
declarationKind: import_ts_morph6.VariableDeclarationKind.Const,
|
|
2205
|
-
declarations: [
|
|
2206
|
-
{
|
|
2207
|
-
name: "dateInterceptor",
|
|
2208
|
-
type: "HttpInterceptorFn",
|
|
2209
|
-
initializer: "dateInterceptorWithRegex()"
|
|
2210
|
-
}
|
|
2211
|
-
],
|
|
2212
|
-
leadingTrivia: `/**
|
|
2213
|
-
* Functional date interceptor using the default ISO_DATE_REGEX.
|
|
2214
|
-
* Use dateInterceptorWithRegex(...) to customize the pattern.
|
|
2215
|
-
*/
|
|
2216
|
-
`
|
|
2217
2165
|
});
|
|
2218
2166
|
sourceFile.addClass({
|
|
2219
2167
|
name: "DateInterceptor",
|
|
@@ -2258,7 +2206,14 @@ var _DateTransformerGenerator = class _DateTransformerGenerator {
|
|
|
2258
2206
|
],
|
|
2259
2207
|
returnType: "Observable<HttpEvent<any>>",
|
|
2260
2208
|
statements: `
|
|
2261
|
-
return next.handle(req).pipe(
|
|
2209
|
+
return next.handle(req).pipe(
|
|
2210
|
+
map(event => {
|
|
2211
|
+
if (event instanceof HttpResponse && event.body) {
|
|
2212
|
+
return event.clone({ body: transformDates(event.body, this.dateRegex) });
|
|
2213
|
+
}
|
|
2214
|
+
return event;
|
|
2215
|
+
})
|
|
2216
|
+
);`
|
|
2262
2217
|
}
|
|
2263
2218
|
]
|
|
2264
2219
|
});
|
|
@@ -2337,14 +2292,13 @@ var _ProviderGenerator = class _ProviderGenerator {
|
|
|
2337
2292
|
});
|
|
2338
2293
|
sourceFile.insertText(0, PROVIDER_GENERATOR_HEADER_COMMENT);
|
|
2339
2294
|
const basePathTokenName = getBasePathTokenName(this.clientName);
|
|
2340
|
-
const
|
|
2341
|
-
const baseInterceptorClassName =
|
|
2295
|
+
const interceptorsTokenName = getInterceptorsTokenName(this.clientName);
|
|
2296
|
+
const baseInterceptorClassName = `${this.capitalizeFirst(this.clientName)}BaseInterceptor`;
|
|
2342
2297
|
sourceFile.addImportDeclarations([
|
|
2343
2298
|
{
|
|
2344
2299
|
namedImports: [
|
|
2345
2300
|
"EnvironmentProviders",
|
|
2346
2301
|
"Provider",
|
|
2347
|
-
"inject",
|
|
2348
2302
|
"makeEnvironmentProviders"
|
|
2349
2303
|
],
|
|
2350
2304
|
moduleSpecifier: "@angular/core"
|
|
@@ -2352,15 +2306,14 @@ var _ProviderGenerator = class _ProviderGenerator {
|
|
|
2352
2306
|
{
|
|
2353
2307
|
namedImports: [
|
|
2354
2308
|
"HTTP_INTERCEPTORS",
|
|
2355
|
-
"HttpInterceptor"
|
|
2356
|
-
"HttpInterceptorFn"
|
|
2309
|
+
"HttpInterceptor"
|
|
2357
2310
|
],
|
|
2358
2311
|
moduleSpecifier: "@angular/common/http"
|
|
2359
2312
|
},
|
|
2360
2313
|
{
|
|
2361
2314
|
namedImports: [
|
|
2362
2315
|
basePathTokenName,
|
|
2363
|
-
|
|
2316
|
+
interceptorsTokenName
|
|
2364
2317
|
],
|
|
2365
2318
|
moduleSpecifier: "./tokens"
|
|
2366
2319
|
},
|
|
@@ -2374,7 +2327,7 @@ var _ProviderGenerator = class _ProviderGenerator {
|
|
|
2374
2327
|
if (this.config.options.dateType === "Date") {
|
|
2375
2328
|
sourceFile.addImportDeclaration({
|
|
2376
2329
|
namedImports: [
|
|
2377
|
-
"
|
|
2330
|
+
"DateInterceptor"
|
|
2378
2331
|
],
|
|
2379
2332
|
moduleSpecifier: "./utils/date-transformer"
|
|
2380
2333
|
});
|
|
@@ -2388,50 +2341,24 @@ var _ProviderGenerator = class _ProviderGenerator {
|
|
|
2388
2341
|
]
|
|
2389
2342
|
},
|
|
2390
2343
|
{
|
|
2391
|
-
name: "
|
|
2392
|
-
type: "
|
|
2393
|
-
hasQuestionToken: true,
|
|
2394
|
-
docs: [
|
|
2395
|
-
"Class-based HTTP interceptors to apply to this client.",
|
|
2396
|
-
"Classes are resolved through DI when provided; classes that are not",
|
|
2397
|
-
"provided anywhere are instantiated without constructor arguments, so",
|
|
2398
|
-
"classes with required dependencies must be registered as providers."
|
|
2399
|
-
]
|
|
2400
|
-
},
|
|
2401
|
-
{
|
|
2402
|
-
name: "interceptorFns",
|
|
2403
|
-
type: "HttpInterceptorFn[]",
|
|
2344
|
+
name: "enableDateTransform",
|
|
2345
|
+
type: "boolean",
|
|
2404
2346
|
hasQuestionToken: true,
|
|
2405
2347
|
docs: [
|
|
2406
|
-
"
|
|
2348
|
+
"Enable automatic date transformation (default: true)"
|
|
2407
2349
|
]
|
|
2408
2350
|
},
|
|
2409
2351
|
{
|
|
2410
|
-
name: "
|
|
2411
|
-
type: "
|
|
2352
|
+
name: "interceptors",
|
|
2353
|
+
type: "(new (...args: HttpInterceptor[]) => HttpInterceptor)[]",
|
|
2412
2354
|
hasQuestionToken: true,
|
|
2413
2355
|
docs: [
|
|
2414
|
-
"
|
|
2415
|
-
"Set to false when your app needs withInterceptorsFromDi() for its own",
|
|
2416
|
-
"interceptors but this client's chain is registered functionally via",
|
|
2417
|
-
"withInterceptors([...]) \u2014 otherwise the chain would run twice.",
|
|
2418
|
-
"",
|
|
2419
|
-
"WARNING: with false you MUST register the functional interceptor yourself",
|
|
2420
|
-
"(provideHttpClient(withInterceptors([...]))); if neither variant is",
|
|
2421
|
-
"registered, this client's entire chain (date transform, interceptors,",
|
|
2422
|
-
"interceptorFns) silently does nothing."
|
|
2356
|
+
"Array of HTTP interceptor classes to apply to this client"
|
|
2423
2357
|
]
|
|
2424
2358
|
}
|
|
2425
2359
|
];
|
|
2426
2360
|
if (this.config.options.dateType === "Date") {
|
|
2427
2361
|
configProperties.push({
|
|
2428
|
-
name: "enableDateTransform",
|
|
2429
|
-
type: "boolean",
|
|
2430
|
-
hasQuestionToken: true,
|
|
2431
|
-
docs: [
|
|
2432
|
-
"Enable automatic date transformation (default: true)"
|
|
2433
|
-
]
|
|
2434
|
-
}, {
|
|
2435
2362
|
name: "dateTransformRegex",
|
|
2436
2363
|
type: "RegExp",
|
|
2437
2364
|
hasQuestionToken: true,
|
|
@@ -2449,25 +2376,14 @@ var _ProviderGenerator = class _ProviderGenerator {
|
|
|
2449
2376
|
],
|
|
2450
2377
|
properties: configProperties
|
|
2451
2378
|
});
|
|
2452
|
-
this.addMainProviderFunction(sourceFile, basePathTokenName,
|
|
2379
|
+
this.addMainProviderFunction(sourceFile, basePathTokenName, interceptorsTokenName, baseInterceptorClassName);
|
|
2453
2380
|
sourceFile.formatText();
|
|
2454
2381
|
sourceFile.saveSync();
|
|
2455
2382
|
}
|
|
2456
|
-
addMainProviderFunction(sourceFile, basePathTokenName,
|
|
2383
|
+
addMainProviderFunction(sourceFile, basePathTokenName, interceptorsTokenName, baseInterceptorClassName) {
|
|
2457
2384
|
const hasDateInterceptor = this.config.options.dateType === "Date";
|
|
2458
2385
|
const functionName = `provide${this.capitalizeFirst(this.clientName)}Client`;
|
|
2459
2386
|
const configTypeName = `${this.capitalizeFirst(this.clientName)}Config`;
|
|
2460
|
-
const interceptorFnName = getClientInterceptorFnName(this.clientName);
|
|
2461
|
-
const dateInterceptorBlock = hasDateInterceptor ? `
|
|
2462
|
-
// Date interceptor first: it runs first on requests (a no-op) and, being
|
|
2463
|
-
// outermost, its response transform applies last \u2014 the other client
|
|
2464
|
-
// interceptors see the raw body; only the service sees Date instances
|
|
2465
|
-
if (config.enableDateTransform !== false) {
|
|
2466
|
-
interceptorFns.push(dateInterceptorWithRegex(config.dateTransformRegex));
|
|
2467
|
-
}
|
|
2468
|
-
` : `
|
|
2469
|
-
// Date transformation not available (dateType: 'string' was used in generation)
|
|
2470
|
-
`;
|
|
2471
2387
|
const functionBody = `
|
|
2472
2388
|
const providers: Provider[] = [
|
|
2473
2389
|
// Base path token for this client
|
|
@@ -2475,36 +2391,38 @@ const providers: Provider[] = [
|
|
|
2475
2391
|
provide: ${basePathTokenName},
|
|
2476
2392
|
useValue: config.basePath
|
|
2477
2393
|
},
|
|
2478
|
-
//
|
|
2394
|
+
// Base interceptor that handles client-specific interceptors
|
|
2479
2395
|
{
|
|
2480
|
-
provide:
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
${dateInterceptorBlock}
|
|
2484
|
-
// Class-based interceptors are resolved through DI when provided,
|
|
2485
|
-
// otherwise instantiated directly, and adapted to functional form
|
|
2486
|
-
for (const interceptorClass of config.interceptors ?? []) {
|
|
2487
|
-
const instance = inject(interceptorClass, { optional: true }) ?? new interceptorClass();
|
|
2488
|
-
interceptorFns.push((req, next) => instance.intercept(req, { handle: next }));
|
|
2489
|
-
}
|
|
2490
|
-
|
|
2491
|
-
interceptorFns.push(...(config.interceptorFns ?? []));
|
|
2492
|
-
|
|
2493
|
-
return interceptorFns;
|
|
2494
|
-
}
|
|
2396
|
+
provide: HTTP_INTERCEPTORS,
|
|
2397
|
+
useClass: ${baseInterceptorClassName},
|
|
2398
|
+
multi: true
|
|
2495
2399
|
}
|
|
2496
2400
|
];
|
|
2497
2401
|
|
|
2498
|
-
//
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
if (config.
|
|
2402
|
+
// Add client-specific interceptor instances
|
|
2403
|
+
if (config.interceptors && config.interceptors.length > 0) {
|
|
2404
|
+
const interceptorInstances = config.interceptors.map(InterceptorClass => new InterceptorClass());
|
|
2405
|
+
|
|
2406
|
+
${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
|
|
2407
|
+
if (config.enableDateTransform !== false) {
|
|
2408
|
+
interceptorInstances.unshift(new DateInterceptor(config.dateTransformRegex));
|
|
2409
|
+
}` : `// Date transformation not available (dateType: 'string' was used in generation)`}
|
|
2410
|
+
|
|
2504
2411
|
providers.push({
|
|
2505
|
-
provide:
|
|
2506
|
-
|
|
2507
|
-
|
|
2412
|
+
provide: ${interceptorsTokenName},
|
|
2413
|
+
useValue: interceptorInstances
|
|
2414
|
+
});
|
|
2415
|
+
} ${hasDateInterceptor ? `else if (config.enableDateTransform !== false) {
|
|
2416
|
+
// Only date interceptor enabled
|
|
2417
|
+
providers.push({
|
|
2418
|
+
provide: ${interceptorsTokenName},
|
|
2419
|
+
useValue: [new DateInterceptor(config.dateTransformRegex)]
|
|
2420
|
+
});
|
|
2421
|
+
}` : ``} else {
|
|
2422
|
+
// No interceptors
|
|
2423
|
+
providers.push({
|
|
2424
|
+
provide: ${interceptorsTokenName},
|
|
2425
|
+
useValue: []
|
|
2508
2426
|
});
|
|
2509
2427
|
}
|
|
2510
2428
|
|
|
@@ -2518,17 +2436,13 @@ return makeEnvironmentProviders(providers);`;
|
|
|
2518
2436
|
"@example",
|
|
2519
2437
|
"```typescript",
|
|
2520
2438
|
"// In your app.config.ts",
|
|
2521
|
-
"import { provideHttpClient, withInterceptors } from '@angular/common/http';",
|
|
2522
2439
|
`import { ${functionName} } from './api/providers';`,
|
|
2523
|
-
`import { ${interceptorFnName} } from './api/utils/base-interceptor';`,
|
|
2524
2440
|
"",
|
|
2525
2441
|
"export const appConfig: ApplicationConfig = {",
|
|
2526
2442
|
" providers: [",
|
|
2527
|
-
` provideHttpClient(withInterceptors([${interceptorFnName}])),`,
|
|
2528
2443
|
` ${functionName}({`,
|
|
2529
2444
|
" basePath: 'https://api.example.com',",
|
|
2530
|
-
" interceptors: [AuthInterceptor
|
|
2531
|
-
" interceptorFns: [loggingInterceptor] // Functional interceptors",
|
|
2445
|
+
" interceptors: [AuthInterceptor, LoggingInterceptor] // Classes, not instances",
|
|
2532
2446
|
" }),",
|
|
2533
2447
|
" // other providers...",
|
|
2534
2448
|
" ]",
|
|
@@ -2588,28 +2502,23 @@ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
|
|
|
2588
2502
|
overwrite: true
|
|
2589
2503
|
});
|
|
2590
2504
|
sourceFile.insertText(0, BASE_INTERCEPTOR_HEADER_COMMENT(__privateGet(this, _clientName)));
|
|
2591
|
-
const
|
|
2505
|
+
const interceptorsTokenName = getInterceptorsTokenName(__privateGet(this, _clientName));
|
|
2592
2506
|
const clientContextTokenName = getClientContextTokenName(__privateGet(this, _clientName));
|
|
2593
|
-
const interceptorFnName = getClientInterceptorFnName(__privateGet(this, _clientName));
|
|
2594
2507
|
sourceFile.addImportDeclarations([
|
|
2595
2508
|
{
|
|
2596
2509
|
namedImports: [
|
|
2597
2510
|
"HttpContextToken",
|
|
2598
2511
|
"HttpEvent",
|
|
2599
2512
|
"HttpHandler",
|
|
2600
|
-
"HttpHandlerFn",
|
|
2601
2513
|
"HttpInterceptor",
|
|
2602
|
-
"HttpInterceptorFn",
|
|
2603
2514
|
"HttpRequest"
|
|
2604
2515
|
],
|
|
2605
2516
|
moduleSpecifier: "@angular/common/http"
|
|
2606
2517
|
},
|
|
2607
2518
|
{
|
|
2608
2519
|
namedImports: [
|
|
2609
|
-
"EnvironmentInjector",
|
|
2610
2520
|
"inject",
|
|
2611
|
-
"Injectable"
|
|
2612
|
-
"runInInjectionContext"
|
|
2521
|
+
"Injectable"
|
|
2613
2522
|
],
|
|
2614
2523
|
moduleSpecifier: "@angular/core"
|
|
2615
2524
|
},
|
|
@@ -2622,80 +2531,14 @@ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
|
|
|
2622
2531
|
{
|
|
2623
2532
|
namedImports: [
|
|
2624
2533
|
clientContextTokenName,
|
|
2625
|
-
|
|
2534
|
+
interceptorsTokenName
|
|
2626
2535
|
],
|
|
2627
2536
|
moduleSpecifier: "../tokens"
|
|
2628
2537
|
}
|
|
2629
2538
|
]);
|
|
2630
|
-
sourceFile.addFunction({
|
|
2631
|
-
name: "interceptClientRequest",
|
|
2632
|
-
parameters: [
|
|
2633
|
-
{
|
|
2634
|
-
name: "req",
|
|
2635
|
-
type: "HttpRequest<any>"
|
|
2636
|
-
},
|
|
2637
|
-
{
|
|
2638
|
-
name: "next",
|
|
2639
|
-
type: "HttpHandlerFn"
|
|
2640
|
-
},
|
|
2641
|
-
{
|
|
2642
|
-
name: "interceptorFns",
|
|
2643
|
-
type: "HttpInterceptorFn[]"
|
|
2644
|
-
},
|
|
2645
|
-
{
|
|
2646
|
-
name: "clientContextToken",
|
|
2647
|
-
type: "HttpContextToken<string>"
|
|
2648
|
-
},
|
|
2649
|
-
{
|
|
2650
|
-
name: "injector",
|
|
2651
|
-
type: "EnvironmentInjector"
|
|
2652
|
-
}
|
|
2653
|
-
],
|
|
2654
|
-
returnType: "Observable<HttpEvent<any>>",
|
|
2655
|
-
statements: `
|
|
2656
|
-
// Check if this request belongs to this client using HttpContext
|
|
2657
|
-
if (!req.context.has(clientContextToken)) {
|
|
2658
|
-
// This request doesn't belong to this client, pass it through
|
|
2659
|
-
return next(req);
|
|
2660
|
-
}
|
|
2661
|
-
|
|
2662
|
-
// Compose right-to-left so the interceptors run in array order. Each fn is
|
|
2663
|
-
// invoked inside an injection context, mirroring Angular's own interceptor
|
|
2664
|
-
// chain, so client interceptors can use inject().
|
|
2665
|
-
const chain = interceptorFns.reduceRight<HttpHandlerFn>(
|
|
2666
|
-
(nextFn, interceptorFn) => (request) => runInInjectionContext(injector, () => interceptorFn(request, nextFn)),
|
|
2667
|
-
next
|
|
2668
|
-
);
|
|
2669
|
-
|
|
2670
|
-
return chain(req);`
|
|
2671
|
-
});
|
|
2672
|
-
sourceFile.addVariableStatement({
|
|
2673
|
-
isExported: true,
|
|
2674
|
-
declarationKind: import_ts_morph7.VariableDeclarationKind.Const,
|
|
2675
|
-
declarations: [
|
|
2676
|
-
{
|
|
2677
|
-
name: interceptorFnName,
|
|
2678
|
-
type: "HttpInterceptorFn",
|
|
2679
|
-
initializer: `(req, next) =>
|
|
2680
|
-
interceptClientRequest(req, next, inject(${interceptorFnsTokenName}), ${clientContextTokenName}, inject(EnvironmentInjector))`
|
|
2681
|
-
}
|
|
2682
|
-
],
|
|
2683
|
-
leadingTrivia: `/**
|
|
2684
|
-
* Functional interceptor running the ${__privateGet(this, _clientName)} client's scoped interceptor chain.
|
|
2685
|
-
* Register it once with \`provideHttpClient(withInterceptors([${interceptorFnName}]))\`.
|
|
2686
|
-
* If your app also uses \`withInterceptorsFromDi()\`, pass \`registerDiInterceptor: false\`
|
|
2687
|
-
* to the client's provide function \u2014 otherwise the class-based registration it adds
|
|
2688
|
-
* would run the same chain twice.
|
|
2689
|
-
*/
|
|
2690
|
-
`
|
|
2691
|
-
});
|
|
2692
2539
|
sourceFile.addClass({
|
|
2693
|
-
name:
|
|
2540
|
+
name: `${this.capitalizeFirst(__privateGet(this, _clientName))}BaseInterceptor`,
|
|
2694
2541
|
isExported: true,
|
|
2695
|
-
docs: [
|
|
2696
|
-
`Class-based equivalent of \`${interceptorFnName}\` for DI registration via
|
|
2697
|
-
\`withInterceptorsFromDi()\`. Register exactly one of the two variants.`
|
|
2698
|
-
],
|
|
2699
2542
|
decorators: [
|
|
2700
2543
|
{
|
|
2701
2544
|
name: "Injectable",
|
|
@@ -2707,11 +2550,11 @@ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
|
|
|
2707
2550
|
],
|
|
2708
2551
|
properties: [
|
|
2709
2552
|
{
|
|
2710
|
-
name: "
|
|
2711
|
-
type: "
|
|
2553
|
+
name: "httpInterceptors",
|
|
2554
|
+
type: "HttpInterceptor[]",
|
|
2712
2555
|
scope: import_ts_morph7.Scope.Private,
|
|
2713
2556
|
isReadonly: true,
|
|
2714
|
-
initializer: `inject(${
|
|
2557
|
+
initializer: `inject(${interceptorsTokenName})`
|
|
2715
2558
|
},
|
|
2716
2559
|
{
|
|
2717
2560
|
name: "clientContextToken",
|
|
@@ -2719,13 +2562,6 @@ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
|
|
|
2719
2562
|
scope: import_ts_morph7.Scope.Private,
|
|
2720
2563
|
isReadonly: true,
|
|
2721
2564
|
initializer: clientContextTokenName
|
|
2722
|
-
},
|
|
2723
|
-
{
|
|
2724
|
-
name: "injector",
|
|
2725
|
-
type: "EnvironmentInjector",
|
|
2726
|
-
scope: import_ts_morph7.Scope.Private,
|
|
2727
|
-
isReadonly: true,
|
|
2728
|
-
initializer: "inject(EnvironmentInjector)"
|
|
2729
2565
|
}
|
|
2730
2566
|
],
|
|
2731
2567
|
methods: [
|
|
@@ -2743,13 +2579,32 @@ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
|
|
|
2743
2579
|
],
|
|
2744
2580
|
returnType: "Observable<HttpEvent<any>>",
|
|
2745
2581
|
statements: `
|
|
2746
|
-
|
|
2582
|
+
// Check if this request belongs to this client using HttpContext
|
|
2583
|
+
if (!req.context.has(this.clientContextToken)) {
|
|
2584
|
+
// This request doesn't belong to this client, pass it through
|
|
2585
|
+
return next.handle(req);
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2588
|
+
// Apply client-specific interceptors in reverse order
|
|
2589
|
+
let handler = next;
|
|
2590
|
+
|
|
2591
|
+
handler = this.httpInterceptors.reduceRight(
|
|
2592
|
+
(next, interceptor) => ({
|
|
2593
|
+
handle: (request: HttpRequest<any>) => interceptor.intercept(request, next)
|
|
2594
|
+
}),
|
|
2595
|
+
handler
|
|
2596
|
+
);
|
|
2597
|
+
|
|
2598
|
+
return handler.handle(req);`
|
|
2747
2599
|
}
|
|
2748
2600
|
]
|
|
2749
2601
|
});
|
|
2750
2602
|
sourceFile.formatText();
|
|
2751
2603
|
sourceFile.saveSync();
|
|
2752
2604
|
}
|
|
2605
|
+
capitalizeFirst(str) {
|
|
2606
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
2607
|
+
}
|
|
2753
2608
|
};
|
|
2754
2609
|
_project = new WeakMap();
|
|
2755
2610
|
_clientName = new WeakMap();
|
|
@@ -4037,11 +3892,9 @@ __name(generateFromConfig, "generateFromConfig");
|
|
|
4037
3892
|
extractPaths,
|
|
4038
3893
|
generateFromConfig,
|
|
4039
3894
|
generateParseRequestTypeParams,
|
|
4040
|
-
getBaseInterceptorClassName,
|
|
4041
3895
|
getBasePathTokenName,
|
|
4042
3896
|
getClientContextTokenName,
|
|
4043
|
-
|
|
4044
|
-
getInterceptorFnsTokenName,
|
|
3897
|
+
getInterceptorsTokenName,
|
|
4045
3898
|
getModelTypeName,
|
|
4046
3899
|
getRequestBodyType,
|
|
4047
3900
|
getResourceClassName,
|
package/package.json
CHANGED