second
[josuexyz/.git] / node_modules / mime-types / index.js
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 }