import type { VercelRequest, VercelResponse } from '@vercel/node'; export type ApiHandler = (req: VercelRequest, res: VercelResponse) => Promise; function resolveCorsOrigin(req: VercelRequest): string { const requestOrigin = typeof req.headers.origin === 'string' ? req.headers.origin.trim() : ''; const ALLOWED_ORIGINS = [ 'https://getcert.eu.cc', 'https://verify.getcert.eu.cc', 'https://getcert.vercel.app', 'http://localhost:5173', 'http://localhost:3000', 'http://localhost:3001', ]; if ( requestOrigin && (ALLOWED_ORIGINS.includes(requestOrigin) || requestOrigin.endsWith('.getcert.eu.cc') || requestOrigin.endsWith('.vercel.app')) ) { return requestOrigin; } const configured = (process.env.APP_ORIGIN || '').trim(); if (configured && !configured.includes('hf.space')) { return configured; } return 'https://getcert.eu.cc'; } export function applyCors(req: VercelRequest, res: VercelResponse): void { const origin = resolveCorsOrigin(req); res.setHeader('Vary', 'Origin'); res.setHeader('Access-Control-Allow-Origin', origin); res.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS'); res.setHeader( 'Access-Control-Allow-Headers', 'Content-Type, Authorization, x-admin-review-secret, x-payment-review-secret' ); } export function withCors(handler: ApiHandler): ApiHandler { return async (req, res) => { applyCors(req, res); if (req.method === 'OPTIONS') { res.status(200).end(); return; } await handler(req, res); }; } export function assertMethod(req: VercelRequest, res: VercelResponse, method: 'GET' | 'POST'): boolean { if (req.method === 'HEAD' && method === 'GET') { return true; } if (req.method !== method) { res.status(405).json({ success: false, error: `Method ${req.method} not allowed` }); return false; } return true; } export function parseJsonBody(req: VercelRequest): T { if (!req.body) { return {} as T; } if (typeof req.body === 'string') { return JSON.parse(req.body) as T; } return req.body as T; } export function ok(res: VercelResponse, payload: unknown): void { res.status(200).json({ success: true, data: payload }); } export function fail(res: VercelResponse, status: number, error: string, details?: unknown): void { res.status(status).json({ success: false, error, details: details ?? null, }); }