Skip to content

Commit f7ccb94

Browse files
authored
Merge pull request #156 from broofa/facets
Prioritize by "facet" when resolving type collisions
2 parents fb02668 + 902ec07 commit f7ccb94

File tree

6 files changed

+96
-15
lines changed

6 files changed

+96
-15
lines changed

.eslintrc.json

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"root": true,
3+
"env": {
4+
"browser": true,
5+
"commonjs": true,
6+
"node": true,
7+
"mocha": true
8+
},
9+
"extends": ["eslint:recommended"],
10+
"installedESLint": true,
11+
"rules": {
12+
"array-bracket-spacing": ["warn", "never"],
13+
"arrow-body-style": ["warn", "as-needed"],
14+
"arrow-parens": ["warn", "as-needed"],
15+
"arrow-spacing": "warn",
16+
"brace-style": "warn",
17+
"camelcase": "warn",
18+
"comma-spacing": ["warn", {"after": true}],
19+
"dot-notation": "warn",
20+
"indent": ["warn", 2, {
21+
"SwitchCase": 1,
22+
"FunctionDeclaration": {"parameters": 1},
23+
"MemberExpression": 1,
24+
"CallExpression": {"arguments": 1}
25+
}],
26+
"key-spacing": ["warn", {"beforeColon": false, "afterColon": true, "mode": "minimum"}],
27+
"keyword-spacing": "warn",
28+
"no-console": "off",
29+
"no-empty": "off",
30+
"no-multi-spaces": "warn",
31+
"no-redeclare": "off",
32+
"no-restricted-globals": ["warn", "Promise"],
33+
"no-trailing-spaces": "warn",
34+
"no-undef": "error",
35+
"no-unused-vars": ["warn", {"args": "none"}],
36+
"padded-blocks": ["warn", "never"],
37+
"object-curly-spacing": ["warn", "never"],
38+
"quotes": ["warn", "single"],
39+
"react/prop-types": "off",
40+
"react/jsx-no-bind": "off",
41+
"semi": ["warn", "always"],
42+
"space-before-blocks": ["warn", "always"],
43+
"space-before-function-paren": ["warn", "never"],
44+
"space-in-parens": ["warn", "never"]
45+
}
46+
}

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
node_modules
22
npm-debug.log
3+
*.sw* # VIM temp files
4+
.DS_Store # Mac desktop services store

build/test.js

+18-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
var mime = require('../mime');
66
var assert = require('assert');
7-
var path = require('path');
87

98
//
109
// Test mime lookups
@@ -21,6 +20,24 @@ assert.equal('text/plain', mime.lookup('\\txt')); // Windows, extension-l
2120
assert.equal('application/octet-stream', mime.lookup('text.nope')); // unrecognized
2221
assert.equal('fallback', mime.lookup('text.fallback', 'fallback')); // alternate default
2322

23+
//
24+
// Test types that are known to have conflicting definitions but different facet priorities
25+
//
26+
27+
assert.equal('application/octet-stream', mime.lookup('dmg'));
28+
assert.equal('application/bdoc', mime.lookup('bdoc'));
29+
assert.equal('application/octet-stream', mime.lookup('deb'));
30+
assert.equal('application/octet-stream', mime.lookup('iso'));
31+
assert.equal('application/octet-stream', mime.lookup('exe'));
32+
assert.equal('application/octet-stream', mime.lookup('exe'));
33+
assert.equal('application/octet-stream', mime.lookup('dll'));
34+
assert.equal('application/octet-stream', mime.lookup('msi'));
35+
assert.equal('application/vnd.palm', mime.lookup('pdb'));
36+
assert.equal('audio/mp3', mime.lookup('mp3'));
37+
assert.equal('audio/mp4', mime.lookup('m4a'));
38+
assert.equal('font/opentype', mime.lookup('otf'));
39+
assert.equal('image/bmp', mime.lookup('bmp'));
40+
2441
//
2542
// Test extensions
2643
//

mime.js

+27-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
var path = require('path');
21
var fs = require('fs');
32

3+
// If two types claim the same extension, we resolve the conflict by checking
4+
// facet precedence. https://tools.ietf.org/html/rfc6838#section-3
5+
// Facets listed here are in order of decreasing precedence
6+
var FACETS = ['vnd.', 'x-', 'prs.'];
7+
var FACET_RE = new RegExp('/(' + FACETS.join('|') + ')');
8+
49
function Mime() {
510
// Map of extension -> mime type
611
this.types = Object.create(null);
@@ -18,16 +23,27 @@ function Mime() {
1823
*
1924
* @param map (Object) type definitions
2025
*/
21-
Mime.prototype.define = function (map) {
26+
Mime.prototype.define = function(map) {
2227
for (var type in map) {
2328
var exts = map[type];
29+
2430
for (var i = 0; i < exts.length; i++) {
25-
if (process.env.DEBUG_MIME && this.types[exts[i]]) {
26-
console.warn((this._loading || "define()").replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' +
27-
this.types[exts[i]] + ' to ' + type);
31+
var ext = exts[i];
32+
var found = this.types[ext];
33+
34+
// If there's already a type for this extension ...
35+
if (found) {
36+
var pri0 = FACETS.indexOf(FACET_RE.test(found) && RegExp.$1);
37+
var pri1 = FACETS.indexOf(FACET_RE.test(type) && RegExp.$1);
38+
39+
if (process.env.DEBUG_MIME) console.warn('Type conflict for .' + ext +
40+
' (' + found + ' pri=' + pri0 + ', ' + type + ' pri=' + pri1 + ')');
41+
42+
// Prioritize based on facet precedence
43+
if (pri0 <= pri1) continue;
2844
}
2945

30-
this.types[exts[i]] = type;
46+
this.types[ext] = type;
3147
}
3248

3349
// Default extension is the first one we encounter
@@ -48,9 +64,9 @@ Mime.prototype.define = function (map) {
4864
Mime.prototype.load = function(file) {
4965
this._loading = file;
5066
// Read file and split into lines
51-
var map = {},
52-
content = fs.readFileSync(file, 'ascii'),
53-
lines = content.split(/[\r\n]+/);
67+
var map = {};
68+
var content = fs.readFileSync(file, 'ascii');
69+
var lines = content.split(/[\r\n]+/);
5470

5571
lines.forEach(function(line) {
5672
// Clean up whitespace/comments, and split into fields
@@ -69,7 +85,7 @@ Mime.prototype.load = function(file) {
6985
Mime.prototype.lookup = function(path, fallback) {
7086
var ext = path.replace(/.*[\.\/\\]/, '').toLowerCase();
7187

72-
return this.types[ext] || fallback || this.default_type;
88+
return this.types[ext] || fallback || this.default_type; // eslint-disable-line camelcase
7389
};
7490

7591
/**
@@ -87,7 +103,7 @@ var mime = new Mime();
87103
mime.define(require('./types.json'));
88104

89105
// Default type
90-
mime.default_type = mime.lookup('bin');
106+
mime.default_type = mime.lookup('bin'); // eslint-disable-line camelcase
91107

92108
//
93109
// Additional API specific to the default instance

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"mime-db": "^1.22.0"
2222
},
2323
"scripts": {
24-
"prepublish": "node build/build.js > types.json",
24+
"prepare": "node build/build.js > types.json",
2525
"test": "node build/test.js"
2626
},
2727
"keywords": [
@@ -34,5 +34,5 @@
3434
"url": "https://github.com/broofa/node-mime",
3535
"type": "git"
3636
},
37-
"version": "1.3.4"
37+
"version": "1.3.5"
3838
}

types.json

+1-1
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)