UNPKG

tailorx

Version:

Tailor assembles a web page from multiple fragments

95 lines (88 loc) 2.41 kB
'use strict'; /** * Parse link headers * '<http://example.com/script.js>; rel="fragment-script"' * * [ * { * rel: "fragment-script", * uri: "http://localhost:8080/script.js" * } * ] * * Based on code from parse-link-header! * https://github.com/thlorenz/parse-link-header/blob/master/index.js */ module.exports = function parseLinkHeader(linkHeader) { return fixLink(linkHeader) .split(/,\s*</) .map(link => { const match = link.match(/<?([^>]*)>(.*)/); if (!match) { return null; } const linkUrl = match[1]; return { uri: linkUrl, rel: getRelValue(match[2]), params: getParams(match[2]) }; }) .filter(v => v && v.rel != null) .reduce((acc, curr) => { return acc.concat(curr); }, []); }; /** * Get the value of rel attribute * * rel="fragment-script" -> ["rel", "fragment-script"] */ function getRelValue(parts) { const m = parts.match(/\s*rel\s*=\s*"?([^"]+)"?/); if (!m) { return null; } return m[1]; } /** * Get the params of rel attribute * * rel="fragment-script" -> ["rel", "fragment-script"] */ function getParams(parts) { return parts.split(';').reduce((acc, attribute) => { let [key, value] = attribute.trim().split('='); key = key.trim(); if (value === undefined || key === 'rel') { return acc; } acc[key] = value .trim() .replace(/(^"|"$)/g, '') .trim(); return acc; }, {}); } function fixLink(headerLink) { return headerLink .split(',') .map(link => { return link .split(';') .map((attribute, index) => { if (index) { const [key, value] = attribute.trim().split('='); return !value || value.trim().startsWith('"') ? attribute : `${key}="${value}"`; } else { return !attribute || attribute.trim().startsWith('<') ? attribute : `<${attribute}>`; } }) .join(';'); }) .join(','); }