X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fcontent-negotiation.js;h=fcf99adafcdb26f8e726a2203c9b4cfeca363346;hb=refs%2Fheads%2Fv2.1-dev;hp=1425852ffa30925646bfcbc4809bb79d23c308ae;hpb=29837f0eeb9fcb4c53426e5bd89e9bdf7e9d961b;p=squeep-api-dingus diff --git a/lib/content-negotiation.js b/lib/content-negotiation.js index 1425852..fcf99ad 100644 --- a/lib/content-negotiation.js +++ b/lib/content-negotiation.js @@ -7,12 +7,16 @@ const Enum = require('./enum'); // A weight value smaller than the allowed resolution, for minute wildcard de-preferencing. const WeightIota = 0.0001; +/** + * Methods for negotiating content types. + */ class ContentNegotiation { /** * Convert accept clause string to object. * Adjust weight based on wildcards, to prefer literal matches. - * @param {string} clause + * @param {string} clause portion of an accept header + * @returns {object|undefined} details of clause */ static _unpackAcceptClause(clause) { let params = clause.split(';'); @@ -20,7 +24,7 @@ class ContentNegotiation { if (type) { let weight = 1.0; params = params.reduce((acc, param) => { - const [p, v] = common.splitFirst(param, '=').map((x) => x && x.trim()); + const [p, v] = common.splitFirst(param, '=').map((x) => x?.trim()); if (p && v) { if (p === 'q') { weight = Number(v); @@ -44,18 +48,22 @@ class ContentNegotiation { /** * Split an accept field into clauses, return list of clauses sorted by heaviest weights first. - * @param {string} acceptHeader + * @param {string} acceptHeader collection of accept clauses + * @returns {object[]} array of clause details sorted by desirability */ static _acceptClauses(acceptHeader) { - const clauses = (acceptHeader||'').split(',').map((clause) => ContentNegotiation._unpackAcceptClause(clause)).filter((clause) => clause); + const clauses = (acceptHeader||'').split(',') + .map((clause) => ContentNegotiation._unpackAcceptClause(clause)) + .filter((clause) => clause); return clauses.sort((a, b) => b.weight - a.weight); } /** * Check if an Accept-able Content-Type matches a fixed Content-Type. * (Allows for '*' fields in Accept-able type.) - * @param {string} pattern - * @param {string} type + * @param {string} acceptableType explicit or wildcard + * @param {string} fixedType explicit + * @returns {boolean} matches */ static _matchType(acceptableType, fixedType) { acceptableType = common.splitFirst(acceptableType, '/', '*'); @@ -74,8 +82,9 @@ class ContentNegotiation { /** * Return the best match between available and acceptable types. - * @param {string[]} acceptableTypes - * @param {string} acceptHeader + * @param {string[]} acceptableTypes available types + * @param {string} acceptHeader accept header + * @returns {string|undefined} best matched type */ static accept(acceptableTypes, acceptHeader) { const validTypesQuality = {}; @@ -100,6 +109,7 @@ class ContentNegotiation { if (acc === undefined && validTypesQuality[cur] !== 0.0) { return cur; } + // istanbul ignore next // eslint-disable-next-line security/detect-object-injection return validTypesQuality[acc] < validTypesQuality[cur] ? cur : acc; }, undefined); @@ -110,7 +120,8 @@ class ContentNegotiation { * Return all viable matches between acceptable and requested encodings, ordered by highest preference first. * TODO: sort equal q-values by server-preference rather than header order * @param {string[]} acceptableEncodings e.g. ['br', 'gzip'] in order of server preference - * @param {string} acceptHeader + * @param {string} acceptHeader encoding header + * @returns {string[]} preferred encoding */ static preferred(acceptableEncodings, acceptHeader) { const Identity = Enum.EncodingType.Identity;