Mime.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. 'use strict';
  2. /**
  3. * @param typeMap [Object] Map of MIME type -> Array[extensions]
  4. * @param ...
  5. */
  6. function Mime() {
  7. this._types = Object.create(null);
  8. this._extensions = Object.create(null);
  9. for (var i = 0; i < arguments.length; i++) {
  10. this.define(arguments[i]);
  11. }
  12. }
  13. /**
  14. * Define mimetype -> xtension mappings. Each key is a mime-type that maps
  15. * to an array of extensions associated with the type. The first extension is
  16. * used as the default extension for the type.
  17. *
  18. * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
  19. *
  20. * If a type declares an extension that has already been defined, an error will
  21. * be thrown. To suppress this error and force the extension to be associated
  22. * with the new type, pass `force`=true. Alternatively, you may prefix the
  23. * extension with "*" to map the type to extension, without mapping the
  24. * extension to the type.
  25. *
  26. * e.g. mime.define({'audio/wav', ['wav']}, {'audio/x-wav', ['*wav']});
  27. *
  28. *
  29. * @param map (Object) type definitions
  30. * @param force (Boolean) if true, force overriding of existing definitions
  31. */
  32. Mime.prototype.define = function(typeMap, force) {
  33. for (var type in typeMap) {
  34. var extensions = typeMap[type];
  35. for (var i = 0; i < extensions.length; i++) {
  36. var ext = extensions[i];
  37. // '*' prefix = not the preferred type for this extension. So fixup the
  38. // extension, and skip it.
  39. if (ext[0] == '*') {
  40. continue;
  41. }
  42. if (!force && (ext in this._types)) {
  43. throw new Error(
  44. 'Attempt to change mapping for "' + ext +
  45. '" extension from "' + this._types[ext] + '" to "' + type +
  46. '". Pass `force=true` to allow this, otherwise remove "' + ext +
  47. '" from the list of extensions for "' + type + '".'
  48. );
  49. }
  50. this._types[ext] = type;
  51. }
  52. // Use first extension as default
  53. if (force || !this._extensions[type]) {
  54. var ext = extensions[0];
  55. this._extensions[type] = (ext[0] != '*') ? ext : ext.substr(1)
  56. }
  57. }
  58. };
  59. /**
  60. * Lookup a mime type based on extension
  61. */
  62. Mime.prototype.getType = function(path) {
  63. path = String(path);
  64. var last = path.replace(/^.*[/\\]/, '').toLowerCase();
  65. var ext = last.replace(/^.*\./, '').toLowerCase();
  66. var hasPath = last.length < path.length;
  67. var hasDot = ext.length < last.length - 1;
  68. return (hasDot || !hasPath) && this._types[ext] || null;
  69. };
  70. /**
  71. * Return file extension associated with a mime type
  72. */
  73. Mime.prototype.getExtension = function(type) {
  74. type = /^\s*([^;\s]*)/.test(type) && RegExp.$1;
  75. return type && this._extensions[type.toLowerCase()] || null;
  76. };
  77. module.exports = Mime;