UNPKG

@foundatiofx/fetchclient

Version:

A typed JSON fetch client with middleware support for Deno, Node and the browser.

71 lines (70 loc) 2.07 kB
const MAX_HEADER_LENGTH = 2000; const THROW_ON_MAX_HEADER_LENGTH_EXCEEDED = false; function hasRel(x) { return x && x.rel; } function intoRels(acc, x) { function splitRel(rel) { acc[rel] = Object.assign({}, x, { rel: rel }); } x.rel.split(/\s+/).forEach(splitRel); return acc; } // deno-lint-ignore no-explicit-any function createObjects(acc, p) { // rel="next" => 1: rel 2: next const m = p.match(/\s*(.+)\s*=\s*"?([^"]+)"?/); if (m) acc[m[1]] = m[2]; return acc; } function parseLink(link) { try { const m = link.match(/<?([^>]*)>(.*)/); if (!m) return null; const linkUrl = m[1]; const parts = m[2].split(";"); const qry = {}; // The origin is unused but it's required to parse relative URLs const url = new URL(linkUrl, "https://example.com"); for (const [key, value] of url.searchParams) { qry[key] = value; } parts.shift(); let info = parts.reduce(createObjects, {}); info = Object.assign({}, qry, info); info.url = linkUrl; return info; } catch { return null; } } function checkHeader(linkHeader, options) { if (!linkHeader) return false; options = options || {}; const maxHeaderLength = options.maxHeaderLength || MAX_HEADER_LENGTH; const throwOnMaxHeaderLengthExceeded = options.throwOnMaxHeaderLengthExceeded || THROW_ON_MAX_HEADER_LENGTH_EXCEEDED; if (linkHeader.length > maxHeaderLength) { if (throwOnMaxHeaderLengthExceeded) { throw new Error("Input string too long, it should be under " + maxHeaderLength + " characters."); } else { return false; } } return true; } function parseLinkHeader(linkHeader, options) { if (!checkHeader(linkHeader, options)) return null; return linkHeader.split(/,\s*</) .map(parseLink) .filter(hasRel) .reduce(intoRels, {}); } export { parseLinkHeader };