| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- 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<string, string>
- )
- // Only use custom headers and ensure Content-Type is set
- const requestHeaders: Record<string, string> = {
- '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<string, string> = {}
- 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',
- },
- })
- }
- }
|