Skip to content

Commit

Permalink
Merge pull request #156 from broofa/facets
Browse files Browse the repository at this point in the history
Prioritize by "facet" when resolving type collisions
  • Loading branch information
broofa committed May 11, 2017
2 parents fb02668 + 902ec07 commit f7ccb94
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 15 deletions.
46 changes: 46 additions & 0 deletions .eslintrc.json
@@ -0,0 +1,46 @@
{
"root": true,
"env": {
"browser": true,
"commonjs": true,
"node": true,
"mocha": true
},
"extends": ["eslint:recommended"],
"installedESLint": true,
"rules": {
"array-bracket-spacing": ["warn", "never"],
"arrow-body-style": ["warn", "as-needed"],
"arrow-parens": ["warn", "as-needed"],
"arrow-spacing": "warn",
"brace-style": "warn",
"camelcase": "warn",
"comma-spacing": ["warn", {"after": true}],
"dot-notation": "warn",
"indent": ["warn", 2, {
"SwitchCase": 1,
"FunctionDeclaration": {"parameters": 1},
"MemberExpression": 1,
"CallExpression": {"arguments": 1}
}],
"key-spacing": ["warn", {"beforeColon": false, "afterColon": true, "mode": "minimum"}],
"keyword-spacing": "warn",
"no-console": "off",
"no-empty": "off",
"no-multi-spaces": "warn",
"no-redeclare": "off",
"no-restricted-globals": ["warn", "Promise"],
"no-trailing-spaces": "warn",
"no-undef": "error",
"no-unused-vars": ["warn", {"args": "none"}],
"padded-blocks": ["warn", "never"],
"object-curly-spacing": ["warn", "never"],
"quotes": ["warn", "single"],
"react/prop-types": "off",
"react/jsx-no-bind": "off",
"semi": ["warn", "always"],
"space-before-blocks": ["warn", "always"],
"space-before-function-paren": ["warn", "never"],
"space-in-parens": ["warn", "never"]
}
}
2 changes: 2 additions & 0 deletions .gitignore
@@ -1,2 +1,4 @@
node_modules
npm-debug.log
*.sw* # VIM temp files
.DS_Store # Mac desktop services store
19 changes: 18 additions & 1 deletion build/test.js
Expand Up @@ -4,7 +4,6 @@

var mime = require('../mime');
var assert = require('assert');
var path = require('path');

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

//
// Test types that are known to have conflicting definitions but different facet priorities
//

assert.equal('application/octet-stream', mime.lookup('dmg'));
assert.equal('application/bdoc', mime.lookup('bdoc'));
assert.equal('application/octet-stream', mime.lookup('deb'));
assert.equal('application/octet-stream', mime.lookup('iso'));
assert.equal('application/octet-stream', mime.lookup('exe'));
assert.equal('application/octet-stream', mime.lookup('exe'));
assert.equal('application/octet-stream', mime.lookup('dll'));
assert.equal('application/octet-stream', mime.lookup('msi'));
assert.equal('application/vnd.palm', mime.lookup('pdb'));
assert.equal('audio/mp3', mime.lookup('mp3'));
assert.equal('audio/mp4', mime.lookup('m4a'));
assert.equal('font/opentype', mime.lookup('otf'));
assert.equal('image/bmp', mime.lookup('bmp'));

//
// Test extensions
//
Expand Down
38 changes: 27 additions & 11 deletions mime.js
@@ -1,6 +1,11 @@
var path = require('path');
var fs = require('fs');

// If two types claim the same extension, we resolve the conflict by checking
// facet precedence. https://tools.ietf.org/html/rfc6838#section-3
// Facets listed here are in order of decreasing precedence
var FACETS = ['vnd.', 'x-', 'prs.'];
var FACET_RE = new RegExp('/(' + FACETS.join('|') + ')');

function Mime() {
// Map of extension -> mime type
this.types = Object.create(null);
Expand All @@ -18,16 +23,27 @@ function Mime() {
*
* @param map (Object) type definitions
*/
Mime.prototype.define = function (map) {
Mime.prototype.define = function(map) {
for (var type in map) {
var exts = map[type];

for (var i = 0; i < exts.length; i++) {
if (process.env.DEBUG_MIME && this.types[exts[i]]) {
console.warn((this._loading || "define()").replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' +
this.types[exts[i]] + ' to ' + type);
var ext = exts[i];
var found = this.types[ext];

// If there's already a type for this extension ...
if (found) {
var pri0 = FACETS.indexOf(FACET_RE.test(found) && RegExp.$1);
var pri1 = FACETS.indexOf(FACET_RE.test(type) && RegExp.$1);

if (process.env.DEBUG_MIME) console.warn('Type conflict for .' + ext +
' (' + found + ' pri=' + pri0 + ', ' + type + ' pri=' + pri1 + ')');

// Prioritize based on facet precedence
if (pri0 <= pri1) continue;
}

this.types[exts[i]] = type;
this.types[ext] = type;
}

// Default extension is the first one we encounter
Expand All @@ -48,9 +64,9 @@ Mime.prototype.define = function (map) {
Mime.prototype.load = function(file) {
this._loading = file;
// Read file and split into lines
var map = {},
content = fs.readFileSync(file, 'ascii'),
lines = content.split(/[\r\n]+/);
var map = {};
var content = fs.readFileSync(file, 'ascii');
var lines = content.split(/[\r\n]+/);

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

return this.types[ext] || fallback || this.default_type;
return this.types[ext] || fallback || this.default_type; // eslint-disable-line camelcase
};

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

// Default type
mime.default_type = mime.lookup('bin');
mime.default_type = mime.lookup('bin'); // eslint-disable-line camelcase

//
// Additional API specific to the default instance
Expand Down
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -21,7 +21,7 @@
"mime-db": "^1.22.0"
},
"scripts": {
"prepublish": "node build/build.js > types.json",
"prepare": "node build/build.js > types.json",
"test": "node build/test.js"
},
"keywords": [
Expand All @@ -34,5 +34,5 @@
"url": "https://github.com/broofa/node-mime",
"type": "git"
},
"version": "1.3.4"
"version": "1.3.5"
}
2 changes: 1 addition & 1 deletion types.json

Large diffs are not rendered by default.

0 comments on commit f7ccb94

Please sign in to comment.