()
| 372 | export function createClaudeAiProxyFetch(innerFetch: FetchLike): FetchLike { |
| 373 | return async (url, init) => { |
| 374 | const doRequest = async () => { |
| 375 | await checkAndRefreshOAuthTokenIfNeeded() |
| 376 | const currentTokens = getClaudeAIOAuthTokens() |
| 377 | if (!currentTokens) { |
| 378 | throw new Error('No claude.ai OAuth token available') |
| 379 | } |
| 380 | // eslint-disable-next-line eslint-plugin-n/no-unsupported-features/node-builtins |
| 381 | const headers = new Headers(init?.headers) |
| 382 | headers.set('Authorization', `Bearer ${currentTokens.accessToken}`) |
| 383 | const response = await innerFetch(url, { ...init, headers }) |
| 384 | // Return the exact token that was sent. Reading getClaudeAIOAuthTokens() |
| 385 | // again after the request is wrong under concurrent 401s: another |
| 386 | // connector's handleOAuth401Error clears the memoize cache, so we'd read |
| 387 | // the NEW token from keychain, pass it to handleOAuth401Error, which |
| 388 | // finds same-as-keychain → returns false → skips retry. Same pattern as |
| 389 | // bridgeApi.ts withOAuthRetry (token passed as fn param). |
| 390 | return { response, sentToken: currentTokens.accessToken } |
| 391 | } |
| 392 | |
| 393 | const { response, sentToken } = await doRequest() |
| 394 | if (response.status !== 401) { |
no test coverage detected