index.js 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. 'use strict';
  2. const escapeStringRegexp = require('escape-string-regexp');
  3. const reCache = new Map();
  4. function makeRe(pattern, options) {
  5. const opts = Object.assign({
  6. caseSensitive: false
  7. }, options);
  8. const cacheKey = pattern + JSON.stringify(opts);
  9. if (reCache.has(cacheKey)) {
  10. return reCache.get(cacheKey);
  11. }
  12. const negated = pattern[0] === '!';
  13. if (negated) {
  14. pattern = pattern.slice(1);
  15. }
  16. pattern = escapeStringRegexp(pattern).replace(/\\\*/g, '.*');
  17. const re = new RegExp(`^${pattern}$`, opts.caseSensitive ? '' : 'i');
  18. re.negated = negated;
  19. reCache.set(cacheKey, re);
  20. return re;
  21. }
  22. module.exports = (inputs, patterns, options) => {
  23. if (!(Array.isArray(inputs) && Array.isArray(patterns))) {
  24. throw new TypeError(`Expected two arrays, got ${typeof inputs} ${typeof patterns}`);
  25. }
  26. if (patterns.length === 0) {
  27. return inputs;
  28. }
  29. const firstNegated = patterns[0][0] === '!';
  30. patterns = patterns.map(x => makeRe(x, options));
  31. const ret = [];
  32. for (const input of inputs) {
  33. // If first pattern is negated we include everything to match user expectation
  34. let matches = firstNegated;
  35. for (const pattern of patterns) {
  36. if (pattern.test(input)) {
  37. matches = !pattern.negated;
  38. }
  39. }
  40. if (matches) {
  41. ret.push(input);
  42. }
  43. }
  44. return ret;
  45. };
  46. module.exports.isMatch = (input, pattern, options) => {
  47. const re = makeRe(pattern, options);
  48. const matches = re.test(input);
  49. return re.negated ? !matches : matches;
  50. };