UNPKG

@chubbyts/chubbyts-negotiation

Version:
55 lines (54 loc) 2.18 kB
import { resolveHeaderToMap } from './negotiation.js'; const escapeStringRegexp = (regex) => { return regex.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }; const compareMediaTypeWithTypeOnly = (supportedValues, mediaType, attributes) => { const mediaTypeParts = mediaType.match(/([^/+]+)\/\*/); if (null === mediaTypeParts) { return undefined; } for (const supportedValue of supportedValues) { if (null !== supportedValue.match(new RegExp('^' + escapeStringRegexp(mediaTypeParts[1]) + '/'))) { return { value: supportedValue, attributes }; } } return undefined; }; const compareMediaTypes = (supportedValues, suffixSupportedValues, headerToMap) => { for (const [mediaType, attributes] of headerToMap.entries()) { if (-1 !== supportedValues.indexOf(mediaType)) { return { value: mediaType, attributes }; } } for (const [mediaType, attributes] of headerToMap.entries()) { if (suffixSupportedValues.has(mediaType)) { return { value: suffixSupportedValues.get(mediaType), attributes }; } } for (const [mediaType, attributes] of headerToMap.entries()) { const negotiatedValue = compareMediaTypeWithTypeOnly(supportedValues, mediaType, attributes); if (undefined !== negotiatedValue) { return negotiatedValue; } } if (headerToMap.has('*/*')) { return { value: supportedValues[0], attributes: headerToMap.get('*/*') }; } return undefined; }; export const createAcceptNegotiator = (supportedValues) => { const suffixSupportedValues = new Map(supportedValues.map((supportedValue) => { const supportedValueParts = supportedValue.match(/([^/+]+)\/([^/+]+)\+([^/+]+)/); return [ null !== supportedValueParts ? supportedValueParts[1] + '/' + supportedValueParts[3] : undefined, supportedValue, ]; })); return { negotiate: (header) => { const headerToMap = resolveHeaderToMap(header); return compareMediaTypes(supportedValues, suffixSupportedValues, headerToMap); }, supportedValues, }; };