157 lines
4.6 KiB
JavaScript
157 lines
4.6 KiB
JavaScript
// Define the handler function
|
|
export const handler = async (request, res) => {
|
|
try {
|
|
console.log("Request strated")
|
|
const { request } = req.body;
|
|
const modified = preRequestHandlerWrapper(request);
|
|
res.status(200).json(modified);
|
|
} catch (err) {
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
|