Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
25 lines
1.2 KiB
TypeScript
25 lines
1.2 KiB
TypeScript
import { ProviderHttpError } from "../provider-http";
|
|
|
|
/** How long one sign-in or renewal request may take, body included. */
|
|
export const OAUTH_REQUEST_TIMEOUT_MS = 30_000;
|
|
|
|
/** A sign-in or renewal request that ends on the user's cancel or a stalled server; runs stop only their own wait, since refreshes are shared. */
|
|
export async function oauthFetch(url: string, init: RequestInit, cancel?: AbortSignal): Promise<{ response: Response; text: string }> {
|
|
const controller = new AbortController();
|
|
const abort = () => controller.abort();
|
|
if (cancel?.aborted) controller.abort();
|
|
else cancel?.addEventListener("abort", abort, { once: true });
|
|
const timer = setTimeout(abort, OAUTH_REQUEST_TIMEOUT_MS);
|
|
try {
|
|
const response = await fetch(url, { ...init, signal: controller.signal });
|
|
return { response, text: await response.text() };
|
|
} catch (error) {
|
|
if (cancel?.aborted) throw new Error("Login cancelled");
|
|
if (controller.signal.aborted) throw new ProviderHttpError(`Sign-in request to ${new URL(url).host} timed out.`, null, null, true);
|
|
throw error;
|
|
} finally {
|
|
clearTimeout(timer);
|
|
cancel?.removeEventListener("abort", abort);
|
|
}
|
|
}
|