@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
JavaScript
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
};