From 34db76fbdc66117eb7e240422532a1f5abd7c701 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 14 Dec 2025 13:17:21 -0800 Subject: [PATCH] add client-side wiki fetcher to bypass cloudflare --- src/lib/api/wiki.ts | 80 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/lib/api/wiki.ts diff --git a/src/lib/api/wiki.ts b/src/lib/api/wiki.ts new file mode 100644 index 00000000..06295e99 --- /dev/null +++ b/src/lib/api/wiki.ts @@ -0,0 +1,80 @@ +/** + * Wiki API Client + * + * Fetches wiki data directly from gbf.wiki in the browser. + * This bypasses CloudFlare's server-side blocking by running in the client. + */ + +const GBF_WIKI_API = 'https://gbf.wiki/api.php' + +export interface WikiFetchResult { + wikiPage: string + wikiRaw?: string + error?: string + redirectedFrom?: string +} + +/** + * Fetches wiki text for a single page from gbf.wiki + * Runs in browser to bypass CloudFlare + */ +export async function fetchWikiPage(pageName: string): Promise { + const params = new URLSearchParams({ + action: 'parse', + format: 'json', + page: pageName, + prop: 'wikitext', + origin: '*' // Required for CORS + }) + + try { + const response = await fetch(`${GBF_WIKI_API}?${params}`) + const data = await response.json() + + if (data.error) { + return { wikiPage: pageName, error: data.error.info } + } + + const wikiText = data.parse?.wikitext?.['*'] + + if (!wikiText) { + return { wikiPage: pageName, error: 'No wikitext in response' } + } + + // Handle redirects + const redirectMatch = wikiText.match(/#REDIRECT \[\[(.*?)\]\]/) + if (redirectMatch) { + const redirectTarget = redirectMatch[1] + const redirectResult = await fetchWikiPage(redirectTarget) + return { + ...redirectResult, + redirectedFrom: pageName, + wikiPage: redirectResult.wikiPage + } + } + + return { wikiPage: pageName, wikiRaw: wikiText } + } catch (e) { + return { wikiPage: pageName, error: e instanceof Error ? e.message : String(e) } + } +} + +/** + * Fetches wiki text for multiple pages in parallel + */ +export async function fetchWikiPages(pageNames: string[]): Promise { + return Promise.all(pageNames.map(fetchWikiPage)) +} + +/** + * Builds a wiki_data map from fetch results for sending to the API + */ +export function buildWikiDataMap(results: WikiFetchResult[]): Record { + const wikiData: Record = {} + for (const result of results) { + if (result.wikiRaw) { + wikiData[result.wikiPage] = result.wikiRaw + } + } + return wikiData +}