2020 * }
2121 * }
2222 */
23- export class APIClient {
24- private beforeListeners = new Set < APIClient . BeforeListenerFunction > ( ) ;
25- private afterListeners = new Set < APIClient . AfterListenerFunction > ( ) ;
26-
23+ export class APIClient implements APIClient . Type {
2724 /** The base URL for all API requests. Must be defined in subclasses. */
2825 protected readonly baseURL : URL ;
2926
3027 constructor ( baseURL : URL ) {
3128 this . baseURL = baseURL ;
3229 }
3330
31+ public interceptors = {
32+ before : new Interceptor < APIClient . BeforeListenerFunction > ( ) ,
33+ after : new Interceptor < APIClient . AfterListenerFunction > ( ) ,
34+ } ;
35+
3436 /**
3537 * This method is called before the request is sent.
3638 * It can be used to modify the request before it is sent (e.g., adding
@@ -68,20 +70,14 @@ export class APIClient {
6870
6971 let request = new Request ( url . toString ( ) , init ) ;
7072 request = await this . before ( request ) ;
71-
72- if ( this . beforeListeners . size > 0 ) {
73- for ( let listener of this . beforeListeners ) {
74- request = await listener ( request ) ;
75- }
73+ for ( let listener of this . interceptors . before . listeners ) {
74+ request = await listener ( request ) ;
7675 }
7776
7877 let response = await fetch ( request ) ;
7978 response = await this . after ( request , response ) ;
80-
81- if ( this . afterListeners . size > 0 ) {
82- for ( let listener of this . afterListeners ) {
83- response = await listener ( request , response ) ;
84- }
79+ for ( let listener of this . interceptors . after . listeners ) {
80+ response = await listener ( request , response ) ;
8581 }
8682
8783 return response ;
@@ -141,33 +137,22 @@ export class APIClient {
141137 delete ( path : string , init ?: Omit < RequestInit , "method" > ) {
142138 return this . fetch ( path , { ...init , method : "DELETE" } ) ;
143139 }
140+ }
144141
145- public on ( event : "before" , listener : APIClient . BeforeListenerFunction ) : this;
146- public on ( event : "after" , listener : APIClient . AfterListenerFunction ) : this;
147- public on ( event : "before" | "after" , listener : APIClient . ListenerFunction ) {
148- if ( event === "before" ) {
149- this . beforeListeners . add ( listener as APIClient . BeforeListenerFunction ) ;
150- }
151-
152- if ( event === "after" ) {
153- this . afterListeners . add ( listener as APIClient . AfterListenerFunction ) ;
154- }
142+ // biome-ignore lint/complexity/noBannedTypes: I need to use `Function` here
143+ class Interceptor < Listener extends Function > {
144+ #listeners = new Set < Listener > ( ) ;
155145
156- return this ;
146+ public on ( event : Listener ) {
147+ this . #listeners. add ( event ) ;
157148 }
158149
159- public off ( event : "before" , listener : APIClient . BeforeListenerFunction ) : this;
160- public off ( event : "after" , listener : APIClient . AfterListenerFunction ) : this;
161- public off ( event : "before" | "after" , listener : APIClient . ListenerFunction ) {
162- if ( event === "before" ) {
163- this . beforeListeners . delete ( listener as APIClient . BeforeListenerFunction ) ;
164- }
165-
166- if ( event === "after" ) {
167- this . afterListeners . delete ( listener as APIClient . AfterListenerFunction ) ;
168- }
150+ public off ( event : Listener ) {
151+ this . #listeners. delete ( event ) ;
152+ }
169153
170- return this ;
154+ get listeners ( ) {
155+ return Array . from ( this . #listeners) ;
171156 }
172157}
173158
@@ -180,4 +165,18 @@ export namespace APIClient {
180165 ) => Promise < Response > ;
181166
182167 export type ListenerFunction = BeforeListenerFunction | AfterListenerFunction ;
168+
169+ export interface Type {
170+ interceptors : {
171+ before : Interceptor < BeforeListenerFunction > ;
172+ after : Interceptor < AfterListenerFunction > ;
173+ } ;
174+
175+ fetch ( path : string , init ?: RequestInit ) : Promise < Response > ;
176+ get ( path : string , init ?: Omit < RequestInit , "method" > ) : Promise < Response > ;
177+ post ( path : string , init ?: Omit < RequestInit , "method" > ) : Promise < Response > ;
178+ put ( path : string , init ?: Omit < RequestInit , "method" > ) : Promise < Response > ;
179+ patch ( path : string , init ?: Omit < RequestInit , "method" > ) : Promise < Response > ;
180+ delete ( path : string , init ?: Omit < RequestInit , "method" > ) : Promise < Response > ;
181+ }
183182}
0 commit comments