diff --git a/handler.js b/handler.js index 2e720b7..9ba75c5 100644 --- a/handler.js +++ b/handler.js @@ -1,25 +1,156 @@ // Define the handler function -export const handler = async (event, res) => { +export const handler = async (request, res) => { try { - // Prepare the response JSON - const responseJson = { - message: "Hello World" - }; + console.log("Request strated") + const { request } = req.body; + const modified = preRequestHandlerWrapper(request); + res.status(200).json(modified); + } catch (err) { - // Print the JSON response to stdout - console.log(JSON.stringify(responseJson)); - - // Set the response headers - res.setHeader('Content-Type', 'application/json'); - - // Send the response JSON - res.end(JSON.stringify(responseJson)); - } catch (error) { - // Handle errors - console.error(error); - // Send an error response if needed - res.statusCode = 500; - res.setHeader('Content-Type', 'text/plain'); - res.end('Internal Server Error'); + if (err?.message.includes('Body content-type is not valid JSON')) { + res.status(err.statusCode).json({ + error: err.name, + message: err.message, + ...(err.details && { details: err.details }) + }); + } else { + res.status(500).json({ + error: err.name || 'InternalServerError', + message: err.message || 'Something went wrong', + }); + } } }; + +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; + } +} + +