Files
webrequest/ts/interceptors/interceptor.manager.ts
Juergen Kunz 54afcc46e2 feat: Implement comprehensive web request handling with caching, retry, and interceptors
- Added cache strategies: NetworkFirst, CacheFirst, StaleWhileRevalidate, NetworkOnly, and CacheOnly.
- Introduced InterceptorManager for managing request, response, and error interceptors.
- Developed RetryManager for handling request retries with customizable backoff strategies.
- Implemented RequestDeduplicator to prevent simultaneous identical requests.
- Created timeout utilities for handling request timeouts.
- Enhanced WebrequestClient to support global interceptors, caching, and retry logic.
- Added convenience methods for common HTTP methods (GET, POST, PUT, DELETE) with JSON handling.
- Established a fetch-compatible webrequest function for seamless integration.
- Defined core type structures for caching, retry options, interceptors, and web request configurations.
2025-10-20 09:59:24 +00:00

150 lines
3.8 KiB
TypeScript

/**
* Interceptor manager for request/response transformation
*/
import type {
TRequestInterceptor,
TResponseInterceptor,
TErrorInterceptor,
} from './interceptor.types.js';
export class InterceptorManager {
private requestInterceptors: TRequestInterceptor[] = [];
private responseInterceptors: TResponseInterceptor[] = [];
private errorInterceptors: TErrorInterceptor[] = [];
/**
* Add a request interceptor
*/
public addRequestInterceptor(interceptor: TRequestInterceptor): void {
this.requestInterceptors.push(interceptor);
}
/**
* Add a response interceptor
*/
public addResponseInterceptor(interceptor: TResponseInterceptor): void {
this.responseInterceptors.push(interceptor);
}
/**
* Add an error interceptor
*/
public addErrorInterceptor(interceptor: TErrorInterceptor): void {
this.errorInterceptors.push(interceptor);
}
/**
* Remove a request interceptor
*/
public removeRequestInterceptor(interceptor: TRequestInterceptor): void {
const index = this.requestInterceptors.indexOf(interceptor);
if (index > -1) {
this.requestInterceptors.splice(index, 1);
}
}
/**
* Remove a response interceptor
*/
public removeResponseInterceptor(interceptor: TResponseInterceptor): void {
const index = this.responseInterceptors.indexOf(interceptor);
if (index > -1) {
this.responseInterceptors.splice(index, 1);
}
}
/**
* Remove an error interceptor
*/
public removeErrorInterceptor(interceptor: TErrorInterceptor): void {
const index = this.errorInterceptors.indexOf(interceptor);
if (index > -1) {
this.errorInterceptors.splice(index, 1);
}
}
/**
* Clear all interceptors
*/
public clearAll(): void {
this.requestInterceptors = [];
this.responseInterceptors = [];
this.errorInterceptors = [];
}
/**
* Process request through all request interceptors
*/
public async processRequest(request: Request): Promise<Request> {
let processedRequest = request;
for (const interceptor of this.requestInterceptors) {
try {
processedRequest = await interceptor(processedRequest);
} catch (error) {
// If interceptor throws, process through error interceptors
throw await this.processError(
error instanceof Error ? error : new Error(String(error)),
);
}
}
return processedRequest;
}
/**
* Process response through all response interceptors
*/
public async processResponse(response: Response): Promise<Response> {
let processedResponse = response;
for (const interceptor of this.responseInterceptors) {
try {
processedResponse = await interceptor(processedResponse);
} catch (error) {
// If interceptor throws, process through error interceptors
throw await this.processError(
error instanceof Error ? error : new Error(String(error)),
);
}
}
return processedResponse;
}
/**
* Process error through all error interceptors
*/
public async processError(error: Error): Promise<Error> {
let processedError = error;
for (const interceptor of this.errorInterceptors) {
try {
processedError = await interceptor(processedError);
} catch (newError) {
// If error interceptor throws, use the new error
processedError =
newError instanceof Error ? newError : new Error(String(newError));
}
}
return processedError;
}
/**
* Get count of registered interceptors
*/
public getInterceptorCounts(): {
request: number;
response: number;
error: number;
} {
return {
request: this.requestInterceptors.length,
response: this.responseInterceptors.length,
error: this.errorInterceptors.length,
};
}
}