UNPKG

@thi.ng/server

Version:

Minimal HTTP server with declarative routing, static file serving and freely extensible via pre/post interceptors

58 lines (57 loc) 1.81 kB
import { isArray, isProtoPath } from "@thi.ng/checks"; import { illegalArgs } from "@thi.ng/errors"; import { setInUnsafe, updateInUnsafe } from "@thi.ng/paths"; const parseSearchParams = (params) => { let acc = {}; for (const [k, v] of params) { if (k.includes("[")) acc = parseObjectVal(acc, k, v); else if (!isProtoPath(k)) acc[k] = v; } return acc; }; const parseQuerystring = (url) => { const idx = url.indexOf("?"); return idx >= 0 ? parseFormData(url.substring(idx + 1)) : {}; }; const parseRequestFormData = async (req) => { let body = ""; for await (let chunk of req) body += chunk.toString(); return parseFormData(body); }; const parseFormData = (body) => body.split("&").reduce((acc, x) => { x = decodeURIComponent(x.replace(/\+/g, " ")); const idx = x.indexOf("="); if (idx < 1) return acc; const k = x.substring(0, idx); const v = x.substring(idx + 1); if (k.includes("[")) return parseObjectVal(acc, k, v); if (!isProtoPath(k)) acc[k] = v; return acc; }, {}); const parseObjectVal = (acc, key, val) => { const parts = key.split("["); if (!parts[0]) __illegal(key); const path = [parts[0]]; for (let i = 1, n = parts.length - 1; i <= n; i++) { const p = parts[i]; if (p === "]") { if (i < n) __illegal(key); return !isProtoPath(path) ? updateInUnsafe( acc, path, (curr) => isArray(curr) ? [...curr, val] : [val] ) : acc; } const idx = p.indexOf("]"); if (idx < 0 || idx < p.length - 1) __illegal(key); path.push(p.substring(0, p.length - 1)); } return !isProtoPath(path) ? setInUnsafe(acc, path, val) : acc; }; const __illegal = (key) => illegalArgs("invalid form param: " + key); export { parseFormData, parseQuerystring, parseRequestFormData, parseSearchParams };