* Core fetch method. Applies auth headers, timeout, and retry logic. * Pass `timeout: 0` to disable timeout (e.g. for streaming responses).
(
path: string,
init: RequestInit & { timeout?: number; extraHeaders?: Record<string, string> } = {}
)
| 148 | * Pass `timeout: 0` to disable timeout (e.g. for streaming responses). |
| 149 | */ |
| 150 | async request( |
| 151 | path: string, |
| 152 | init: RequestInit & { timeout?: number; extraHeaders?: Record<string, string> } = {} |
| 153 | ): Promise<Response> { |
| 154 | const { |
| 155 | timeout = DEFAULT_TIMEOUT_MS, |
| 156 | signal: userSignal, |
| 157 | extraHeaders, |
| 158 | ...rest |
| 159 | } = init; |
| 160 | |
| 161 | const url = `${this.baseUrl}${path}`; |
| 162 | const headers = this.buildHeaders(extraHeaders); |
| 163 | |
| 164 | const timeoutSignals: (AbortSignal | undefined)[] = [userSignal]; |
| 165 | let timeoutController: AbortController | undefined; |
| 166 | let timeoutId: ReturnType<typeof setTimeout> | undefined; |
| 167 | |
| 168 | if (timeout > 0) { |
| 169 | timeoutController = new AbortController(); |
| 170 | timeoutId = setTimeout(() => timeoutController!.abort(), timeout); |
| 171 | timeoutSignals.push(timeoutController.signal); |
| 172 | } |
| 173 | |
| 174 | const { signal, cleanup } = combineSignals(...timeoutSignals); |
| 175 | |
| 176 | try { |
| 177 | return await this.fetchWithRetry(url, { ...rest, headers, signal }, 0); |
| 178 | } catch (err) { |
| 179 | if (isAbortError(err)) { |
| 180 | const didTimeout = timeoutController?.signal.aborted ?? false; |
| 181 | throw new ApiError( |
| 182 | 408, |
| 183 | didTimeout ? "Request timed out" : "Request cancelled", |
| 184 | didTimeout ? "timeout" : "abort" |
| 185 | ); |
| 186 | } |
| 187 | throw new ApiError( |
| 188 | 0, |
| 189 | err instanceof Error ? err.message : "Network error", |
| 190 | "network" |
| 191 | ); |
| 192 | } finally { |
| 193 | cleanup(); |
| 194 | if (timeoutId) clearTimeout(timeoutId); |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | // --------------------------------------------------------------------------- |
| 199 | // Convenience methods |
no test coverage detected