150 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			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, | ||
|  |     }; | ||
|  |   } | ||
|  | } |