1 var Negotiator = require('negotiator')
2 var mime = require('mime-types')
6 module.exports = Accepts
8 function Accepts(req) {
9 if (!(this instanceof Accepts))
10 return new Accepts(req)
12 this.headers = req.headers
13 this.negotiator = Negotiator(req)
17 * Check if the given `type(s)` is acceptable, returning
18 * the best match when true, otherwise `undefined`, in which
19 * case you should respond with 406 "Not Acceptable".
21 * The `type` value may be a single mime type string
22 * such as "application/json", the extension name
23 * such as "json" or an array `["json", "html", "text/plain"]`. When a list
24 * or array is given the _best_ match, if any is returned.
28 * // Accept: text/html
32 * // Accept: text/*, application/json
35 * this.types('text/html');
37 * this.types('json', 'text');
39 * this.types('application/json');
40 * // => "application/json"
42 * // Accept: text/*, application/json
43 * this.types('image/png');
47 * // Accept: text/*;q=.5, application/json
48 * this.types(['html', 'json']);
49 * this.types('html', 'json');
52 * @param {String|Array} type(s)...
53 * @return {String|Array|Boolean}
57 Accepts.prototype.type =
58 Accepts.prototype.types = function (types) {
59 if (!Array.isArray(types)) types = slice.call(arguments);
60 var n = this.negotiator;
61 if (!types.length) return n.mediaTypes();
62 if (!this.headers.accept) return types[0];
63 var mimes = types.map(extToMime);
64 var accepts = n.mediaTypes(mimes.filter(validMime));
65 var first = accepts[0];
66 if (!first) return false;
67 return types[mimes.indexOf(first)];
71 * Return accepted encodings or best fit based on `encodings`.
73 * Given `Accept-Encoding: gzip, deflate`
74 * an array sorted by quality is returned:
78 * @param {String|Array} encoding(s)...
79 * @return {String|Array}
83 Accepts.prototype.encoding =
84 Accepts.prototype.encodings = function (encodings) {
85 if (!Array.isArray(encodings)) encodings = slice.call(arguments);
86 var n = this.negotiator;
87 if (!encodings.length) return n.encodings();
88 return n.encodings(encodings)[0] || false;
92 * Return accepted charsets or best fit based on `charsets`.
94 * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
95 * an array sorted by quality is returned:
97 * ['utf-8', 'utf-7', 'iso-8859-1']
99 * @param {String|Array} charset(s)...
100 * @return {String|Array}
104 Accepts.prototype.charset =
105 Accepts.prototype.charsets = function (charsets) {
106 if (!Array.isArray(charsets)) charsets = [].slice.call(arguments);
107 var n = this.negotiator;
108 if (!charsets.length) return n.charsets();
109 if (!this.headers['accept-charset']) return charsets[0];
110 return n.charsets(charsets)[0] || false;
114 * Return accepted languages or best fit based on `langs`.
116 * Given `Accept-Language: en;q=0.8, es, pt`
117 * an array sorted by quality is returned:
121 * @param {String|Array} lang(s)...
122 * @return {Array|String}
126 Accepts.prototype.lang =
127 Accepts.prototype.langs =
128 Accepts.prototype.language =
129 Accepts.prototype.languages = function (langs) {
130 if (!Array.isArray(langs)) langs = slice.call(arguments);
131 var n = this.negotiator;
132 if (!langs.length) return n.languages();
133 if (!this.headers['accept-language']) return langs[0];
134 return n.languages(langs)[0] || false;
138 * Convert extnames to mime.
140 * @param {String} type
145 function extToMime(type) {
146 if (~type.indexOf('/')) return type;
147 return mime.lookup(type);
151 * Check if mime is valid.
153 * @param {String} type
158 function validMime(type) {
159 return typeof type === 'string';