Latest
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869/** * Request interface extension with additional `parsedBody` property (where parsed body gets stored) */export interface ReqWithBody<T = Record<string, unknown>> extends Request { parsedBody?: T}
/** * Universal body parser function * @param fn request body formatter */export const bodyParser = <T>(fn: (body: string) => T) => async (req: ReqWithBody<T>) => { const body = await req.text()
req.parsedBody = fn(body)
return req.parsedBody }
type NextFunction = (err?: Error) => void
/** * Parse a request with JSON body and `Content-Type`: `application/json` header. * @param req Server request * @param _ * @param next */export const json = async <T = Record<string, unknown>>( req: ReqWithBody<T>, _?: unknown, next?: NextFunction,) => { if (req.headers.get('content-type') === 'application/json') { try { await bodyParser((x) => JSON.parse(x.toString()))(req) } catch (e) { next?.(e) } finally { next?.() } } else next?.()}
/** * Parse a form with the body and `Content-Type`: `application/x-www-urlencoded` header. * @param req Server request * @param _ * @param next */export const urlencoded = async ( req: ReqWithBody<Record<string, string>>, _?: unknown, next?: NextFunction,) => { if (req.headers.get('content-type') === 'application/x-www-form-urlencoded') { try { await bodyParser((x) => { const u = new URLSearchParams(x.toString()) return Object.fromEntries(u.entries()) })(req) } catch (e) { next?.(e) } finally { next?.() } } else next?.()}