@sota1235/parse-link-header-ts
Version:
Parses a link header and returns paging information for each contained link.
54 lines (53 loc) • 1.44 kB
JavaScript
const PARSE_LINK_HEADER_MAXLEN = 2000;
function hasRel(link) {
if (link === null) {
return false;
}
return link.rel != null;
}
function intoRels(acc, link) {
function splitRel(rel) {
acc[rel] = { ...link, ...{ rel } };
}
link.rel.split(/\s+/).forEach(splitRel);
return acc;
}
function createObjects(acc, p) {
const m = p.match(/\s*(.+)\s*=\s*"?([^"]+)"?/);
if (m)
acc[m[1]] = m[2];
return acc;
}
function parseLink(link) {
const m = link.match(/<?([^>]*)>(.*)/);
if (m === null) {
throw new Error('Invalid link header');
}
const linkUrl = m[1];
const parts = m[2].split(';');
const parsedUrl = new URL(linkUrl);
const qry = {};
for (const [key, value] of parsedUrl.searchParams) {
qry[key] = value;
}
parts.shift();
let info = parts.reduce(createObjects, {});
info = { ...qry, ...info, url: linkUrl };
return info;
}
function checkHeader(linkHeader) {
if (linkHeader.length > PARSE_LINK_HEADER_MAXLEN) {
throw new Error(`Input string too long, it should be under ${PARSE_LINK_HEADER_MAXLEN} characters.`);
}
}
export default function (linkHeader) {
if (linkHeader === '') {
throw new Error('linkHeader is empty');
}
checkHeader(linkHeader);
return linkHeader
.split(/,\s*</)
.map(parseLink)
.filter(hasRel)
.reduce(intoRels, {});
}