//#region src/utils/accept.ts const isWhitespace = (char) => char === 32 || char === 9 || char === 10 || char === 13; const consumeWhitespace = (acceptHeader, startIndex) => { while (startIndex < acceptHeader.length) { if (!isWhitespace(acceptHeader.charCodeAt(startIndex))) break; startIndex++; } return startIndex; }; const ignoreTrailingWhitespace = (acceptHeader, startIndex) => { while (startIndex > 0) { if (!isWhitespace(acceptHeader.charCodeAt(startIndex - 1))) break; startIndex--; } return startIndex; }; const skipInvalidParam = (acceptHeader, startIndex) => { while (startIndex < acceptHeader.length) { const char = acceptHeader.charCodeAt(startIndex); if (char === 59) return [startIndex + 1, true]; if (char === 44) return [startIndex + 1, false]; startIndex++; } return [startIndex, false]; }; const skipInvalidAcceptValue = (acceptHeader, startIndex) => { let i = startIndex; let inQuotes = false; while (i < acceptHeader.length) { const char = acceptHeader.charCodeAt(i); if (inQuotes && char === 92) i++; else if (char === 34) inQuotes = !inQuotes; else if (!inQuotes && char === 44) return i + 1; i++; } return i; }; const getNextParam = (acceptHeader, startIndex) => { startIndex = consumeWhitespace(acceptHeader, startIndex); let i = startIndex; let key; let value; let hasNext = false; while (i < acceptHeader.length) { const char = acceptHeader.charCodeAt(i); if (char === 61) { key = acceptHeader.slice(startIndex, ignoreTrailingWhitespace(acceptHeader, i)); i++; break; } if (char === 59) return [ i + 1, void 0, void 0, true ]; if (char === 44) return [ i + 1, void 0, void 0, false ]; i++; } if (key === void 0) return [ i, void 0, void 0, false ]; i = consumeWhitespace(acceptHeader, i); if (acceptHeader.charCodeAt(i) === 61) { const skipResult = skipInvalidParam(acceptHeader, i + 1); return [ skipResult[0], key, void 0, skipResult[1] ]; } let inQuotes = false; const paramStartIndex = i; while (i < acceptHeader.length) { const char = acceptHeader.charCodeAt(i); if (inQuotes && char === 92) i++; else if (char === 34) { if (inQuotes) { let nextIndex = consumeWhitespace(acceptHeader, i + 1); const nextChar = acceptHeader.charCodeAt(nextIndex); if (nextIndex < acceptHeader.length && !(nextChar === 59 || nextChar === 44)) { const skipResult = skipInvalidParam(acceptHeader, nextIndex); return [ skipResult[0], key, void 0, skipResult[1] ]; } value = acceptHeader.slice(paramStartIndex + 1, i); if (value.includes("\\")) value = value.replace(/\\(.)/g, "$1"); if (nextChar === 44) return [ nextIndex + 1, key, value, false ]; if (nextChar === 59) { hasNext = true; nextIndex++; } i = nextIndex; break; } inQuotes = true; } else if (!inQuotes && (char === 59 || char === 44)) { value = acceptHeader.slice(paramStartIndex, ignoreTrailingWhitespace(acceptHeader, i)); if (char === 59) hasNext = true; i++; break; } i++; } return [ i, key, value ?? acceptHeader.slice(paramStartIndex, ignoreTrailingWhitespace(acceptHeader, i)), hasNext ]; }; const getNextAcceptValue = (acceptHeader, startIndex) => { const accept = { type: "", params: Object.create(null), q: 1 }; startIndex = consumeWhitespace(acceptHeader, startIndex); let i = startIndex; while (i < acceptHeader.length) { const char = acceptHeader.charCodeAt(i); if (char === 59 || char === 44) { accept.type = acceptHeader.slice(startIndex, ignoreTrailingWhitespace(acceptHeader, i)); i++; if (char === 44) return [i, accept.type ? accept : void 0]; if (!accept.type) return [skipInvalidAcceptValue(acceptHeader, i), void 0]; break; } i++; } if (!accept.type) { accept.type = acceptHeader.slice(startIndex, ignoreTrailingWhitespace(acceptHeader, acceptHeader.length)); return [acceptHeader.length, accept.type ? accept : void 0]; } let param; let value; let hasNext; while (i < acceptHeader.length) { [i, param, value, hasNext] = getNextParam(acceptHeader, i); if (param && value) accept.params[param] = value; if (!hasNext) break; } return [i, accept]; }; const parseAccept = (acceptHeader) => { if (!acceptHeader) return []; const values = []; let i = 0; let accept; let requiresSort = false; let lastAccept; while (i < acceptHeader.length) { [i, accept] = getNextAcceptValue(acceptHeader, i); if (accept) { accept.q = parseQuality(accept.params.q ?? accept.params.Q); values.push(accept); if (lastAccept && lastAccept.q < accept.q) requiresSort = true; lastAccept = accept; } } if (requiresSort) values.sort((a, b) => b.q - a.q); return values; }; const parseQuality = (qVal) => { if (qVal === void 0) return 1; if (qVal === "") return 1; if (qVal === "NaN") return 0; const num = Number(qVal); if (Number.isNaN(num)) return 1; if (num < 0) return 0; if (num > 1) return 1; return num; }; //#endregion export { parseAccept };