Skip to content

Commit ee8b3c3

Browse files
committed
Media Type: Expose more-complete, unstringified parse results
1 parent bd3e873 commit ee8b3c3

File tree

3 files changed

+55
-9
lines changed

3 files changed

+55
-9
lines changed

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ Negotiator.prototype.mediaType = function mediaType(available) {
4747
return set && set[0];
4848
};
4949

50-
Negotiator.prototype.mediaTypes = function mediaTypes(available) {
51-
return preferredMediaTypes(this.request.headers.accept, available);
50+
Negotiator.prototype.mediaTypes = function mediaTypes(available, options) {
51+
return preferredMediaTypes(this.request.headers.accept, available, options);
5252
};
5353

5454
// Backwards compatibility

lib/mediaType.js

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,25 +120,45 @@ function specify(type, spec, index) {
120120

121121
}
122122

123-
function preferredMediaTypes(accept, provided) {
123+
/**
124+
* Returns a list of the acceptable media ranges in preferred order.
125+
*
126+
* @param {string} accept The raw contents of the `Accept` header
127+
* @param {string[]} provided The media ranges the server can produce
128+
* for the resource in question.
129+
* @param {Object} options Configuration options
130+
* @param {boolean} options.detailed If true, this function returns a
131+
* {type, parameters, q} object for each acceptable type, rather than a string.
132+
*/
133+
function preferredMediaTypes(accept, provided, options) {
124134
// RFC 2616 sec 14.2: no header = */*
125135
var accepts = parseAccept(accept === undefined ? '*/*' : accept || '');
136+
var detailed = options && options.detailed;
137+
138+
var specDetails = function(spec) {
139+
return {
140+
type: "" + spec.type + '/' + spec.subtype,
141+
parameters: spec.params,
142+
q: spec.q
143+
};
144+
};
126145

146+
// return sorted list of all types if none are provided.
127147
if (!provided) {
128-
// sorted list of all types
129-
return accepts.filter(isQuality).sort(compareSpecs).map(function getType(spec) {
130-
return spec.full;
131-
});
148+
var mapper = detailed ? specDetails : function(spec) { return spec.full; };
149+
return accepts.filter(isQuality).sort(compareSpecs).map(mapper);
132150
}
133151

134152
var priorities = provided.map(function getPriority(type, index) {
135153
return getMediaTypePriority(type, accepts, index);
136154
});
137155

138-
// sorted list of accepted types
139-
return priorities.filter(isQuality).sort(compareSpecs).map(function getType(priority) {
156+
// sorted list of acceptable types
157+
var acceptables = priorities.filter(isQuality).sort(compareSpecs).map(function getType(priority) {
140158
return provided[priorities.indexOf(priority)];
141159
});
160+
161+
return detailed ? acceptables.map(parseMediaType).map(specDetails) : acceptables;
142162
}
143163

144164
function compareSpecs(a, b) {

test/mediaType.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,32 @@ describe('negotiator.mediaTypes()', function () {
194194
})
195195
})
196196

197+
describe('negotiator.mediaTypes(_, {detailed: true})', function() {
198+
whenAccept('text/html;LEVEL=1, application/json;q=0.5', function () {
199+
it('should return more-detailed spec objects', function () {
200+
assert.deepEqual(
201+
this.negotiator.mediaTypes(undefined, {detailed: true}),
202+
[
203+
{"type": "text/html", "parameters": {"level": "1"}, "q": 1},
204+
{"type": "application/json", "parameters": {}, "q": 0.5},
205+
]
206+
);
207+
});
208+
209+
it('should accept a provided list, but still match parameters exactly', function () {
210+
assert.deepEqual(
211+
this.negotiator.mediaTypes(["text/html"], {detailed: true}),
212+
[]
213+
);
214+
215+
assert.deepEqual(
216+
this.negotiator.mediaTypes(["text/html; level=1"], {detailed: true}),
217+
[{"type": "text/html", "parameters": {"level": "1"}, "q": 1}]
218+
);
219+
});
220+
});
221+
});
222+
197223
describe('negotiator.mediaTypes(array)', function () {
198224
whenAccept(undefined, function () {
199225
it('should return return original list', mediaTypesNegotiated(

0 commit comments

Comments
 (0)