buddy

node MVC discord bot
Log | Files | Refs | README

index.js (3663B)


      1 /*!
      2  * mime-types
      3  * Copyright(c) 2014 Jonathan Ong
      4  * Copyright(c) 2015 Douglas Christopher Wilson
      5  * MIT Licensed
      6  */
      7 
      8 'use strict'
      9 
     10 /**
     11  * Module dependencies.
     12  * @private
     13  */
     14 
     15 var db = require('mime-db')
     16 var extname = require('path').extname
     17 
     18 /**
     19  * Module variables.
     20  * @private
     21  */
     22 
     23 var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/
     24 var TEXT_TYPE_REGEXP = /^text\//i
     25 
     26 /**
     27  * Module exports.
     28  * @public
     29  */
     30 
     31 exports.charset = charset
     32 exports.charsets = { lookup: charset }
     33 exports.contentType = contentType
     34 exports.extension = extension
     35 exports.extensions = Object.create(null)
     36 exports.lookup = lookup
     37 exports.types = Object.create(null)
     38 
     39 // Populate the extensions/types maps
     40 populateMaps(exports.extensions, exports.types)
     41 
     42 /**
     43  * Get the default charset for a MIME type.
     44  *
     45  * @param {string} type
     46  * @return {boolean|string}
     47  */
     48 
     49 function charset (type) {
     50   if (!type || typeof type !== 'string') {
     51     return false
     52   }
     53 
     54   // TODO: use media-typer
     55   var match = EXTRACT_TYPE_REGEXP.exec(type)
     56   var mime = match && db[match[1].toLowerCase()]
     57 
     58   if (mime && mime.charset) {
     59     return mime.charset
     60   }
     61 
     62   // default text/* to utf-8
     63   if (match && TEXT_TYPE_REGEXP.test(match[1])) {
     64     return 'UTF-8'
     65   }
     66 
     67   return false
     68 }
     69 
     70 /**
     71  * Create a full Content-Type header given a MIME type or extension.
     72  *
     73  * @param {string} str
     74  * @return {boolean|string}
     75  */
     76 
     77 function contentType (str) {
     78   // TODO: should this even be in this module?
     79   if (!str || typeof str !== 'string') {
     80     return false
     81   }
     82 
     83   var mime = str.indexOf('/') === -1
     84     ? exports.lookup(str)
     85     : str
     86 
     87   if (!mime) {
     88     return false
     89   }
     90 
     91   // TODO: use content-type or other module
     92   if (mime.indexOf('charset') === -1) {
     93     var charset = exports.charset(mime)
     94     if (charset) mime += '; charset=' + charset.toLowerCase()
     95   }
     96 
     97   return mime
     98 }
     99 
    100 /**
    101  * Get the default extension for a MIME type.
    102  *
    103  * @param {string} type
    104  * @return {boolean|string}
    105  */
    106 
    107 function extension (type) {
    108   if (!type || typeof type !== 'string') {
    109     return false
    110   }
    111 
    112   // TODO: use media-typer
    113   var match = EXTRACT_TYPE_REGEXP.exec(type)
    114 
    115   // get extensions
    116   var exts = match && exports.extensions[match[1].toLowerCase()]
    117 
    118   if (!exts || !exts.length) {
    119     return false
    120   }
    121 
    122   return exts[0]
    123 }
    124 
    125 /**
    126  * Lookup the MIME type for a file path/extension.
    127  *
    128  * @param {string} path
    129  * @return {boolean|string}
    130  */
    131 
    132 function lookup (path) {
    133   if (!path || typeof path !== 'string') {
    134     return false
    135   }
    136 
    137   // get the extension ("ext" or ".ext" or full path)
    138   var extension = extname('x.' + path)
    139     .toLowerCase()
    140     .substr(1)
    141 
    142   if (!extension) {
    143     return false
    144   }
    145 
    146   return exports.types[extension] || false
    147 }
    148 
    149 /**
    150  * Populate the extensions and types maps.
    151  * @private
    152  */
    153 
    154 function populateMaps (extensions, types) {
    155   // source preference (least -> most)
    156   var preference = ['nginx', 'apache', undefined, 'iana']
    157 
    158   Object.keys(db).forEach(function forEachMimeType (type) {
    159     var mime = db[type]
    160     var exts = mime.extensions
    161 
    162     if (!exts || !exts.length) {
    163       return
    164     }
    165 
    166     // mime -> extensions
    167     extensions[type] = exts
    168 
    169     // extension -> mime
    170     for (var i = 0; i < exts.length; i++) {
    171       var extension = exts[i]
    172 
    173       if (types[extension]) {
    174         var from = preference.indexOf(db[types[extension]].source)
    175         var to = preference.indexOf(mime.source)
    176 
    177         if (types[extension] !== 'application/octet-stream' &&
    178           (from > to || (from === to && types[extension].substr(0, 12) === 'application/'))) {
    179           // skip the remapping
    180           continue
    181         }
    182       }
    183 
    184       // set the extension -> mime
    185       types[extension] = type
    186     }
    187   })
    188 }