// === Handler === export const handler = async (req, res) => { try { const modified = processPreRequest(req.body?.request); return res.status(200).json(modified); } catch (err) { return handleError(err, res); } }; // === Core Processing === function processPreRequest(request) { if (!request || typeof request !== 'object') { throw new InvalidJsonContentTypeError('Missing or invalid request body', 400); } const modified = preRequestHandlerWrapper(request); return modified; } // === Unified Error Handler === function handleError(err, res) { const isJsonTypeError = err instanceof InvalidJsonContentTypeError || err?.message?.includes('Body content-type is not valid JSON'); const status = isJsonTypeError ? err.statusCode || 415 : 500; return res.status(status).json({ error: err.name || 'InternalServerError', message: err.message || 'Unexpected error occurred', ...(err.details && { details: err.details }), }); } let currentContext = null; let currentRequest = null; function createContext() { return { addedQueryParams: {}, removedQueryParams: [], addedHeaders: {}, removedHeaders: [], method: null, body: null }; } export function preRequestHandlerWrapper(request) { currentContext = createContext(); currentRequest = request; preRequestHandler(); const ctx = currentContext; currentContext = null; currentRequest = null; return ctx; } export function preRequestHandler() { const headerValue = getHeader('x-api-key'); setHeader('x-api-key-1', headerValue); setQueryParam('accessKey', getQueryParam('queryParam2')); removeQueryParam('queryParam2'); const body = getJsonBody(); if (body) { body.modifiedAt = Date.now(); body.transformedText = "Pre Request Transformed Text"; setJsonBody(body); } } // ========== Utility functions using currentRequest ========== export function setHeader(key, value) { if (!currentRequest?.headers) currentRequest.headers = {}; currentRequest.headers[key.toLowerCase()] = value; currentContext?.addedHeaders && (currentContext.addedHeaders[key.toLowerCase()] = value); } export function removeHeader(key) { if (currentRequest?.headers?.[key.toLowerCase()] !== undefined) { delete currentRequest.headers[key.toLowerCase()]; currentContext?.removedHeaders?.push(key.toLowerCase()); } } export function setQueryParam(key, value) { const url = new URL(currentRequest.url); url.searchParams.set(key, value); currentRequest.url = url.toString(); currentContext?.addedQueryParams && (currentContext.addedQueryParams[key] = value); } export function removeQueryParam(key) { const url = new URL(currentRequest.url); url.searchParams.delete(key); currentRequest.url = url.toString(); currentContext?.removedQueryParams?.push(key); } export function setMethod(method) { if (typeof method === 'string') { currentRequest.method = method.toUpperCase(); currentContext && (currentContext.method = currentRequest.method); } } export function getJsonBody() { if (!currentRequest?.body) return null; const contentType = currentRequest.contentType || currentRequest.headers?.['content-type'] || ''; if (!contentType.includes('application/json')) { throw new InvalidJsonContentTypeError(); } try { return typeof currentRequest.body === 'string' ? JSON.parse(currentRequest.body) : currentRequest.body; } catch (err) { throw new InvalidJsonContentTypeError('Failed to parse JSON body', 415, { originalError: err }); } } export function setJsonBody(json) { const contentType = currentRequest.contentType || currentRequest.headers?.['content-type'] || ''; if (!contentType.includes('application/json')) { throw new InvalidJsonContentTypeError(); } try { currentRequest.body = JSON.stringify(json); currentContext && (currentContext.body = json); } catch (err) { throw new InvalidJsonContentTypeError('Failed to stringify JSON body', 415, { originalError: err }); } } export function getQueryParam(key) { try { const url = new URL(currentRequest.url); return url.searchParams.get(key); } catch { return null; } } export function getHeader(key) { if (!currentRequest?.headers) return null; return currentRequest.headers[key.toLowerCase()] || null; } // === Custom Exception Class === class InvalidJsonContentTypeError extends Error { constructor(message = 'Body content-type is not valid JSON', statusCode = 415, details = {}) { super(message); this.name = 'InvalidJsonContentTypeError'; this.statusCode = statusCode; this.details = details; } }