Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Generate text and images via the reverse-engineered Gemini Web API with multi-turn conversation support.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
scripts/gemini-webapi/utils/http.ts
1export function sleep(ms: number, signal?: AbortSignal): Promise<void> {2return new Promise((resolve) => {3const t = setTimeout(() => {4if (signal) signal.removeEventListener('abort', onAbort);5resolve();6}, ms);78const onAbort = () => {9clearTimeout(t);10if (signal) signal.removeEventListener('abort', onAbort);11resolve();12};1314if (signal) {15if (signal.aborted) {16onAbort();17} else {18signal.addEventListener('abort', onAbort, { once: true });19}20}21});22}2324export function cookie_header(cookies: Record<string, string>): string {25return Object.entries(cookies)26.filter(([, v]) => typeof v === 'string' && v.length > 0)27.map(([k, v]) => `${k}=${v}`)28.join('; ');29}3031export const cookieHeader = cookie_header;3233export function extract_set_cookie_value(setCookie: string | null, name: string): string | null {34if (!setCookie) return null;35const re = new RegExp(`(?:^|[;,\\s])${name.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}=([^;]+)`, 'i');36const m = setCookie.match(re);37if (!m) return null;38return m[1] ?? null;39}4041export async function fetch_with_timeout(42url: string,43init: RequestInit & { timeout_ms?: number } = {},44): Promise<Response> {45const { timeout_ms, ...rest } = init;46if (!timeout_ms || timeout_ms <= 0) return fetch(url, rest);4748const ctl = new AbortController();49const t = setTimeout(() => ctl.abort(), timeout_ms);50try {51return await fetch(url, { ...rest, signal: ctl.signal });52} finally {53clearTimeout(t);54}55}5657export const fetchWithTimeout = fetch_with_timeout;58