Blame view

node_modules/mime/mime.js 2.61 KB
f7563de62   Palak Handa   first commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  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]) {
          console.warn(this._loading.replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' +
            this.types[exts] + ' 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
  ]+/);
  
    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\//).test(mimeType) ? 'UTF-8' : fallback;
    }
  };
  
  module.exports = mime;