Files
Saxon FletcherandJoshen Lim 5508d2cd9d Test edge functions (#33728)
* page components

* page component changes

* settings but broken saving

* rvert

* use sheet for provider

* styling

* remove things

* Some refactoring and fixing, added JSDocs to layouts

* Smol refactor

* Fix

* Update JSDocs

* updated scaffolding

* update edge functions layout

* remove params

* single function layout

* invocation cleanup

* remove vars

* Clean up

* Spelling

* Clean up FormFieldWrappers

* One last clean up

* test edge function

* sheet flag

* remove prop

* fix merge errors

* fix merge errors

* update sheet

* rmeove import

* fix ts

* Some clean ups

* Fix

* Make test response area resizeable

* Final clean up

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2025-02-28 16:07:30 +08:00

113 lines
3.5 KiB
TypeScript

import { NextApiRequest, NextApiResponse } from 'next'
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, method, body: requestBody, headers: customHeaders } = req.body
// 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,
})
// 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',
},
})
}
}