| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466 | 'use strict';var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }// A simple implementation of make-arrayfunction make_array(subject) {  return Array.isArray(subject) ? subject : [subject];}var REGEX_BLANK_LINE = /^\s+$/;var REGEX_LEADING_EXCAPED_EXCLAMATION = /^\\!/;var REGEX_LEADING_EXCAPED_HASH = /^\\#/;var SLASH = '/';var KEY_IGNORE = typeof Symbol !== 'undefined' ? Symbol.for('node-ignore')/* istanbul ignore next */: 'node-ignore';var define = function define(object, key, value) {  return Object.defineProperty(object, key, { value });};var REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g;// Sanitize the range of a regular expression// The cases are complicated, see test cases for detailsvar sanitizeRange = function sanitizeRange(range) {  return range.replace(REGEX_REGEXP_RANGE, function (match, from, to) {    return from.charCodeAt(0) <= to.charCodeAt(0) ? match    // Invalid range (out of order) which is ok for gitignore rules but    //   fatal for JavaScript regular expression, so eliminate it.    : '';  });};// > If the pattern ends with a slash,// > it is removed for the purpose of the following description,// > but it would only find a match with a directory.// > In other words, foo/ will match a directory foo and paths underneath it,// > but will not match a regular file or a symbolic link foo// >  (this is consistent with the way how pathspec works in general in Git).// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`'// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call//      you could use option `mark: true` with `glob`// '`foo/`' should not continue with the '`..`'var DEFAULT_REPLACER_PREFIX = [// > Trailing spaces are ignored unless they are quoted with backslash ("\")[// (a\ ) -> (a )// (a  ) -> (a)// (a \ ) -> (a  )/\\?\s+$/, function (match) {  return match.indexOf('\\') === 0 ? ' ' : '';}],// replace (\ ) with ' '[/\\\s/g, function () {  return ' ';}],// Escape metacharacters// which is written down by users but means special for regular expressions.// > There are 12 characters with special meanings:// > - the backslash \,// > - the caret ^,// > - the dollar sign $,// > - the period or dot .,// > - the vertical bar or pipe symbol |,// > - the question mark ?,// > - the asterisk or star *,// > - the plus sign +,// > - the opening parenthesis (,// > - the closing parenthesis ),// > - and the opening square bracket [,// > - the opening curly brace {,// > These special characters are often called "metacharacters".[/[\\^$.|*+(){]/g, function (match) {  return `\\${match}`;}], [// > [abc] matches any character inside the brackets// >    (in this case a, b, or c);/\[([^\]/]*)($|\])/g, function (match, p1, p2) {  return p2 === ']' ? `[${sanitizeRange(p1)}]` : `\\${match}`;}], [// > a question mark (?) matches a single character/(?!\\)\?/g, function () {  return '[^/]';}],// leading slash[// > A leading slash matches the beginning of the pathname.// > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".// A leading slash matches the beginning of the pathname/^\//, function () {  return '^';}],// replace special metacharacter slash after the leading slash[/\//g, function () {  return '\\/';}], [// > A leading "**" followed by a slash means match in all directories.// > For example, "**/foo" matches file or directory "foo" anywhere,// > the same as pattern "foo".// > "**/foo/bar" matches file or directory "bar" anywhere that is directly// >   under directory "foo".// Notice that the '*'s have been replaced as '\\*'/^\^*\\\*\\\*\\\//,// '**/foo' <-> 'foo'function () {  return '^(?:.*\\/)?';}]];var DEFAULT_REPLACER_SUFFIX = [// starting[// there will be no leading '/'//   (which has been replaced by section "leading slash")// If starts with '**', adding a '^' to the regular expression also works/^(?=[^^])/, function startingReplacer() {  return !/\/(?!$)/.test(this)  // > If the pattern does not contain a slash /,  // >   Git treats it as a shell glob pattern  // Actually, if there is only a trailing slash,  //   git also treats it as a shell glob pattern  ? '(?:^|\\/)'  // > Otherwise, Git treats the pattern as a shell glob suitable for  // >   consumption by fnmatch(3)  : '^';}],// two globstars[// Use lookahead assertions so that we could match more than one `'/**'`/\\\/\\\*\\\*(?=\\\/|$)/g,// Zero, one or several directories// should not use '*', or it will be replaced by the next replacer// Check if it is not the last `'/**'`function (match, index, str) {  return index + 6 < str.length  // case: /**/  // > A slash followed by two consecutive asterisks then a slash matches  // >   zero or more directories.  // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.  // '/**/'  ? '(?:\\/[^\\/]+)*'  // case: /**  // > A trailing `"/**"` matches everything inside.  // #21: everything inside but it should not include the current folder  : '\\/.+';}],// intermediate wildcards[// Never replace escaped '*'// ignore rule '\*' will match the path '*'// 'abc.*/' -> go// 'abc.*'  -> skip this rule/(^|[^\\]+)\\\*(?=.+)/g,// '*.js' matches '.js'// '*.js' doesn't match 'abc'function (match, p1) {  return `${p1}[^\\/]*`;}],// trailing wildcard[/(\^|\\\/)?\\\*$/, function (match, p1) {  var prefix = p1  // '\^':  // '/*' does not match ''  // '/*' does not match everything  // '\\\/':  // 'abc/*' does not match 'abc/'  ? `${p1}[^/]+`  // 'a*' matches 'a'  // 'a*' matches 'aa'  : '[^/]*';  return `${prefix}(?=$|\\/$)`;}], [// unescape/\\\\\\/g, function () {  return '\\';}]];var POSITIVE_REPLACERS = [].concat(DEFAULT_REPLACER_PREFIX, [// 'f'// matches// - /f(end)// - /f/// - (start)f(end)// - (start)f/// doesn't match// - oof// - foo// pseudo:// -> (^|/)f(/|$)// ending[// 'js' will not match 'js.'// 'ab' will not match 'abc'/(?:[^*/])$/,// 'js*' will not match 'a.js'// 'js/' will not match 'a.js'// 'js' will match 'a.js' and 'a.js/'function (match) {  return `${match}(?=$|\\/)`;}]], DEFAULT_REPLACER_SUFFIX);var NEGATIVE_REPLACERS = [].concat(DEFAULT_REPLACER_PREFIX, [// #24, #38// The MISSING rule of [gitignore docs](https://git-scm.com/docs/gitignore)// A negative pattern without a trailing wildcard should not// re-include the things inside that directory.// eg:// ['node_modules/*', '!node_modules']// should ignore `node_modules/a.js`[/(?:[^*])$/, function (match) {  return `${match}(?=$|\\/$)`;}]], DEFAULT_REPLACER_SUFFIX);// A simple cache, because an ignore rule only has only one certain meaningvar cache = Object.create(null);// @param {pattern}var make_regex = function make_regex(pattern, negative, ignorecase) {  var r = cache[pattern];  if (r) {    return r;  }  var replacers = negative ? NEGATIVE_REPLACERS : POSITIVE_REPLACERS;  var source = replacers.reduce(function (prev, current) {    return prev.replace(current[0], current[1].bind(pattern));  }, pattern);  return cache[pattern] = ignorecase ? new RegExp(source, 'i') : new RegExp(source);};// > A blank line matches no files, so it can serve as a separator for readability.var checkPattern = function checkPattern(pattern) {  return pattern && typeof pattern === 'string' && !REGEX_BLANK_LINE.test(pattern)  // > A line starting with # serves as a comment.  && pattern.indexOf('#') !== 0;};var createRule = function createRule(pattern, ignorecase) {  var origin = pattern;  var negative = false;  // > An optional prefix "!" which negates the pattern;  if (pattern.indexOf('!') === 0) {    negative = true;    pattern = pattern.substr(1);  }  pattern = pattern  // > Put a backslash ("\") in front of the first "!" for patterns that  // >   begin with a literal "!", for example, `"\!important!.txt"`.  .replace(REGEX_LEADING_EXCAPED_EXCLAMATION, '!')  // > Put a backslash ("\") in front of the first hash for patterns that  // >   begin with a hash.  .replace(REGEX_LEADING_EXCAPED_HASH, '#');  var regex = make_regex(pattern, negative, ignorecase);  return {    origin,    pattern,    negative,    regex  };};var IgnoreBase = function () {  function IgnoreBase() {    var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},        _ref$ignorecase = _ref.ignorecase,        ignorecase = _ref$ignorecase === undefined ? true : _ref$ignorecase;    _classCallCheck(this, IgnoreBase);    this._rules = [];    this._ignorecase = ignorecase;    define(this, KEY_IGNORE, true);    this._initCache();  }  _createClass(IgnoreBase, [{    key: '_initCache',    value: function _initCache() {      this._cache = Object.create(null);    }    // @param {Array.<string>|string|Ignore} pattern  }, {    key: 'add',    value: function add(pattern) {      this._added = false;      if (typeof pattern === 'string') {        pattern = pattern.split(/\r?\n/g);      }      make_array(pattern).forEach(this._addPattern, this);      // Some rules have just added to the ignore,      // making the behavior changed.      if (this._added) {        this._initCache();      }      return this;    }    // legacy  }, {    key: 'addPattern',    value: function addPattern(pattern) {      return this.add(pattern);    }  }, {    key: '_addPattern',    value: function _addPattern(pattern) {      // #32      if (pattern && pattern[KEY_IGNORE]) {        this._rules = this._rules.concat(pattern._rules);        this._added = true;        return;      }      if (checkPattern(pattern)) {        var rule = createRule(pattern, this._ignorecase);        this._added = true;        this._rules.push(rule);      }    }  }, {    key: 'filter',    value: function filter(paths) {      var _this = this;      return make_array(paths).filter(function (path) {        return _this._filter(path);      });    }  }, {    key: 'createFilter',    value: function createFilter() {      var _this2 = this;      return function (path) {        return _this2._filter(path);      };    }  }, {    key: 'ignores',    value: function ignores(path) {      return !this._filter(path);    }    // @returns `Boolean` true if the `path` is NOT ignored  }, {    key: '_filter',    value: function _filter(path, slices) {      if (!path) {        return false;      }      if (path in this._cache) {        return this._cache[path];      }      if (!slices) {        // path/to/a.js        // ['path', 'to', 'a.js']        slices = path.split(SLASH);      }      slices.pop();      return this._cache[path] = slices.length      // > It is not possible to re-include a file if a parent directory of      // >   that file is excluded.      // If the path contains a parent directory, check the parent first      ? this._filter(slices.join(SLASH) + SLASH, slices) && this._test(path)      // Or only test the path      : this._test(path);    }    // @returns {Boolean} true if a file is NOT ignored  }, {    key: '_test',    value: function _test(path) {      // Explicitly define variable type by setting matched to `0`      var matched = 0;      this._rules.forEach(function (rule) {        // if matched = true, then we only test negative rules        // if matched = false, then we test non-negative rules        if (!(matched ^ rule.negative)) {          matched = rule.negative ^ rule.regex.test(path);        }      });      return !matched;    }  }]);  return IgnoreBase;}();// Windows// --------------------------------------------------------------/* istanbul ignore if  */if (// Detect `process` so that it can run in browsers.typeof process !== 'undefined' && (process.env && process.env.IGNORE_TEST_WIN32 || process.platform === 'win32')) {  var filter = IgnoreBase.prototype._filter;  /* eslint no-control-regex: "off" */  var make_posix = function make_posix(str) {    return (/^\\\\\?\\/.test(str) || /[^\x00-\x80]+/.test(str) ? str : str.replace(/\\/g, '/')    );  };  IgnoreBase.prototype._filter = function filterWin32(path, slices) {    path = make_posix(path);    return filter.call(this, path, slices);  };}module.exports = function (options) {  return new IgnoreBase(options);};
 |