1
+ import { default as FormData } from "form-data" ;
1
2
import qs from "qs" ;
2
3
import { RUNTIME } from "../runtime" ;
3
4
import { APIResponse } from "./APIResponse" ;
@@ -15,7 +16,6 @@ export declare namespace Fetcher {
15
16
timeoutMs ?: number ;
16
17
maxRetries ?: number ;
17
18
withCredentials ?: boolean ;
18
- abortSignal ?: AbortSignal ;
19
19
responseType ?: "json" | "blob" | "streaming" | "text" ;
20
20
}
21
21
@@ -67,28 +67,13 @@ async function fetcherImpl<R = unknown>(args: Fetcher.Args): Promise<APIResponse
67
67
: args . url ;
68
68
69
69
let body : BodyInit | undefined = undefined ;
70
- const maybeStringifyBody = ( body : any ) => {
71
- if ( body instanceof Uint8Array ) {
72
- return body ;
73
- } else {
74
- return JSON . stringify ( body ) ;
75
- }
76
- } ;
77
-
78
- if ( RUNTIME . type === "node" ) {
79
- if ( args . body instanceof ( await import ( "formdata-node" ) ) . FormData ) {
80
- // @ts -expect-error
81
- body = args . body ;
82
- } else {
83
- body = maybeStringifyBody ( args . body ) ;
84
- }
70
+ if ( args . body instanceof FormData ) {
71
+ // @ts -expect-error
72
+ body = args . body ;
73
+ } else if ( args . body instanceof Uint8Array ) {
74
+ body = args . body ;
85
75
} else {
86
- if ( args . body instanceof ( await import ( "form-data" ) ) . default ) {
87
- // @ts -expect-error
88
- body = args . body ;
89
- } else {
90
- body = maybeStringifyBody ( args . body ) ;
91
- }
76
+ body = JSON . stringify ( args . body ) ;
92
77
}
93
78
94
79
// In Node.js environments, the SDK always uses`node-fetch`.
@@ -104,33 +89,21 @@ async function fetcherImpl<R = unknown>(args: Fetcher.Args): Promise<APIResponse
104
89
: ( ( await import ( "node-fetch" ) ) . default as any ) ;
105
90
106
91
const makeRequest = async ( ) : Promise < Response > => {
107
- const signals : AbortSignal [ ] = [ ] ;
108
-
109
- // Add timeout signal
110
- let timeoutAbortId : NodeJS . Timeout | undefined = undefined ;
92
+ const controller = new AbortController ( ) ;
93
+ let abortId = undefined ;
111
94
if ( args . timeoutMs != null ) {
112
- const { signal, abortId } = getTimeoutSignal ( args . timeoutMs ) ;
113
- timeoutAbortId = abortId ;
114
- signals . push ( signal ) ;
95
+ abortId = setTimeout ( ( ) => controller . abort ( ) , args . timeoutMs ) ;
115
96
}
116
-
117
- // Add arbitrary signal
118
- if ( args . abortSignal != null ) {
119
- signals . push ( args . abortSignal ) ;
120
- }
121
-
122
97
const response = await fetchFn ( url , {
123
98
method : args . method ,
124
99
headers,
125
100
body,
126
- signal : anySignal ( signals ) ,
101
+ signal : controller . signal ,
127
102
credentials : args . withCredentials ? "include" : undefined ,
128
103
} ) ;
129
-
130
- if ( timeoutAbortId != null ) {
131
- clearTimeout ( timeoutAbortId ) ;
104
+ if ( abortId != null ) {
105
+ clearTimeout ( abortId ) ;
132
106
}
133
-
134
107
return response ;
135
108
} ;
136
109
@@ -194,15 +167,7 @@ async function fetcherImpl<R = unknown>(args: Fetcher.Args): Promise<APIResponse
194
167
} ;
195
168
}
196
169
} catch ( error ) {
197
- if ( args . abortSignal != null && args . abortSignal . aborted ) {
198
- return {
199
- ok : false ,
200
- error : {
201
- reason : "unknown" ,
202
- errorMessage : "The user aborted a request" ,
203
- } ,
204
- } ;
205
- } else if ( error instanceof Error && error . name === "AbortError" ) {
170
+ if ( error instanceof Error && error . name === "AbortError" ) {
206
171
return {
207
172
ok : false ,
208
173
error : {
@@ -229,43 +194,4 @@ async function fetcherImpl<R = unknown>(args: Fetcher.Args): Promise<APIResponse
229
194
}
230
195
}
231
196
232
- const TIMEOUT = "timeout" ;
233
-
234
- function getTimeoutSignal ( timeoutMs : number ) : { signal : AbortSignal ; abortId : NodeJS . Timeout } {
235
- const controller = new AbortController ( ) ;
236
- const abortId = setTimeout ( ( ) => controller . abort ( TIMEOUT ) , timeoutMs ) ;
237
- return { signal : controller . signal , abortId } ;
238
- }
239
-
240
- /**
241
- * Returns an abort signal that is getting aborted when
242
- * at least one of the specified abort signals is aborted.
243
- *
244
- * Requires at least node.js 18.
245
- */
246
- function anySignal ( ...args : AbortSignal [ ] | [ AbortSignal [ ] ] ) : AbortSignal {
247
- // Allowing signals to be passed either as array
248
- // of signals or as multiple arguments.
249
- const signals = < AbortSignal [ ] > ( args . length === 1 && Array . isArray ( args [ 0 ] ) ? args [ 0 ] : args ) ;
250
-
251
- const controller = new AbortController ( ) ;
252
-
253
- for ( const signal of signals ) {
254
- if ( signal . aborted ) {
255
- // Exiting early if one of the signals
256
- // is already aborted.
257
- controller . abort ( ( signal as any ) ?. reason ) ;
258
- break ;
259
- }
260
-
261
- // Listening for signals and removing the listeners
262
- // when at least one symbol is aborted.
263
- signal . addEventListener ( "abort" , ( ) => controller . abort ( ( signal as any ) ?. reason ) , {
264
- signal : controller . signal ,
265
- } ) ;
266
- }
267
-
268
- return controller . signal ;
269
- }
270
-
271
197
export const fetcher : FetchFunction = fetcherImpl ;
0 commit comments