negotiator-currency
Version:
HTTP content negotiation (plus currency)
93 lines (77 loc) • 2.09 kB
JavaScript
module.exports = preferredTokens;
preferredTokens.preferredTokens = preferredTokens;
function parseAcceptToken(accept) {
return accept.split(',').map(function(e) {
return parseToken(e.trim());
}).filter(function(e) {
return e && e.q > 0;
});
}
function parseToken(s) {
var match = s.match(/^\s*(\S+?)(?:-(\S+?))?\s*(?:;(.*))?$/);
if (!match) return null;
var prefix = match[1],
suffix = match[2],
full = prefix;
if (suffix) full += "-" + suffix;
var q = 1;
if (match[3]) {
var params = match[3].split(';')
for (var i = 0; i < params.length; i ++) {
var p = params[i].split('=');
if (p[0] === 'q') q = parseFloat(p[1]);
}
}
return {
prefix: prefix,
suffix: suffix,
q: q,
full: full
};
}
function getTokenPriority(token, accepted) {
var match = getClosestMatch(token, accepted);
return match ? match.q : 0;
}
function getClosestMatch(token, accepted) {
var parsed = parseToken(token);
var matches = accepted.filter(function(a) {
return a.full === parsed.full;
});
if (matches.length) return matches[0];
matches = accepted.filter(function(a) {
return a.prefix === parsed.prefix && !a.suffix;
});
if (matches.length) return matches[0];
matches = accepted.filter(function(a) {
return a.prefix === parsed.prefix;
});
if (matches.length) return matches[0];
matches = accepted.filter(function(a) {
return a.prefix === '*';
});
return matches[0];
}
function preferredTokens(accept, provided) {
accept = parseAcceptToken(accept || '');
if (provided) {
var ret = provided.map(function(type) {
return [type, getTokenPriority(type, accept)];
}).filter(function(pair) {
return pair[1] > 0;
}).sort(function(a, b) {
// revsort
return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1;
}).map(function(pair) {
return pair[0];
});
return ret;
} else {
return accept.sort(function (a, b) {
// revsort
return a.q < b.q ? 1 : -1;
}).map(function(type) {
return type.full;
});
}
}