/** * Shared proxy utilities for Cloudflare Pages Functions * Handles CORS, error responses, and Worker API forwarding */ export interface Env { WORKER_API_KEY: string; WORKER_API_URL: string; DB: D1Database; } export interface ErrorResponse { success: false; error: string; details?: any; } const CORS_HEADERS = { 'Access-Control-Allow-Origin': 'https://hosting.anvil.it.com', 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type', } as const; /** * Create CORS preflight response */ export function createCorsPreflightResponse(): Response { return new Response(null, { status: 204, headers: CORS_HEADERS, }); } /** * Create error response with CORS headers */ export function createErrorResponse( error: string, status: number = 500, details?: any ): Response { const body: ErrorResponse = { success: false, error, ...(details && { details }), }; return new Response(JSON.stringify(body), { status, headers: { ...CORS_HEADERS, 'Content-Type': 'application/json', }, }); } /** * Proxy request to Worker API with authentication */ export async function proxyToWorker( env: Env, path: string, options: RequestInit = {} ): Promise { const workerUrl = `${env.WORKER_API_URL}${path}`; try { const response = await fetch(workerUrl, { ...options, headers: { ...options.headers, 'X-API-Key': env.WORKER_API_KEY, }, }); // Clone response to add CORS headers const body = await response.text(); return new Response(body, { status: response.status, statusText: response.statusText, headers: { ...CORS_HEADERS, 'Content-Type': response.headers.get('Content-Type') || 'application/json', }, }); } catch (error) { console.error(`[Proxy] Failed to fetch ${workerUrl}:`, error); return createErrorResponse( 'Failed to connect to API server', 503, error instanceof Error ? error.message : String(error) ); } } /** * Build query string from URL search params */ export function buildQueryString(searchParams: URLSearchParams): string { const params = searchParams.toString(); return params ? `?${params}` : ''; }