code:
'use strict';

const util = require('util');
const braces = require('braces');
const picomatch = require('picomatch');
const utils = require('picomatch/lib/utils');

const isEmptyString = v => v === '' || v === './';
const hasBraces = v => {
  const index = v.indexOf('{');
  return index > -1 && v.indexOf('}', index) > -1;
};

/**
 * Returns an array of strings that match one or more glob patterns.
 *
 * ```js
 * const mm = require('micromatch');
 * // mm(list, patterns[, options]);
 *
 * console.log(mm(['a.js', 'a.txt'], ['*.js']));
 * //=> [ 'a.js' ]
 * ```
 * @param {String|Array<string>} `list` List of strings to match.
 * @param {String|Array<string>} `patterns` One or more glob patterns to use for matching.
 * @param {Object} `options` See available [options](#options)
 * @return {Array} Returns an array of matches
 * @summary false
 * @api public
 */

const micromatch = (list, patterns, options) => {
  patterns = [].concat(patterns);
  list = [].concat(list);

  let omit = new Set();
  let keep = new Set();
  let items = new Set();
  let negatives = 0;

  let onResult = state => {
    items.add(state.output);
    if (options && options.onResult) {
      options.onResult(state);
    }
  };

  for (let i = 0; i < patterns.length; i++) {
    let isMatch = picomatch(String(patterns[i]), { ...options, onResult }, true);
    let negated = isMatch.state.negated || isMatch.state.negatedExtglob;
    if (negated) negatives++;

    for (let item of list) {
      let matched = isMatch(item, true);

      let match = negated ? !matched.isMatch : matched.isMatch;
      if (!match) continue;

      if (negated) {
        omit.add(matched.output);
      } else {
        omit.delete(matched.output);
        keep.add(matched.output);
      }
    }
  }

  let result = negatives === patterns.length ? [...items] : [...keep];
  let matches = result.filter(item => !omit.has(item));

  if (options && matches.length === 0) {
    if (options.failglob === true) {
      throw new Error(`No matches found for "${patterns.join(', ')}"`);
    }

    if (options.nonull === true || options.nullglob === true) {
      return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns;
    }
  }

  return matches;
};

/**
 * Backwards compatibility
 */

micromatch.match = micromatch;

/**
 * Returns a matcher function from the given glob `pattern` and `options`.
 * The returned function takes a string to match as its only argument and returns
 * true if the string is a match.
 *
 * ```js
 * const mm = require('micromatch');
 * // mm.matcher(pattern[, options]);
 *
 * const isMatch = mm.matcher('*.!(*a)');
 * console.log(isMatch('a.a')); //=> false
 * console.log(isMatch('a.b')); //=> true
 * ```
 * @param {String} `pattern` Glob pattern
 * @param {Object} `options`
 * @return {Function} Returns a matcher function.
 * @api public
 */

micromatch.matcher = (pattern, options) => picomatch(pattern, options);

/**
 * Returns true if **any** of the given glob `patterns` match the specified `string`.
 *
 * ```js
 * const mm = require('micromatch');
 * // mm.isMatch(string, patterns[, options]);
 *
 * console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true
 * console.log(mm.isMatch('a.a', 'b.*')); //=> false
 * ```
 * @param {String} `str` The string to test.
 * @param {String|Array} `patterns` One or more glob patterns to use for matching.
 * @param {Object} `[options]` See available [options](#options).
 * @return {Boolean} Returns true if any patterns match `str`
 * @api public
 */

micromatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);

/**
 * Backwards compatibility
 */

micromatch.any = micromatch.isMatch;

/**
 * Returns a list of strings that _**do not match any**_ of the given `patterns`.
 *
 * ```js
 * const mm = require('micromatch');
 * // mm.not(list, patterns[, options]);
 *
 * console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a'));
 * //=> ['b.b', 'c.c']
 * ```
 * @param {Array} `list` Array of strings to match.
 * @param {String|Array} `patterns` One or more glob pattern to use for matching.
 * @param {Object} `options` See available [options](#options) for changing how matches are performed
 * @return {Array} Returns an array of strings that **do not match** the given patterns.
 * @api public
 */

micromatch.not = (list, patterns, options = {}) => {
  patterns = [].concat(patterns).map(String);
  let result = new Set();
  let items = [];

  let onResult = state => {
    if (options.onResult) options.onResult(state);
    items.push(state.output);
  };

  let matches = new Set(micromatch(list, patterns, { ...options, onResult }));

  for (let item of items) {
    if (!matches.has(item)) {
      result.add(item);
    }
  }
  return [...result];
};

/**
 * Returns true if the given `string` contains the given pattern. Similar
 * to [.isMatch](#isMatch) but the pattern can match any part of the string.
 *
 * ```js
 * var mm = require('micromatch');
 * // mm.contains(string, pattern[, options]);
 *
 * console.log(mm.contains('aa/bb/cc', '*b'));
 * //=> true
 * console.log(mm.contains('aa/bb/cc', '*d'));
 * //=> false
 * ```
 * @param {String} `str` The string to match.
 * @param {String|Array} `patterns` Glob pattern to use for matching.
 * @param {Object} `options` See available [options](#options) for changing how matches are performed
 * @return {Boolean} Returns true if any of the patterns matches any part of `str`.
 * @api public
 */

micromatch.contains = (str, pattern, options) => {
  if (typeof str !== 'string') {
    throw new TypeError(`Expected a string: "${util.inspect(str)}"`);
  }

  if (Array.isArray(pattern)) {
    return pattern.some(p => micromatch.contains(str, p, options));
  }

  if (typeof pattern === 'string') {
    if (isEmptyString(str) || isEmptyString(pattern)) {
      return false;
    }

    if (str.includes(pattern) || (str.startsWith('./') && str.slice(2).includes(pattern))) {
      return true;
    }
  }

  return micromatch.isMatch(str, pattern, { ...options, contains: true });
};

/**
 * Filter the keys of the given object with the given `glob` pattern
 * and `options`. Does not attempt to match nested keys. If you need this feature,
 * use [glob-object][] instead.
 *
 * ```js
 * const mm = require('micromatch');
 * // mm.matchKeys(object, patterns[, options]);
 *
 * const obj = { aa: 'a', ab: 'b', ac: 'c' };
 * console.log(mm.matchKeys(obj, '*b'));
 * //=> { ab: 'b' }
 * ```
 * @param {Object} `object` The object with keys to filter.
 * @param {String|Array} `patterns` One or more glob patterns to use for matching.
 * @param {Object} `options` See available [options](#options) for changing how matches are performed
 * @return {Object} Returns an object with only keys that match the given patterns.
 * @api public
 */

micromatch.matchKeys = (obj, patterns, options) => {
  if (!utils.isObject(obj)) {
    throw new TypeError('Expected the first argument to be an object');
  }
  let keys = micromatch(Object.keys(obj), patterns, options);
  let res = {};
  for (let key of keys) res[key] = obj[key];
  return res;
};

/**
 * Returns true if some of the strings in the given `list` match any of the given glob `patterns`.
 *
 * ```js
 * const mm = require('micromatch');
 * // mm.some(list, patterns[, options]);
 *
 * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js']));
 * // true
 * console.log(mm.some(['foo.js'], ['*.js', '!foo.js']));
 * // false
 * ```
 * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found.
 * @param {String|Array} `patterns` One or more glob patterns to use for matching.
 * @param {Object} `options` See available [options](#options) for changing how matches are performed
 * @return {Boolean} Returns true if any `patterns` matches any of the strings in `list`
 * @api public
 */

micromatch.some = (list, patterns, options) => {
  let items = [].concat(list);

  for (let pattern of [].concat(patterns)) {
    let isMatch = picomatch(String(pattern), options);
    if (items.some(item => isMatch(item))) {
      return true;
    }
  }
  return false;
};

/**
 * Returns true if every string in the given `list` matches
 * any of the given glob `patterns`.
 *
 * ```js
 * const mm = require('micromatch');
 * // mm.every(list, patterns[, options]);
 *
 * console.log(mm.every('foo.js', ['foo.js']));
 * // true
 * console.log(mm.every(['foo.js', 'bar.js'], ['*.js']));
 * // true
 * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js']));
 * // false
 * console.log(mm.every(['foo.js'], ['*.js', '!foo.js']));
 * // false
 * ```
 * @param {String|Array} `list` The string or array of strings to test.
 * @param {String|Array} `patterns` One or more glob patterns to use for matching.
 * @param {Object} `options` See available [options](#options) for changing how matches are performed
 * @return {Boolean} Returns true if all `patterns` matches all of the strings in `list`
 * @api public
 */

micromatch.every = (list, patterns, options) => {
  let items = [].concat(list);

  for (let pattern of [].concat(patterns)) {
    let isMatch = picomatch(String(pattern), options);
    if (!items.every(item => isMatch(item))) {
      return false;
    }
  }
  return true;
};

/**
 * Returns true if **all** of the given `patterns` match
 * the specified string.
 *
 * ```js
 * const mm = require('micromatch');
 * // mm.all(string, patterns[, options]);
 *
 * console.log(mm.all('foo.js', ['foo.js']));
 * // true
 *
 * console.log(mm.all('foo.js', ['*.js', '!foo.js']));
 * // false
 *
 * console.log(mm.all('foo.js', ['*.js', 'foo.js']));
 * // true
 *
 * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js']));
 * // true
 * ```
 * @param {String|Array} `str` The string to test.
 * @param {String|Array} `patterns` One or more glob patterns to use for matching.
 * @param {Object} `options` See available [options](#options) for changing how matches are performed
 * @return {Boolean} Returns true if any patterns match `str`
 * @api public
 */

micromatch.all = (str, patterns, options) => {
  if (typeof str !== 'string') {
    throw new TypeError(`Expected a string: "${util.inspect(str)}"`);
  }

  return [].concat(patterns).every(p => picomatch(p, options)(str));
};

/**
 * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match.
 *
 * ```js
 * const mm = require('micromatch');
 * // mm.capture(pattern, string[, options]);
 *
 * console.log(mm.capture('test/*.js', 'test/foo.js'));
 * //=> ['foo']
 * console.log(mm.capture('test/*.js', 'foo/bar.css'));
 * //=> null
 * ```
 * @param {String} `glob` Glob pattern to use for matching.
 * @param {String} `input` String to match
 * @param {Object} `options` See available [options](#options) for changing how matches are performed
 * @return {Array|null} Returns an array of captures if the input matches the glob pattern, otherwise `null`.
 * @api public
 */

micromatch.capture = (glob, input, options) => {
  let posix = utils.isWindows(options);
  let regex = picomatch.makeRe(String(glob), { ...options, capture: true });
  let match = regex.exec(posix ? utils.toPosixSlashes(input) : input);

  if (match) {
    return match.slice(1).map(v => v === void 0 ? '' : v);
  }
};

/**
 * Create a regular expression from the given glob `pattern`.
 *
 * ```js
 * const mm = require('micromatch');
 * // mm.makeRe(pattern[, options]);
 *
 * console.log(mm.makeRe('*.js'));
 * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/
 * ```
 * @param {String} `pattern` A glob pattern to convert to regex.
 * @param {Object} `options`
 * @return {RegExp} Returns a regex created from the given pattern.
 * @api public
 */

micromatch.makeRe = (...args) => picomatch.makeRe(...args);

/**
 * Scan a glob pattern to separate the pattern into segments. Used
 * by the [split](#split) method.
 *
 * ```js
 * const mm = require('micromatch');
 * const state = mm.scan(pattern[, options]);
 * ```
 * @param {String} `pattern`
 * @param {Object} `options`
 * @return {Object} Returns an object with
 * @api public
 */

micromatch.scan = (...args) => picomatch.scan(...args);

/**
 * Parse a glob pattern to create the source string for a regular
 * expression.
 *
 * ```js
 * const mm = require('micromatch');
 * const state = mm.parse(pattern[, options]);
 * ```
 * @param {String} `glob`
 * @param {Object} `options`
 * @return {Object} Returns an object with useful properties and output to be used as regex source string.
 * @api public
 */

micromatch.parse = (patterns, options) => {
  let res = [];
  for (let pattern of [].concat(patterns || [])) {
    for (let str of braces(String(pattern), options)) {
      res.push(picomatch.parse(str, options));
    }
  }
  return res;
};

/**
 * Process the given brace `pattern`.
 *
 * ```js
 * const { braces } = require('micromatch');
 * console.log(braces('foo/{a,b,c}/bar'));
 * //=> [ 'foo/(a|b|c)/bar' ]
 *
 * console.log(braces('foo/{a,b,c}/bar', { expand: true }));
 * //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ]
 * ```
 * @param {String} `pattern` String with brace pattern to process.
 * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options.
 * @return {Array}
 * @api public
 */

micromatch.braces = (pattern, options) => {
  if (typeof pattern !== 'string') throw new TypeError('Expected a string');
  if ((options && options.nobrace === true) || !hasBraces(pattern)) {
    return [pattern];
  }
  return braces(pattern, options);
};

/**
 * Expand braces
 */

micromatch.braceExpand = (pattern, options) => {
  if (typeof pattern !== 'string') throw new TypeError('Expected a string');
  return micromatch.braces(pattern, { ...options, expand: true });
};

/**
 * Expose micromatch
 */

// exposed for tests
micromatch.hasBraces = hasBraces;
module.exports = micromatch;


micromatch

description: Glob matching for javascript/node.js. A replacement and faster alternative to minimatch and multimatch.

contributors: Peter Bright <drpizza@quiscalusmexicanus.org> (https://github.com/drpizza)

repository: micromatch/micromatch

license: MIT

test: mocha

keywords: bash bracket character-class expand expansion expression extglob extglobs file files filter find glob globbing globs globstar lookahead lookaround lookbehind match matcher matches matching micromatch minimatch multimatch negate negation path pattern patterns posix regex regexp regular shell star wildcard

toc: collapsible

layout: default

list: braces expand-brackets extglob fill-range nanomatch

reflinks: extglob fill-range glob-object minimatch multimatch

license: mit


code:
1.52.0 / 2022-02-21
===================

  * Add extensions from IANA for more `image/*` types
  * Add extension `.asc` to `application/pgp-keys`
  * Add extensions to various XML types
  * Add new upstream MIME types

1.51.0 / 2021-11-08
===================

  * Add new upstream MIME types
  * Mark `image/vnd.microsoft.icon` as compressible
  * Mark `image/vnd.ms-dds` as compressible

1.50.0 / 2021-09-15
===================

  * Add deprecated iWorks mime types and extensions
  * Add new upstream MIME types

1.49.0 / 2021-07-26
===================

  * Add extension `.trig` to `application/trig`
  * Add new upstream MIME types

1.48.0 / 2021-05-30
===================

  * Add extension `.mvt` to `application/vnd.mapbox-vector-tile`
  * Add new upstream MIME types
  * Mark `text/yaml` as compressible

1.47.0 / 2021-04-01
===================

  * Add new upstream MIME types
  * Remove ambigious extensions from IANA for `application/*+xml` types
  * Update primary extension to `.es` for `application/ecmascript`

1.46.0 / 2021-02-13
===================

  * Add extension `.amr` to `audio/amr`
  * Add extension `.m4s` to `video/iso.segment`
  * Add extension `.opus` to `audio/ogg`
  * Add new upstream MIME types

1.45.0 / 2020-09-22
===================

  * Add `application/ubjson` with extension `.ubj`
  * Add `image/avif` with extension `.avif`
  * Add `image/ktx2` with extension `.ktx2`
  * Add extension `.dbf` to `application/vnd.dbf`
  * Add extension `.rar` to `application/vnd.rar`
  * Add extension `.td` to `application/urc-targetdesc+xml`
  * Add new upstream MIME types
  * Fix extension of `application/vnd.apple.keynote` to be `.key`

1.44.0 / 2020-04-22
===================

  * Add charsets from IANA
  * Add extension `.cjs` to `application/node`
  * Add new upstream MIME types

1.43.0 / 2020-01-05
===================

  * Add `application/x-keepass2` with extension `.kdbx`
  * Add extension `.mxmf` to `audio/mobile-xmf`
  * Add extensions from IANA for `application/*+xml` types
  * Add new upstream MIME types

1.42.0 / 2019-09-25
===================

  * Add `image/vnd.ms-dds` with extension `.dds`
  * Add new upstream MIME types
  * Remove compressible from `multipart/mixed`

1.41.0 / 2019-08-30
===================

  * Add new upstream MIME types
  * Add `application/toml` with extension `.toml`
  * Mark `font/ttf` as compressible

1.40.0 / 2019-04-20
===================

  * Add extensions from IANA for `model/*` types
  * Add `text/mdx` with extension `.mdx`

1.39.0 / 2019-04-04
===================

  * Add extensions `.siv` and `.sieve` to `application/sieve`
  * Add new upstream MIME types

1.38.0 / 2019-02-04
===================

  * Add extension `.nq` to `application/n-quads`
  * Add extension `.nt` to `application/n-triples`
  * Add new upstream MIME types
  * Mark `text/less` as compressible

1.37.0 / 2018-10-19
===================

  * Add extensions to HEIC image types
  * Add new upstream MIME types

1.36.0 / 2018-08-20
===================

  * Add Apple file extensions from IANA
  * Add extensions from IANA for `image/*` types
  * Add new upstream MIME types

1.35.0 / 2018-07-15
===================

  * Add extension `.owl` to `application/rdf+xml`
  * Add new upstream MIME types
    - Removes extension `.woff` from `application/font-woff`

1.34.0 / 2018-06-03
===================

  * Add extension `.csl` to `application/vnd.citationstyles.style+xml`
  * Add extension `.es` to `application/ecmascript`
  * Add new upstream MIME types
  * Add `UTF-8` as default charset for `text/turtle`
  * Mark all XML-derived types as compressible

1.33.0 / 2018-02-15
===================

  * Add extensions from IANA for `message/*` types
  * Add new upstream MIME types
  * Fix some incorrect OOXML types
  * Remove `application/font-woff2`

1.32.0 / 2017-11-29
===================

  * Add new upstream MIME types
  * Update `text/hjson` to registered `application/hjson`
  * Add `text/shex` with extension `.shex`

1.31.0 / 2017-10-25
===================

  * Add `application/raml+yaml` with extension `.raml`
  * Add `application/wasm` with extension `.wasm`
  * Add new `font` type from IANA
  * Add new upstream font extensions
  * Add new upstream MIME types
  * Add extensions for JPEG-2000 images

1.30.0 / 2017-08-27
===================

  * Add `application/vnd.ms-outlook`
  * Add `application/x-arj`
  * Add extension `.mjs` to `application/javascript`
  * Add glTF types and extensions
  * Add new upstream MIME types
  * Add `text/x-org`
  * Add VirtualBox MIME types
  * Fix `source` records for `video/*` types that are IANA
  * Update `font/opentype` to registered `font/otf`

1.29.0 / 2017-07-10
===================

  * Add `application/fido.trusted-apps+json`
  * Add extension `.wadl` to `application/vnd.sun.wadl+xml`
  * Add new upstream MIME types
  * Add `UTF-8` as default charset for `text/css`

1.28.0 / 2017-05-14
===================

  * Add new upstream MIME types
  * Add extension `.gz` to `application/gzip`
  * Update extensions `.md` and `.markdown` to be `text/markdown`

1.27.0 / 2017-03-16
===================

  * Add new upstream MIME types
  * Add `image/apng` with extension `.apng`

1.26.0 / 2017-01-14
===================

  * Add new upstream MIME types
  * Add extension `.geojson` to `application/geo+json`

1.25.0 / 2016-11-11
===================

  * Add new upstream MIME types

1.24.0 / 2016-09-18
===================

  * Add `audio/mp3`
  * Add new upstream MIME types

1.23.0 / 2016-05-01
===================

  * Add new upstream MIME types
  * Add extension `.3gpp` to `audio/3gpp`

1.22.0 / 2016-02-15
===================

  * Add `text/slim`
  * Add extension `.rng` to `application/xml`
  * Add new upstream MIME types
  * Fix extension of `application/dash+xml` to be `.mpd`
  * Update primary extension to `.m4a` for `audio/mp4`

1.21.0 / 2016-01-06
===================

  * Add Google document types
  * Add new upstream MIME types

1.20.0 / 2015-11-10
===================

  * Add `text/x-suse-ymp`
  * Add new upstream MIME types

1.19.0 / 2015-09-17
===================

  * Add `application/vnd.apple.pkpass`
  * Add new upstream MIME types

1.18.0 / 2015-09-03
===================

  * Add new upstream MIME types

1.17.0 / 2015-08-13
===================

  * Add `application/x-msdos-program`
  * Add `audio/g711-0`
  * Add `image/vnd.mozilla.apng`
  * Add extension `.exe` to `application/x-msdos-program`

1.16.0 / 2015-07-29
===================

  * Add `application/vnd.uri-map`

1.15.0 / 2015-07-13
===================

  * Add `application/x-httpd-php`

1.14.0 / 2015-06-25
===================

  * Add `application/scim+json`
  * Add `application/vnd.3gpp.ussd+xml`
  * Add `application/vnd.biopax.rdf+xml`
  * Add `text/x-processing`

1.13.0 / 2015-06-07
===================

  * Add nginx as a source
  * Add `application/x-cocoa`
  * Add `application/x-java-archive-diff`
  * Add `application/x-makeself`
  * Add `application/x-perl`
  * Add `application/x-pilot`
  * Add `application/x-redhat-package-manager`
  * Add `application/x-sea`
  * Add `audio/x-m4a`
  * Add `audio/x-realaudio`
  * Add `image/x-jng`
  * Add `text/mathml`

1.12.0 / 2015-06-05
===================

  * Add `application/bdoc`
  * Add `application/vnd.hyperdrive+json`
  * Add `application/x-bdoc`
  * Add extension `.rtf` to `text/rtf`

1.11.0 / 2015-05-31
===================

  * Add `audio/wav`
  * Add `audio/wave`
  * Add extension `.litcoffee` to `text/coffeescript`
  * Add extension `.sfd-hdstx` to `application/vnd.hydrostatix.sof-data`
  * Add extension `.n-gage` to `application/vnd.nokia.n-gage.symbian.install`

1.10.0 / 2015-05-19
===================

  * Add `application/vnd.balsamiq.bmpr`
  * Add `application/vnd.microsoft.portable-executable`
  * Add `application/x-ns-proxy-autoconfig`

1.9.1 / 2015-04-19
==================

  * Remove `.json` extension from `application/manifest+json`
    - This is causing bugs downstream

1.9.0 / 2015-04-19
==================

  * Add `application/manifest+json`
  * Add `application/vnd.micro+json`
  * Add `image/vnd.zbrush.pcx`
  * Add `image/x-ms-bmp`

1.8.0 / 2015-03-13
==================

  * Add `application/vnd.citationstyles.style+xml`
  * Add `application/vnd.fastcopy-disk-image`
  * Add `application/vnd.gov.sk.xmldatacontainer+xml`
  * Add extension `.jsonld` to `application/ld+json`

1.7.0 / 2015-02-08
==================

  * Add `application/vnd.gerber`
  * Add `application/vnd.msa-disk-image`

1.6.1 / 2015-02-05
==================

  * Community extensions ownership transferred from `node-mime`

1.6.0 / 2015-01-29
==================

  * Add `application/jose`
  * Add `application/jose+json`
  * Add `application/json-seq`
  * Add `application/jwk+json`
  * Add `application/jwk-set+json`
  * Add `application/jwt`
  * Add `application/rdap+json`
  * Add `application/vnd.gov.sk.e-form+xml`
  * Add `application/vnd.ims.imsccv1p3`

1.5.0 / 2014-12-30
==================

  * Add `application/vnd.oracle.resource+json`
  * Fix various invalid MIME type entries
    - `application/mbox+xml`
    - `application/oscp-response`
    - `application/vwg-multiplexed`
    - `audio/g721`

1.4.0 / 2014-12-21
==================

  * Add `application/vnd.ims.imsccv1p2`
  * Fix various invalid MIME type entries
    - `application/vnd-acucobol`
    - `application/vnd-curl`
    - `application/vnd-dart`
    - `application/vnd-dxr`
    - `application/vnd-fdf`
    - `application/vnd-mif`
    - `application/vnd-sema`
    - `application/vnd-wap-wmlc`
    - `application/vnd.adobe.flash-movie`
    - `application/vnd.dece-zip`
    - `application/vnd.dvb_service`
    - `application/vnd.micrografx-igx`
    - `application/vnd.sealed-doc`
    - `application/vnd.sealed-eml`
    - `application/vnd.sealed-mht`
    - `application/vnd.sealed-ppt`
    - `application/vnd.sealed-tiff`
    - `application/vnd.sealed-xls`
    - `application/vnd.sealedmedia.softseal-html`
    - `application/vnd.sealedmedia.softseal-pdf`
    - `application/vnd.wap-slc`
    - `application/vnd.wap-wbxml`
    - `audio/vnd.sealedmedia.softseal-mpeg`
    - `image/vnd-djvu`
    - `image/vnd-svf`
    - `image/vnd-wap-wbmp`
    - `image/vnd.sealed-png`
    - `image/vnd.sealedmedia.softseal-gif`
    - `image/vnd.sealedmedia.softseal-jpg`
    - `model/vnd-dwf`
    - `model/vnd.parasolid.transmit-binary`
    - `model/vnd.parasolid.transmit-text`
    - `text/vnd-a`
    - `text/vnd-curl`
    - `text/vnd.wap-wml`
  * Remove example template MIME types
    - `application/example`
    - `audio/example`
    - `image/example`
    - `message/example`
    - `model/example`
    - `multipart/example`
    - `text/example`
    - `video/example`

1.3.1 / 2014-12-16
==================

  * Fix missing extensions
    - `application/json5`
    - `text/hjson`

1.3.0 / 2014-12-07
==================

  * Add `application/a2l`
  * Add `application/aml`
  * Add `application/atfx`
  * Add `application/atxml`
  * Add `application/cdfx+xml`
  * Add `application/dii`
  * Add `application/json5`
  * Add `application/lxf`
  * Add `application/mf4`
  * Add `application/vnd.apache.thrift.compact`
  * Add `application/vnd.apache.thrift.json`
  * Add `application/vnd.coffeescript`
  * Add `application/vnd.enphase.envoy`
  * Add `application/vnd.ims.imsccv1p1`
  * Add `text/csv-schema`
  * Add `text/hjson`
  * Add `text/markdown`
  * Add `text/yaml`

1.2.0 / 2014-11-09
==================

  * Add `application/cea`
  * Add `application/dit`
  * Add `application/vnd.gov.sk.e-form+zip`
  * Add `application/vnd.tmd.mediaflex.api+xml`
  * Type `application/epub+zip` is now IANA-registered

1.1.2 / 2014-10-23
==================

  * Rebuild database for `application/x-www-form-urlencoded` change

1.1.1 / 2014-10-20
==================

  * Mark `application/x-www-form-urlencoded` as compressible.

1.1.0 / 2014-09-28
==================

  * Add `application/font-woff2`

1.0.3 / 2014-09-25
==================

  * Fix engine requirement in package

1.0.2 / 2014-09-25
==================

  * Add `application/coap-group+json`
  * Add `application/dcd`
  * Add `application/vnd.apache.thrift.binary`
  * Add `image/vnd.tencent.tap`
  * Mark all JSON-derived types as compressible
  * Update `text/vtt` data

1.0.1 / 2014-08-30
==================

  * Fix extension ordering

1.0.0 / 2014-08-30
==================

  * Add `application/atf`
  * Add `application/merge-patch+json`
  * Add `multipart/x-mixed-replace`
  * Add `source: 'apache'` metadata
  * Add `source: 'iana'` metadata
  * Remove badly-assumed charset data


code:
# mime-db

[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-image]][node-url]
[![Build Status][ci-image]][ci-url]
[![Coverage Status][coveralls-image]][coveralls-url]

This is a large database of mime types and information about them.
It consists of a single, public JSON file and does not include any logic,
allowing it to remain as un-opinionated as possible with an API.
It aggregates data from the following sources:

- http://www.iana.org/assignments/media-types/media-types.xhtml
- http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
- http://hg.nginx.org/nginx/raw-file/default/conf/mime.types

## Installation

```bash
npm install mime-db
```

### Database Download

If you're crazy enough to use this in the browser, you can just grab the
JSON file using [jsDelivr](https://www.jsdelivr.com/). It is recommended to
replace `master` with [a release tag](https://github.com/jshttp/mime-db/tags)
as the JSON format may change in the future.

```
https://cdn.jsdelivr.net/gh/jshttp/mime-db@master/db.json
```

## Usage

```js
var db = require('mime-db')

// grab data on .js files
var data = db['application/javascript']
```

## Data Structure

The JSON file is a map lookup for lowercased mime types.
Each mime type has the following properties:

- `.source` - where the mime type is defined.
    If not set, it's probably a custom media type.
    - `apache` - [Apache common media types](http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types)
    - `iana` - [IANA-defined media types](http://www.iana.org/assignments/media-types/media-types.xhtml)
    - `nginx` - [nginx media types](http://hg.nginx.org/nginx/raw-file/default/conf/mime.types)
- `.extensions[]` - known extensions associated with this mime type.
- `.compressible` - whether a file of this type can be gzipped.
- `.charset` - the default charset associated with this type, if any.

If unknown, every property could be `undefined`.

## Contributing

To edit the database, only make PRs against `src/custom-types.json` or
`src/custom-suffix.json`.

The `src/custom-types.json` file is a JSON object with the MIME type as the
keys and the values being an object with the following keys:

- `compressible` - leave out if you don't know, otherwise `true`/`false` to
  indicate whether the data represented by the type is typically compressible.
- `extensions` - include an array of file extensions that are associated with
  the type.
- `notes` - human-readable notes about the type, typically what the type is.
- `sources` - include an array of URLs of where the MIME type and the associated
  extensions are sourced from. This needs to be a [primary source](https://en.wikipedia.org/wiki/Primary_source);
  links to type aggregating sites and Wikipedia are _not acceptable_.

To update the build, run `npm run build`.

### Adding Custom Media Types

The best way to get new media types included in this library is to register
them with the IANA. The community registration procedure is outlined in
[RFC 6838 section 5](http://tools.ietf.org/html/rfc6838#section-5). Types
registered with the IANA are automatically pulled into this library.

If that is not possible / feasible, they can be added directly here as a
"custom" type. To do this, it is required to have a primary source that
definitively lists the media type. If an extension is going to be listed as
associateed with this media type, the source must definitively link the
media type and extension as well.

[ci-image]: https://badgen.net/github/checks/jshttp/mime-db/master?label=ci
[ci-url]: https://github.com/jshttp/mime-db/actions?query=workflow%3Aci
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/mime-db/master
[coveralls-url]: https://coveralls.io/r/jshttp/mime-db?branch=master
[node-image]: https://badgen.net/npm/node/mime-db
[node-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/mime-db
[npm-url]: https://npmjs.org/package/mime-db
[npm-version-image]: https://badgen.net/npm/v/mime-db


source: iana

source: apache

extensions: bin dms lrf mar so dist distz pkg bpk dump elc deploy exe dll deb dmg iso img msi msp msm buffer


code:
/*!
 * mime-db
 * Copyright(c) 2014 Jonathan Ong
 * Copyright(c) 2015-2022 Douglas Christopher Wilson
 * MIT Licensed
 */

/**
 * Module exports.
 */

module.exports = require('./db.json')


mime-db

description: Media Type Database

contributors: Douglas Christopher Wilson <doug@somethingdoug.com>

contributors: Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)

contributors: Robert Kieffer <robert@broofa.com> (http://github.com/broofa)

keywords: mime db type types database charset charsets

repository: jshttp/mime-db

build: node scripts/build

fetch: node scripts/fetch-apache && gnode scripts/fetch-iana && node scripts/fetch-nginx

lint: eslint .

test: mocha --reporter spec --bail --check-leaks test/

test-ci: nyc --reporter=lcov --reporter=text npm test

test-cov: nyc --reporter=html --reporter=text npm test

update: npm run fetch && npm run build

version: node scripts/version-history.js && git add HISTORY.md


code:
2.1.35 / 2022-03-12
===================

  * deps: mime-db@1.52.0
    - Add extensions from IANA for more `image/*` types
    - Add extension `.asc` to `application/pgp-keys`
    - Add extensions to various XML types
    - Add new upstream MIME types

2.1.34 / 2021-11-08
===================

  * deps: mime-db@1.51.0
    - Add new upstream MIME types

2.1.33 / 2021-10-01
===================

  * deps: mime-db@1.50.0
    - Add deprecated iWorks mime types and extensions
    - Add new upstream MIME types

2.1.32 / 2021-07-27
===================

  * deps: mime-db@1.49.0
    - Add extension `.trig` to `application/trig`
    - Add new upstream MIME types

2.1.31 / 2021-06-01
===================

  * deps: mime-db@1.48.0
    - Add extension `.mvt` to `application/vnd.mapbox-vector-tile`
    - Add new upstream MIME types

2.1.30 / 2021-04-02
===================

  * deps: mime-db@1.47.0
    - Add extension `.amr` to `audio/amr`
    - Remove ambigious extensions from IANA for `application/*+xml` types
    - Update primary extension to `.es` for `application/ecmascript`

2.1.29 / 2021-02-17
===================

  * deps: mime-db@1.46.0
    - Add extension `.amr` to `audio/amr`
    - Add extension `.m4s` to `video/iso.segment`
    - Add extension `.opus` to `audio/ogg`
    - Add new upstream MIME types

2.1.28 / 2021-01-01
===================

  * deps: mime-db@1.45.0
    - Add `application/ubjson` with extension `.ubj`
    - Add `image/avif` with extension `.avif`
    - Add `image/ktx2` with extension `.ktx2`
    - Add extension `.dbf` to `application/vnd.dbf`
    - Add extension `.rar` to `application/vnd.rar`
    - Add extension `.td` to `application/urc-targetdesc+xml`
    - Add new upstream MIME types
    - Fix extension of `application/vnd.apple.keynote` to be `.key`

2.1.27 / 2020-04-23
===================

  * deps: mime-db@1.44.0
    - Add charsets from IANA
    - Add extension `.cjs` to `application/node`
    - Add new upstream MIME types

2.1.26 / 2020-01-05
===================

  * deps: mime-db@1.43.0
    - Add `application/x-keepass2` with extension `.kdbx`
    - Add extension `.mxmf` to `audio/mobile-xmf`
    - Add extensions from IANA for `application/*+xml` types
    - Add new upstream MIME types

2.1.25 / 2019-11-12
===================

  * deps: mime-db@1.42.0
    - Add new upstream MIME types
    - Add `application/toml` with extension `.toml`
    - Add `image/vnd.ms-dds` with extension `.dds`

2.1.24 / 2019-04-20
===================

  * deps: mime-db@1.40.0
    - Add extensions from IANA for `model/*` types
    - Add `text/mdx` with extension `.mdx`

2.1.23 / 2019-04-17
===================

  * deps: mime-db@~1.39.0
    - Add extensions `.siv` and `.sieve` to `application/sieve`
    - Add new upstream MIME types

2.1.22 / 2019-02-14
===================

  * deps: mime-db@~1.38.0
    - Add extension `.nq` to `application/n-quads`
    - Add extension `.nt` to `application/n-triples`
    - Add new upstream MIME types

2.1.21 / 2018-10-19
===================

  * deps: mime-db@~1.37.0
    - Add extensions to HEIC image types
    - Add new upstream MIME types

2.1.20 / 2018-08-26
===================

  * deps: mime-db@~1.36.0
    - Add Apple file extensions from IANA
    - Add extensions from IANA for `image/*` types
    - Add new upstream MIME types

2.1.19 / 2018-07-17
===================

  * deps: mime-db@~1.35.0
    - Add extension `.csl` to `application/vnd.citationstyles.style+xml`
    - Add extension `.es` to `application/ecmascript`
    - Add extension `.owl` to `application/rdf+xml`
    - Add new upstream MIME types
    - Add UTF-8 as default charset for `text/turtle`

2.1.18 / 2018-02-16
===================

  * deps: mime-db@~1.33.0
    - Add `application/raml+yaml` with extension `.raml`
    - Add `application/wasm` with extension `.wasm`
    - Add `text/shex` with extension `.shex`
    - Add extensions for JPEG-2000 images
    - Add extensions from IANA for `message/*` types
    - Add new upstream MIME types
    - Update font MIME types
    - Update `text/hjson` to registered `application/hjson`

2.1.17 / 2017-09-01
===================

  * deps: mime-db@~1.30.0
    - Add `application/vnd.ms-outlook`
    - Add `application/x-arj`
    - Add extension `.mjs` to `application/javascript`
    - Add glTF types and extensions
    - Add new upstream MIME types
    - Add `text/x-org`
    - Add VirtualBox MIME types
    - Fix `source` records for `video/*` types that are IANA
    - Update `font/opentype` to registered `font/otf`

2.1.16 / 2017-07-24
===================

  * deps: mime-db@~1.29.0
    - Add `application/fido.trusted-apps+json`
    - Add extension `.wadl` to `application/vnd.sun.wadl+xml`
    - Add extension `.gz` to `application/gzip`
    - Add new upstream MIME types
    - Update extensions `.md` and `.markdown` to be `text/markdown`

2.1.15 / 2017-03-23
===================

  * deps: mime-db@~1.27.0
    - Add new mime types
    - Add `image/apng`

2.1.14 / 2017-01-14
===================

  * deps: mime-db@~1.26.0
    - Add new mime types

2.1.13 / 2016-11-18
===================

  * deps: mime-db@~1.25.0
    - Add new mime types

2.1.12 / 2016-09-18
===================

  * deps: mime-db@~1.24.0
    - Add new mime types
    - Add `audio/mp3`

2.1.11 / 2016-05-01
===================

  * deps: mime-db@~1.23.0
    - Add new mime types

2.1.10 / 2016-02-15
===================

  * deps: mime-db@~1.22.0
    - Add new mime types
    - Fix extension of `application/dash+xml`
    - Update primary extension for `audio/mp4`

2.1.9 / 2016-01-06
==================

  * deps: mime-db@~1.21.0
    - Add new mime types

2.1.8 / 2015-11-30
==================

  * deps: mime-db@~1.20.0
    - Add new mime types

2.1.7 / 2015-09-20
==================

  * deps: mime-db@~1.19.0
    - Add new mime types

2.1.6 / 2015-09-03
==================

  * deps: mime-db@~1.18.0
    - Add new mime types

2.1.5 / 2015-08-20
==================

  * deps: mime-db@~1.17.0
    - Add new mime types

2.1.4 / 2015-07-30
==================

  * deps: mime-db@~1.16.0
    - Add new mime types

2.1.3 / 2015-07-13
==================

  * deps: mime-db@~1.15.0
    - Add new mime types

2.1.2 / 2015-06-25
==================

  * deps: mime-db@~1.14.0
    - Add new mime types

2.1.1 / 2015-06-08
==================

  * perf: fix deopt during mapping

2.1.0 / 2015-06-07
==================

  * Fix incorrectly treating extension-less file name as extension
    - i.e. `'path/to/json'` will no longer return `application/json`
  * Fix `.charset(type)` to accept parameters
  * Fix `.charset(type)` to match case-insensitive
  * Improve generation of extension to MIME mapping
  * Refactor internals for readability and no argument reassignment
  * Prefer `application/*` MIME types from the same source
  * Prefer any type over `application/octet-stream`
  * deps: mime-db@~1.13.0
    - Add nginx as a source
    - Add new mime types

2.0.14 / 2015-06-06
===================

  * deps: mime-db@~1.12.0
    - Add new mime types

2.0.13 / 2015-05-31
===================

  * deps: mime-db@~1.11.0
    - Add new mime types

2.0.12 / 2015-05-19
===================

  * deps: mime-db@~1.10.0
    - Add new mime types

2.0.11 / 2015-05-05
===================

  * deps: mime-db@~1.9.1
    - Add new mime types

2.0.10 / 2015-03-13
===================

  * deps: mime-db@~1.8.0
    - Add new mime types

2.0.9 / 2015-02-09
==================

  * deps: mime-db@~1.7.0
    - Add new mime types
    - Community extensions ownership transferred from `node-mime`

2.0.8 / 2015-01-29
==================

  * deps: mime-db@~1.6.0
    - Add new mime types

2.0.7 / 2014-12-30
==================

  * deps: mime-db@~1.5.0
    - Add new mime types
    - Fix various invalid MIME type entries

2.0.6 / 2014-12-30
==================

  * deps: mime-db@~1.4.0
    - Add new mime types
    - Fix various invalid MIME type entries
    - Remove example template MIME types

2.0.5 / 2014-12-29
==================

  * deps: mime-db@~1.3.1
    - Fix missing extensions

2.0.4 / 2014-12-10
==================

  * deps: mime-db@~1.3.0
    - Add new mime types

2.0.3 / 2014-11-09
==================

  * deps: mime-db@~1.2.0
    - Add new mime types

2.0.2 / 2014-09-28
==================

  * deps: mime-db@~1.1.0
    - Add new mime types
    - Update charsets

2.0.1 / 2014-09-07
==================

  * Support Node.js 0.6

2.0.0 / 2014-09-02
==================

  * Use `mime-db`
  * Remove `.define()`

1.0.2 / 2014-08-04
==================

  * Set charset=utf-8 for `text/javascript`

1.0.1 / 2014-06-24
==================

  * Add `text/jsx` type

1.0.0 / 2014-05-12
==================

  * Return `false` for unknown types
  * Set charset=utf-8 for `application/json`

0.1.0 / 2014-05-02
==================

  * Initial release


code:
# mime-types

[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][ci-image]][ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]

The ultimate javascript content-type utility.

Similar to [the `mime@1.x` module](https://www.npmjs.com/package/mime), except:

- __No fallbacks.__ Instead of naively returning the first available type,
  `mime-types` simply returns `false`, so do
  `var type = mime.lookup('unrecognized') || 'application/octet-stream'`.
- No `new Mime()` business, so you could do `var lookup = require('mime-types').lookup`.
- No `.define()` functionality
- Bug fixes for `.lookup(path)`

Otherwise, the API is compatible with `mime` 1.x.

## Install

This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):

```sh
$ npm install mime-types
```

## Adding Types

All mime types are based on [mime-db](https://www.npmjs.com/package/mime-db),
so open a PR there if you'd like to add mime types.

## API

```js
var mime = require('mime-types')
```

All functions return `false` if input is invalid or not found.

### mime.lookup(path)

Lookup the content-type associated with a file.

```js
mime.lookup('json') // 'application/json'
mime.lookup('.md') // 'text/markdown'
mime.lookup('file.html') // 'text/html'
mime.lookup('folder/file.js') // 'application/javascript'
mime.lookup('folder/.htaccess') // false

mime.lookup('cats') // false
```

### mime.contentType(type)

Create a full content-type header given a content-type or extension.
When given an extension, `mime.lookup` is used to get the matching
content-type, otherwise the given content-type is used. Then if the
content-type does not already have a `charset` parameter, `mime.charset`
is used to get the default charset and add to the returned content-type.

```js
mime.contentType('markdown') // 'text/x-markdown; charset=utf-8'
mime.contentType('file.json') // 'application/json; charset=utf-8'
mime.contentType('text/html') // 'text/html; charset=utf-8'
mime.contentType('text/html; charset=iso-8859-1') // 'text/html; charset=iso-8859-1'

// from a full path
mime.contentType(path.extname('/path/to/file.json')) // 'application/json; charset=utf-8'
```

### mime.extension(type)

Get the default extension for a content-type.

```js
mime.extension('application/octet-stream') // 'bin'
```

### mime.charset(type)

Lookup the implied default charset of a content-type.

```js
mime.charset('text/markdown') // 'UTF-8'
```

### var type = mime.types[extension]

A map of content-types by extension.

### [extensions...] = mime.extensions[type]

A map of extensions by content-type.

## License

[MIT](LICENSE)

[ci-image]: https://badgen.net/github/checks/jshttp/mime-types/master?label=ci
[ci-url]: https://github.com/jshttp/mime-types/actions/workflows/ci.yml
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/mime-types/master
[coveralls-url]: https://coveralls.io/r/jshttp/mime-types?branch=master
[node-version-image]: https://badgen.net/npm/node/mime-types
[node-version-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/mime-types
[npm-url]: https://npmjs.org/package/mime-types
[npm-version-image]: https://badgen.net/npm/v/mime-types


code:
/*!
 * mime-types
 * Copyright(c) 2014 Jonathan Ong
 * Copyright(c) 2015 Douglas Christopher Wilson
 * MIT Licensed
 */

'use strict'

/**
 * Module dependencies.
 * @private
 */

var db = require('mime-db')
var extname = require('path').extname

/**
 * Module variables.
 * @private
 */

var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/
var TEXT_TYPE_REGEXP = /^text\//i

/**
 * Module exports.
 * @public
 */

exports.charset = charset
exports.charsets = { lookup: charset }
exports.contentType = contentType
exports.extension = extension
exports.extensions = Object.create(null)
exports.lookup = lookup
exports.types = Object.create(null)

// Populate the extensions/types maps
populateMaps(exports.extensions, exports.types)

/**
 * Get the default charset for a MIME type.
 *
 * @param {string} type
 * @return {boolean|string}
 */

function charset (type) {
  if (!type || typeof type !== 'string') {
    return false
  }

  // TODO: use media-typer
  var match = EXTRACT_TYPE_REGEXP.exec(type)
  var mime = match && db[match[1].toLowerCase()]

  if (mime && mime.charset) {
    return mime.charset
  }

  // default text/* to utf-8
  if (match && TEXT_TYPE_REGEXP.test(match[1])) {
    return 'UTF-8'
  }

  return false
}

/**
 * Create a full Content-Type header given a MIME type or extension.
 *
 * @param {string} str
 * @return {boolean|string}
 */

function contentType (str) {
  // TODO: should this even be in this module?
  if (!str || typeof str !== 'string') {
    return false
  }

  var mime = str.indexOf('/') === -1
    ? exports.lookup(str)
    : str

  if (!mime) {
    return false
  }

  // TODO: use content-type or other module
  if (mime.indexOf('charset') === -1) {
    var charset = exports.charset(mime)
    if (charset) mime += '; charset=' + charset.toLowerCase()
  }

  return mime
}

/**
 * Get the default extension for a MIME type.
 *
 * @param {string} type
 * @return {boolean|string}
 */

function extension (type) {
  if (!type || typeof type !== 'string') {
    return false
  }

  // TODO: use media-typer
  var match = EXTRACT_TYPE_REGEXP.exec(type)

  // get extensions
  var exts = match && exports.extensions[match[1].toLowerCase()]

  if (!exts || !exts.length) {
    return false
  }

  return exts[0]
}

/**
 * Lookup the MIME type for a file path/extension.
 *
 * @param {string} path
 * @return {boolean|string}
 */

function lookup (path) {
  if (!path || typeof path !== 'string') {
    return false
  }

  // get the extension ("ext" or ".ext" or full path)
  var extension = extname('x.' + path)
    .toLowerCase()
    .substr(1)

  if (!extension) {
    return false
  }

  return exports.types[extension] || false
}

/**
 * Populate the extensions and types maps.
 * @private
 */

function populateMaps (extensions, types) {
  // source preference (least -> most)
  var preference = ['nginx', 'apache', undefined, 'iana']

  Object.keys(db).forEach(function forEachMimeType (type) {
    var mime = db[type]
    var exts = mime.extensions

    if (!exts || !exts.length) {
      return
    }

    // mime -> extensions
    extensions[type] = exts

    // extension -> mime
    for (var i = 0; i < exts.length; i++) {
      var extension = exts[i]

      if (types[extension]) {
        var from = preference.indexOf(db[types[extension]].source)
        var to = preference.indexOf(mime.source)

        if (types[extension] !== 'application/octet-stream' &&
          (from > to || (from === to && types[extension].substr(0, 12) === 'application/'))) {
          // skip the remapping
          continue
        }
      }

      // set the extension -> mime
      types[extension] = type
    }
  })
}


mime-types

description: The ultimate javascript content-type utility.

contributors: Jeremiah Senkpiel <fishrock123@rocketmail.com> (https://searchbeam.jit.su)

keywords: mime types

repository: jshttp/mime-types

test: mocha --reporter spec test/test.js


code:
# Changelog

## v1.6.0 (24/11/2017)
*No changelog for this release.*

---

## v2.0.4 (24/11/2017)
- [**closed**] Switch to mime-score module for resolving extension contention issues. [#182](https://github.com/broofa/node-mime/issues/182)
- [**closed**] Update mime-db to 1.31.0 in v1.x branch [#181](https://github.com/broofa/node-mime/issues/181)

---

## v1.5.0 (22/11/2017)
- [**closed**] need ES5 version ready in npm package [#179](https://github.com/broofa/node-mime/issues/179)
- [**closed**] mime-db no trace of iWork - pages / numbers / etc. [#178](https://github.com/broofa/node-mime/issues/178)
- [**closed**] How it works in brownser ? [#176](https://github.com/broofa/node-mime/issues/176)
- [**closed**] Missing `./Mime` [#175](https://github.com/broofa/node-mime/issues/175)
- [**closed**] Vulnerable Regular Expression [#167](https://github.com/broofa/node-mime/issues/167)

---

## v2.0.3 (25/09/2017)
*No changelog for this release.*

---

## v1.4.1 (25/09/2017)
- [**closed**] Issue when bundling with webpack [#172](https://github.com/broofa/node-mime/issues/172)

---

## v2.0.2 (15/09/2017)
- [**V2**] fs.readFileSync is not a function [#165](https://github.com/broofa/node-mime/issues/165)
- [**closed**] The extension for video/quicktime should map to .mov, not .qt [#164](https://github.com/broofa/node-mime/issues/164)
- [**V2**] [v2 Feedback request] Mime class API [#163](https://github.com/broofa/node-mime/issues/163)
- [**V2**] [v2 Feedback request] Resolving conflicts over extensions [#162](https://github.com/broofa/node-mime/issues/162)
- [**V2**] Allow callers to load module with official, full, or no defined types.  [#161](https://github.com/broofa/node-mime/issues/161)
- [**V2**] Use "facets" to resolve extension conflicts [#160](https://github.com/broofa/node-mime/issues/160)
- [**V2**] Remove fs and path dependencies [#152](https://github.com/broofa/node-mime/issues/152)
- [**V2**] Default content-type should not be application/octet-stream [#139](https://github.com/broofa/node-mime/issues/139)
- [**V2**] reset mime-types [#124](https://github.com/broofa/node-mime/issues/124)
- [**V2**] Extensionless paths should return null or false [#113](https://github.com/broofa/node-mime/issues/113)

---

## v2.0.1 (14/09/2017)
- [**closed**] Changelog for v2.0 does not mention breaking changes [#171](https://github.com/broofa/node-mime/issues/171)
- [**closed**] MIME breaking with 'class' declaration as it is without 'use strict mode' [#170](https://github.com/broofa/node-mime/issues/170)

---

## v2.0.0 (12/09/2017)
- [**closed**] woff and woff2 [#168](https://github.com/broofa/node-mime/issues/168)

---

## v1.4.0 (28/08/2017)
- [**closed**] support for ac3 voc files [#159](https://github.com/broofa/node-mime/issues/159)
- [**closed**] Help understanding change from application/xml to text/xml [#158](https://github.com/broofa/node-mime/issues/158)
- [**closed**] no longer able to override mimetype [#157](https://github.com/broofa/node-mime/issues/157)
- [**closed**] application/vnd.adobe.photoshop [#147](https://github.com/broofa/node-mime/issues/147)
- [**closed**] Directories should appear as something other than application/octet-stream [#135](https://github.com/broofa/node-mime/issues/135)
- [**closed**] requested features [#131](https://github.com/broofa/node-mime/issues/131)
- [**closed**] Make types.json loading optional? [#129](https://github.com/broofa/node-mime/issues/129)
- [**closed**] Cannot find module './types.json' [#120](https://github.com/broofa/node-mime/issues/120)
- [**V2**] .wav files show up as "audio/x-wav" instead of "audio/x-wave" [#118](https://github.com/broofa/node-mime/issues/118)
- [**closed**] Don't be a pain in the ass for node community [#108](https://github.com/broofa/node-mime/issues/108)
- [**closed**] don't make default_type global [#78](https://github.com/broofa/node-mime/issues/78)
- [**closed**] mime.extension() fails if the content-type is parameterized [#74](https://github.com/broofa/node-mime/issues/74)

---

## v1.3.6 (11/05/2017)
- [**closed**] .md should be text/markdown as of March 2016 [#154](https://github.com/broofa/node-mime/issues/154)
- [**closed**] Error while installing mime [#153](https://github.com/broofa/node-mime/issues/153)
- [**closed**] application/manifest+json [#149](https://github.com/broofa/node-mime/issues/149)
- [**closed**] Dynamic adaptive streaming over HTTP (DASH) file extension typo [#141](https://github.com/broofa/node-mime/issues/141)
- [**closed**] charsets image/png undefined [#140](https://github.com/broofa/node-mime/issues/140)
- [**closed**] Mime-db dependency out of date [#130](https://github.com/broofa/node-mime/issues/130)
- [**closed**] how to support plist？ [#126](https://github.com/broofa/node-mime/issues/126)
- [**closed**] how does .types file format look like? [#123](https://github.com/broofa/node-mime/issues/123)
- [**closed**] Feature: support for expanding MIME patterns [#121](https://github.com/broofa/node-mime/issues/121)
- [**closed**] DEBUG_MIME doesn't work [#117](https://github.com/broofa/node-mime/issues/117)

---

## v1.3.4 (06/02/2015)
*No changelog for this release.*

---

## v1.3.3 (06/02/2015)
*No changelog for this release.*

---

## v1.3.1 (05/02/2015)
- [**closed**] Consider adding support for Handlebars .hbs file ending [#111](https://github.com/broofa/node-mime/issues/111)
- [**closed**] Consider adding support for hjson. [#110](https://github.com/broofa/node-mime/issues/110)
- [**closed**] Add mime type for Opus audio files [#94](https://github.com/broofa/node-mime/issues/94)
- [**closed**] Consider making the `Requesting New Types` information more visible [#77](https://github.com/broofa/node-mime/issues/77)

---

## v1.3.0 (05/02/2015)
- [**closed**] Add common name? [#114](https://github.com/broofa/node-mime/issues/114)
- [**closed**] application/x-yaml [#104](https://github.com/broofa/node-mime/issues/104)
- [**closed**] Add mime type for WOFF file format 2.0 [#102](https://github.com/broofa/node-mime/issues/102)
- [**closed**] application/x-msi for .msi [#99](https://github.com/broofa/node-mime/issues/99)
- [**closed**] Add mimetype for gettext translation files [#98](https://github.com/broofa/node-mime/issues/98)
- [**closed**] collaborators [#88](https://github.com/broofa/node-mime/issues/88)
- [**closed**] getting errot in installation of mime module...any1 can help? [#87](https://github.com/broofa/node-mime/issues/87)
- [**closed**] should application/json's charset be utf8? [#86](https://github.com/broofa/node-mime/issues/86)
- [**closed**] Add "license" and "licenses" to package.json [#81](https://github.com/broofa/node-mime/issues/81)
- [**closed**] lookup with extension-less file on Windows returns wrong type [#68](https://github.com/broofa/node-mime/issues/68)

---

## v1.2.11 (15/08/2013)
- [**closed**] Update mime.types [#65](https://github.com/broofa/node-mime/issues/65)
- [**closed**] Publish a new version [#63](https://github.com/broofa/node-mime/issues/63)
- [**closed**] README should state upfront that "application/octet-stream" is default for unknown extension [#55](https://github.com/broofa/node-mime/issues/55)
- [**closed**] Suggested improvement to the charset API [#52](https://github.com/broofa/node-mime/issues/52)

---

## v1.2.10 (25/07/2013)
- [**closed**] Mime type for woff files should be application/font-woff and not application/x-font-woff [#62](https://github.com/broofa/node-mime/issues/62)
- [**closed**] node.types in conflict with mime.types [#51](https://github.com/broofa/node-mime/issues/51)

---

## v1.2.9 (17/01/2013)
- [**closed**] Please update "mime" NPM [#49](https://github.com/broofa/node-mime/issues/49)
- [**closed**] Please add semicolon [#46](https://github.com/broofa/node-mime/issues/46)
- [**closed**] parse full mime types [#43](https://github.com/broofa/node-mime/issues/43)

---

## v1.2.8 (10/01/2013)
- [**closed**] /js directory mime is application/javascript. Is it correct? [#47](https://github.com/broofa/node-mime/issues/47)
- [**closed**] Add mime types for lua code. [#45](https://github.com/broofa/node-mime/issues/45)

---

## v1.2.7 (19/10/2012)
- [**closed**] cannot install 1.2.7 via npm [#41](https://github.com/broofa/node-mime/issues/41)
- [**closed**] Transfer ownership to @broofa [#36](https://github.com/broofa/node-mime/issues/36)
- [**closed**] it's wrong to set charset to UTF-8 for text [#30](https://github.com/broofa/node-mime/issues/30)
- [**closed**] Allow multiple instances of MIME types container [#27](https://github.com/broofa/node-mime/issues/27)

---

## v1.2.5 (16/02/2012)
- [**closed**] When looking up a types, check hasOwnProperty [#23](https://github.com/broofa/node-mime/issues/23)
- [**closed**] Bump version to 1.2.2 [#18](https://github.com/broofa/node-mime/issues/18)
- [**closed**] No license [#16](https://github.com/broofa/node-mime/issues/16)
- [**closed**] Some types missing that are used by html5/css3 [#13](https://github.com/broofa/node-mime/issues/13)
- [**closed**] npm install fails for 1.2.1 [#12](https://github.com/broofa/node-mime/issues/12)
- [**closed**] image/pjpeg + image/x-png [#10](https://github.com/broofa/node-mime/issues/10)
- [**closed**] symlink [#8](https://github.com/broofa/node-mime/issues/8)
- [**closed**] gzip [#2](https://github.com/broofa/node-mime/issues/2)
- [**closed**] ALL CAPS filenames return incorrect mime type [#1](https://github.com/broofa/node-mime/issues/1)


code:
# mime

Comprehensive MIME type mapping API based on mime-db module.

## Install

Install with [npm](http://github.com/isaacs/npm):

    npm install mime

## Contributing / Testing

    npm run test

## Command Line

    mime [path_string]

E.g.

    > mime scripts/jquery.js
    application/javascript

## API - Queries

### mime.lookup(path)
Get the mime type associated with a file, if no mime type is found `application/octet-stream` is returned. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.').  E.g.

```js
var mime = require('mime');

mime.lookup('/path/to/file.txt');         // => 'text/plain'
mime.lookup('file.txt');                  // => 'text/plain'
mime.lookup('.TXT');                      // => 'text/plain'
mime.lookup('htm');                       // => 'text/html'
```

### mime.default_type
Sets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.)

### mime.extension(type)
Get the default extension for `type`

```js
mime.extension('text/html');                 // => 'html'
mime.extension('application/octet-stream');  // => 'bin'
```

### mime.charsets.lookup()

Map mime-type to charset

```js
mime.charsets.lookup('text/plain');        // => 'UTF-8'
```

(The logic for charset lookups is pretty rudimentary.  Feel free to suggest improvements.)

## API - Defining Custom Types

Custom type mappings can be added on a per-project basis via the following APIs.

### mime.define()

Add custom mime/extension mappings

```js
mime.define({
    'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],
    'application/x-my-type': ['x-mt', 'x-mtt'],
    // etc ...
});

mime.lookup('x-sft');                 // => 'text/x-some-format'
```

The first entry in the extensions array is returned by `mime.extension()`. E.g.

```js
mime.extension('text/x-some-format'); // => 'x-sf'
```

### mime.load(filepath)

Load mappings from an Apache ".types" format file

```js
mime.load('./my_project.types');
```
The .types file format is simple -  See the `types` dir for examples.


code:
#!/usr/bin/env node

var mime = require('./mime.js');
var file = process.argv[2];
var type = mime.lookup(file);

process.stdout.write(type + '\n');


code:
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;


mime

description: A comprehensive library for mime-type mapping

prepare: node src/build.js

changelog: gren changelog --tags=all --generate --override

test: node src/test.js

keywords: util mime

type: git


code:
#!/usr/bin/env node

'use strict';

const fs = require('fs');
const path = require('path');
const mimeScore = require('mime-score');

let db = require('mime-db');
let chalk = require('chalk');

const STANDARD_FACET_SCORE = 900;

const byExtension = {};

// Clear out any conflict extensions in mime-db
for (let type in db) {
  let entry = db[type];
  entry.type = type;

  if (!entry.extensions) continue;

  entry.extensions.forEach(ext => {
    if (ext in byExtension) {
      const e0 = entry;
      const e1 = byExtension[ext];
      e0.pri = mimeScore(e0.type, e0.source);
      e1.pri = mimeScore(e1.type, e1.source);

      let drop = e0.pri < e1.pri ? e0 : e1;
      let keep = e0.pri >= e1.pri ? e0 : e1;
      drop.extensions = drop.extensions.filter(e => e !== ext);

      console.log(`${ext}: Keeping ${chalk.green(keep.type)} (${keep.pri}), dropping ${chalk.red(drop.type)} (${drop.pri})`);
    }
    byExtension[ext] = entry;
  });
}

function writeTypesFile(types, path) {
  fs.writeFileSync(path, JSON.stringify(types));
}

// Segregate into standard and non-standard types based on facet per
// https://tools.ietf.org/html/rfc6838#section-3.1
const types = {};

Object.keys(db).sort().forEach(k => {
  const entry = db[k];
  types[entry.type] = entry.extensions;
});

writeTypesFile(types, path.join(__dirname, '..', 'types.json'));


code:
/**
 * Usage: node test.js
 */

var mime = require('../mime');
var assert = require('assert');
var path = require('path');

//
// Test mime lookups
//

assert.equal('text/plain', mime.lookup('text.txt'));     // normal file
assert.equal('text/plain', mime.lookup('TEXT.TXT'));     // uppercase
assert.equal('text/plain', mime.lookup('dir/text.txt')); // dir + file
assert.equal('text/plain', mime.lookup('.text.txt'));    // hidden file
assert.equal('text/plain', mime.lookup('.txt'));         // nameless
assert.equal('text/plain', mime.lookup('txt'));          // extension-only
assert.equal('text/plain', mime.lookup('/txt'));         // extension-less ()
assert.equal('text/plain', mime.lookup('\\txt'));        // Windows, extension-less
assert.equal('application/octet-stream', mime.lookup('text.nope')); // unrecognized
assert.equal('fallback', mime.lookup('text.fallback', 'fallback')); // alternate default

//
// Test extensions
//

assert.equal('txt', mime.extension(mime.types.text));
assert.equal('html', mime.extension(mime.types.htm));
assert.equal('bin', mime.extension('application/octet-stream'));
assert.equal('bin', mime.extension('application/octet-stream '));
assert.equal('html', mime.extension(' text/html; charset=UTF-8'));
assert.equal('html', mime.extension('text/html; charset=UTF-8 '));
assert.equal('html', mime.extension('text/html; charset=UTF-8'));
assert.equal('html', mime.extension('text/html ; charset=UTF-8'));
assert.equal('html', mime.extension('text/html;charset=UTF-8'));
assert.equal('html', mime.extension('text/Html;charset=UTF-8'));
assert.equal(undefined, mime.extension('unrecognized'));

//
// Test node.types lookups
//

assert.equal('font/woff', mime.lookup('file.woff'));
assert.equal('application/octet-stream', mime.lookup('file.buffer'));
// TODO: Uncomment once #157 is resolved
// assert.equal('audio/mp4', mime.lookup('file.m4a'));
assert.equal('font/otf', mime.lookup('file.otf'));

//
// Test charsets
//

assert.equal('UTF-8', mime.charsets.lookup('text/plain'));
assert.equal('UTF-8', mime.charsets.lookup(mime.types.js));
assert.equal('UTF-8', mime.charsets.lookup(mime.types.json));
assert.equal(undefined, mime.charsets.lookup(mime.types.bin));
assert.equal('fallback', mime.charsets.lookup('application/octet-stream', 'fallback'));

console.log('\nAll tests passed');


code:
declare const mimicFn: {
	/**
	Make a function mimic another one. It will copy over the properties `name`, `length`, `displayName`, and any custom properties you may have set.

	@param to - Mimicking function.
	@param from - Function to mimic.
	@returns The modified `to` function.

	@example
	```
	import mimicFn = require('mimic-fn');

	function foo() {}
	foo.unicorn = '🦄';

	function wrapper() {
		return foo();
	}

	console.log(wrapper.name);
	//=> 'wrapper'

	mimicFn(wrapper, foo);

	console.log(wrapper.name);
	//=> 'foo'

	console.log(wrapper.unicorn);
	//=> '🦄'
	```
	*/
	<
		ArgumentsType extends unknown[],
		ReturnType,
		FunctionType extends (...arguments: ArgumentsType) => ReturnType
	>(
		to: (...arguments: ArgumentsType) => ReturnType,
		from: FunctionType
	): FunctionType;

	// TODO: Remove this for the next major release, refactor the whole definition to:
	// declare function mimicFn<
	//	ArgumentsType extends unknown[],
	//	ReturnType,
	//	FunctionType extends (...arguments: ArgumentsType) => ReturnType
	// >(
	//	to: (...arguments: ArgumentsType) => ReturnType,
	//	from: FunctionType
	// ): FunctionType;
	// export = mimicFn;
	default: typeof mimicFn;
};

export = mimicFn;


code:
'use strict';

const mimicFn = (to, from) => {
	for (const prop of Reflect.ownKeys(from)) {
		Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop));
	}

	return to;
};

module.exports = mimicFn;
// TODO: Remove this for the next major release
module.exports.default = mimicFn;


mimic-fn

description: Make a function mimic another one

repository: sindresorhus/mimic-fn

test: xo && ava && tsd

keywords: function mimic imitate rename copy inherit properties name func fn set infer change


code:
# mimic-fn [![Build Status](https://travis-ci.org/sindresorhus/mimic-fn.svg?branch=master)](https://travis-ci.org/sindresorhus/mimic-fn)

> Make a function mimic another one

Useful when you wrap a function in another function and like to preserve the original name and other properties.

## Install

```
$ npm install mimic-fn
```

## Usage

```js
const mimicFn = require('mimic-fn');

function foo() {}
foo.unicorn = '🦄';

function wrapper() {
	return foo();
}

console.log(wrapper.name);
//=> 'wrapper'

mimicFn(wrapper, foo);

console.log(wrapper.name);
//=> 'foo'

console.log(wrapper.unicorn);
//=> '🦄'
```

## API

It will copy over the properties `name`, `length`, `displayName`, and any custom properties you may have set.

### mimicFn(to, from)

Modifies the `to` function and returns it.

#### to

Type: `Function`

Mimicking function.

#### from

Type: `Function`

Function to mimic.

## Related

- [rename-fn](https://github.com/sindresorhus/rename-fn) - Rename a function
- [keep-func-props](https://github.com/ehmicky/keep-func-props) - Wrap a function without changing its name, length and other properties

## License

MIT © [Sindre Sorhus](https://sindresorhus.com)


code:
export type Options = {
	/**
	Skip modifying [non-configurable properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor#Description) instead of throwing an error.

	@default false
	*/
	readonly ignoreNonConfigurable?: boolean;
};

/**
Modifies the `to` function to mimic the `from` function. Returns the `to` function.

`name`, `displayName`, and any other properties of `from` are copied. The `length` property is not copied. Prototype, class, and inherited properties are copied.

`to.toString()` will return the same as `from.toString()` but prepended with a `Wrapped with to()` comment.

@param to - Mimicking function.
@param from - Function to mimic.
@returns The modified `to` function.

@example
```
import mimicFunction from 'mimic-function';

function foo() {}
foo.unicorn = '🦄';

function wrapper() {
	return foo();
}

console.log(wrapper.name);
//=> 'wrapper'

mimicFunction(wrapper, foo);

console.log(wrapper.name);
//=> 'foo'

console.log(wrapper.unicorn);
//=> '🦄'
```
*/
export default function mimicFunction<
	ArgumentsType extends unknown[],
	ReturnType,
	FunctionType extends (...arguments_: ArgumentsType) => ReturnType,
>(
	to: (...arguments_: ArgumentsType) => ReturnType,
	from: FunctionType,
	options?: Options,
): FunctionType;


code:
const copyProperty = (to, from, property, ignoreNonConfigurable) => {
	// `Function#length` should reflect the parameters of `to` not `from` since we keep its body.
	// `Function#prototype` is non-writable and non-configurable so can never be modified.
	if (property === 'length' || property === 'prototype') {
		return;
	}

	// `Function#arguments` and `Function#caller` should not be copied. They were reported to be present in `Reflect.ownKeys` for some devices in React Native (#41), so we explicitly ignore them here.
	if (property === 'arguments' || property === 'caller') {
		return;
	}

	const toDescriptor = Object.getOwnPropertyDescriptor(to, property);
	const fromDescriptor = Object.getOwnPropertyDescriptor(from, property);

	if (!canCopyProperty(toDescriptor, fromDescriptor) && ignoreNonConfigurable) {
		return;
	}

	Object.defineProperty(to, property, fromDescriptor);
};

// `Object.defineProperty()` throws if the property exists, is not configurable and either:
// - one its descriptors is changed
// - it is non-writable and its value is changed
const canCopyProperty = function (toDescriptor, fromDescriptor) {
	return toDescriptor === undefined || toDescriptor.configurable || (
		toDescriptor.writable === fromDescriptor.writable
		&& toDescriptor.enumerable === fromDescriptor.enumerable
		&& toDescriptor.configurable === fromDescriptor.configurable
		&& (toDescriptor.writable || toDescriptor.value === fromDescriptor.value)
	);
};

const changePrototype = (to, from) => {
	const fromPrototype = Object.getPrototypeOf(from);
	if (fromPrototype === Object.getPrototypeOf(to)) {
		return;
	}

	Object.setPrototypeOf(to, fromPrototype);
};

const wrappedToString = (withName, fromBody) => `/* Wrapped ${withName}*/\n${fromBody}`;

const toStringDescriptor = Object.getOwnPropertyDescriptor(Function.prototype, 'toString');
const toStringName = Object.getOwnPropertyDescriptor(Function.prototype.toString, 'name');

// We call `from.toString()` early (not lazily) to ensure `from` can be garbage collected.
// We use `bind()` instead of a closure for the same reason.
// Calling `from.toString()` early also allows caching it in case `to.toString()` is called several times.
const changeToString = (to, from, name) => {
	const withName = name === '' ? '' : `with ${name.trim()}() `;
	const newToString = wrappedToString.bind(null, withName, from.toString());
	// Ensure `to.toString.toString` is non-enumerable and has the same `same`
	Object.defineProperty(newToString, 'name', toStringName);
	const {writable, enumerable, configurable} = toStringDescriptor; // We destructue to avoid a potential `get` descriptor.
	Object.defineProperty(to, 'toString', {value: newToString, writable, enumerable, configurable});
};

export default function mimicFunction(to, from, {ignoreNonConfigurable = false} = {}) {
	const {name} = to;

	for (const property of Reflect.ownKeys(from)) {
		copyProperty(to, from, property, ignoreNonConfigurable);
	}

	changePrototype(to, from);
	changeToString(to, from, name);

	return to;
}


mimic-function

description: Make a function mimic another one

repository: sindresorhus/mimic-function

type: module


code:
<picture>
	<source media="(prefers-color-scheme: dark)" srcset="media/logo_dark.svg">

</picture>

> Make a function mimic another one

Useful when you wrap a function in another function and you would like to preserve the original name and other properties.

## Install

```sh
npm install mimic-function
```

## Usage

```js
import mimicFunction from 'mimic-function';

function foo() {}
foo.unicorn = '🦄';

function wrapper() {
	return foo();
}

console.log(wrapper.name);
//=> 'wrapper'

mimicFunction(wrapper, foo);

console.log(wrapper.name);
//=> 'foo'

console.log(wrapper.unicorn);
//=> '🦄'

console.log(String(wrapper));
//=> '/* Wrapped with wrapper() */\nfunction foo() {}'
```

## API

### mimicFunction(to, from, options?)

Modifies the `to` function to mimic the `from` function. Returns the `to` function.

`name`, `displayName`, and any other properties of `from` are copied. The `length` property is not copied. Prototype, class, and inherited properties are copied.

`to.toString()` will return the same as `from.toString()` but prepended with a `Wrapped with to()` comment.

#### to

Type: `Function`

Mimicking function.

#### from

Type: `Function`

Function to mimic.

#### options

Type: `object`

##### ignoreNonConfigurable

Type: `boolean`\
Default: `false`

Skip modifying [non-configurable properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor#Description) instead of throwing an error.

## Related

- [rename-fn](https://github.com/sindresorhus/rename-fn) - Rename a function
- [keep-func-props](https://github.com/ehmicky/keep-func-props) - Wrap a function without changing its name and other properties