import { IS_PLATFORM } from 'common' import { NextApiRequest, NextApiResponse } from 'next' import { isValidEdgeFunctionURL } from '@/lib/api/edgeFunctions' export default async function handler(req: NextApiRequest, res: NextApiResponse) { const { method } = req switch (method) { case 'POST': return handlePost(req, res) default: return new Response( JSON.stringify({ data: null, error: { message: `Method ${method} Not Allowed` } }), { status: 405, headers: { 'Content-Type': 'application/json', Allow: 'POST' }, } ) } } async function handlePost(req: NextApiRequest, res: NextApiResponse) { try { const { url: requestUrl, method, body: requestBody, headers: customHeaders } = req.body const url = IS_PLATFORM ? requestUrl : requestUrl.replace(process.env.BRIVEN_PUBLIC_URL, process.env.BRIVEN_URL) const validEdgeFnUrl = isValidEdgeFunctionURL(url, IS_PLATFORM) if (!validEdgeFnUrl) { return res.status(400).json({ status: 400, error: { message: 'Provided URL is not a valid Briven edge function URL' }, }) } // Remove any undefined or null values from custom headers const sanitizedCustomHeaders = Object.entries(customHeaders || {}).reduce( (acc, [key, value]) => { if (value !== undefined && value !== null && value !== '') { acc[key] = value as string } return acc }, {} as Record ) // Only use custom headers and ensure Content-Type is set const requestHeaders: Record = { 'Content-Type': 'application/json', ...sanitizedCustomHeaders, } // Use the test authorization header if provided if (sanitizedCustomHeaders['x-test-authorization']) { requestHeaders['Authorization'] = sanitizedCustomHeaders['x-test-authorization'] // Remove the x-test-authorization header as we've moved it to Authorization delete requestHeaders['x-test-authorization'] } // Prepare the request body based on method and Content-Type let finalBody = undefined if (method !== 'GET' && method !== 'HEAD') { if (requestHeaders['Content-Type'] === 'application/json') { finalBody = typeof requestBody === 'string' ? requestBody : JSON.stringify(requestBody) } else { finalBody = requestBody } } const response = await fetch(url, { method, headers: requestHeaders, body: finalBody, redirect: 'manual', // don't follow the redirect and return response as is }) // Handle non-JSON responses let responseBody: string const contentType = response.headers.get('content-type') if (contentType?.includes('application/json')) { // If JSON, parse and stringify to ensure it's valid JSON const jsonBody = await response.json() responseBody = JSON.stringify(jsonBody) } else { // For non-JSON responses, get raw text responseBody = await response.text() } if (!response.ok) { // Try to parse error response if it's JSON try { const errorBody = JSON.parse(responseBody) return res.status(response.status).json({ status: response.status, error: { message: errorBody?.error || 'Edge function returned an error' }, }) } catch (parseError) { // If not JSON, return the raw error return res.status(response.status).json({ status: response.status, error: { message: responseBody || 'Edge function returned an error' }, }) } } const responseHeaders: Record = {} response.headers.forEach((value, key) => { responseHeaders[key] = value }) return res.status(response.status).json({ status: response.status, headers: responseHeaders, body: responseBody, }) } catch (error: any) { return res.status(500).json({ status: 500, error: { message: error.message || 'Failed to test edge function', }, }) } }