109 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			109 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								var path = require('path');
							 | 
						||
| 
								 | 
							
								var fs = require('fs');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function Mime() {
							 | 
						||
| 
								 | 
							
								  // Map of extension -> mime type
							 | 
						||
| 
								 | 
							
								  this.types = Object.create(null);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Map of mime type -> extension
							 | 
						||
| 
								 | 
							
								  this.extensions = Object.create(null);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Define mimetype -> extension mappings.  Each key is a mime-type that maps
							 | 
						||
| 
								 | 
							
								 * to an array of extensions associated with the type.  The first extension is
							 | 
						||
| 
								 | 
							
								 * used as the default extension for the type.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param map (Object) type definitions
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								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);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      this.types[exts[i]] = type;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Default extension is the first one we encounter
							 | 
						||
| 
								 | 
							
								    if (!this.extensions[type]) {
							 | 
						||
| 
								 | 
							
								      this.extensions[type] = exts[0];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Load an Apache2-style ".types" file
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This may be called multiple times (it's expected).  Where files declare
							 | 
						||
| 
								 | 
							
								 * overlapping types/extensions, the last file wins.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param file (String) path of file to load.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								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]+/);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  lines.forEach(function(line) {
							 | 
						||
| 
								 | 
							
								    // Clean up whitespace/comments, and split into fields
							 | 
						||
| 
								 | 
							
								    var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/);
							 | 
						||
| 
								 | 
							
								    map[fields.shift()] = fields;
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.define(map);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this._loading = null;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Lookup a mime type based on extension
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mime.prototype.lookup = function(path, fallback) {
							 | 
						||
| 
								 | 
							
								  var ext = path.replace(/^.*[\.\/\\]/, '').toLowerCase();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return this.types[ext] || fallback || this.default_type;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Return file extension associated with a mime type
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mime.prototype.extension = function(mimeType) {
							 | 
						||
| 
								 | 
							
								  var type = mimeType.match(/^\s*([^;\s]*)(?:;|\s|$)/)[1].toLowerCase();
							 | 
						||
| 
								 | 
							
								  return this.extensions[type];
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Default instance
							 | 
						||
| 
								 | 
							
								var mime = new Mime();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Define built-in types
							 | 
						||
| 
								 | 
							
								mime.define(require('./types.json'));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Default type
							 | 
						||
| 
								 | 
							
								mime.default_type = mime.lookup('bin');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Additional API specific to the default instance
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mime.Mime = Mime;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Lookup a charset based on mime type.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								mime.charsets = {
							 | 
						||
| 
								 | 
							
								  lookup: function(mimeType, fallback) {
							 | 
						||
| 
								 | 
							
								    // Assume text types are utf8
							 | 
						||
| 
								 | 
							
								    return (/^text\/|^application\/(javascript|json)/).test(mimeType) ? 'UTF-8' : fallback;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = mime;
							 |