export const hasBody = (method) => ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method); export const p = (fn) => async (req, _res, next) => { try { let body = ''; for await (const chunk of req) body += chunk; return fn(body); } catch (e) { next(e); } }; const custom = (fn) => async (req, _res, next) => { req.body = await p(fn)(req, _res, next); next(); }; const json = () => async (req, res, next) => { if (hasBody(req.method)) { req.body = await p((x) => (x ? JSON.parse(x.toString()) : {}))(req, res, next); next(); } else next(); }; const raw = () => async (req, _res, next) => { if (hasBody(req.method)) { req.body = await p((x) => x)(req, _res, next); next(); } else next(); }; const text = () => async (req, _res, next) => { if (hasBody(req.method)) { req.body = await p((x) => x.toString())(req, _res, next); next(); } else next(); }; const urlencoded = () => async (req, res, next) => { if (hasBody(req.method)) { req.body = await p((x) => { const urlSearchParam = new URLSearchParams(x.toString()); return Object.fromEntries(urlSearchParam.entries()); })(req, res, next); next(); } else next(); }; const getBoundary = (contentType) => { const match = /boundary=(.+);?/.exec(contentType); return match ? `--${match[1]}` : null; }; const parseMultipart = (body, boundary) => { const parts = body.split(new RegExp(`${boundary}(--)?`)).filter((part) => !!part && /content-disposition/i.test(part)); const parsedBody = {}; parts.map((part) => { const [headers, ...lines] = part.split('\r\n').filter((part) => !!part); const data = lines.join('\r\n').trim(); const name = /name="(.+?)"/.exec(headers)[1]; const filename = /filename="(.+?)"/.exec(headers); if (filename) { const contentTypeMatch = /Content-Type: (.+)/i.exec(data); const fileContent = data.slice(contentTypeMatch[0].length + 2); return Object.assign(parsedBody, { [name]: new File([fileContent], filename[1], { type: contentTypeMatch[1] }) }); } return Object.assign(parsedBody, { [name]: data }); }); return parsedBody; }; const multipart = () => async (req, res, next) => { if (hasBody(req.method)) { req.body = await p((x) => { const boundary = getBoundary(req.headers['content-type']); if (boundary) return parseMultipart(x, boundary); })(req, res, next); next(); } else next(); }; export { custom, json, raw, text, urlencoded, multipart };