micromatch 3.1.9 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of micromatch might be problematic. Click here for more details.

package/index.js CHANGED
@@ -1,331 +1,139 @@
1
1
  'use strict';
2
2
 
3
- /**
4
- * Module dependencies
5
- */
6
-
7
- var util = require('util');
8
- var braces = require('braces');
9
- var toRegex = require('to-regex');
10
- var extend = require('extend-shallow');
11
-
12
- /**
13
- * Local dependencies
14
- */
15
-
16
- var compilers = require('./lib/compilers');
17
- var parsers = require('./lib/parsers');
18
- var cache = require('./lib/cache');
19
- var utils = require('./lib/utils');
20
- var MAX_LENGTH = 1024 * 64;
3
+ const util = require('util');
4
+ const braces = require('braces');
5
+ const picomatch = require('picomatch');
6
+ const utils = require('picomatch/lib/utils');
7
+ const isEmptyString = val => typeof val === 'string' && (val === '' || val === './');
21
8
 
22
9
  /**
23
- * The main function takes a list of strings and one or more
24
- * glob patterns to use for matching.
10
+ * Returns an array of strings that match one or more glob patterns.
25
11
  *
26
12
  * ```js
27
- * var mm = require('micromatch');
28
- * mm(list, patterns[, options]);
13
+ * const mm = require('micromatch');
14
+ * // mm(list, patterns[, options]);
29
15
  *
30
16
  * console.log(mm(['a.js', 'a.txt'], ['*.js']));
31
17
  * //=> [ 'a.js' ]
32
18
  * ```
33
- * @param {Array} `list` A list of strings to match
34
- * @param {String|Array} `patterns` One or more glob patterns to use for matching.
35
- * @param {Object} `options` See available [options](#options) for changing how matches are performed
19
+ * @param {String|Array<string>} list List of strings to match.
20
+ * @param {String|Array<string>} patterns One or more glob patterns to use for matching.
21
+ * @param {Object} options See available [options](#options)
36
22
  * @return {Array} Returns an array of matches
37
23
  * @summary false
38
24
  * @api public
39
25
  */
40
26
 
41
- function micromatch(list, patterns, options) {
42
- patterns = utils.arrayify(patterns);
43
- list = utils.arrayify(list);
27
+ const micromatch = (list, patterns, options) => {
28
+ patterns = [].concat(patterns);
29
+ list = [].concat(list);
44
30
 
45
- var len = patterns.length;
46
- if (list.length === 0 || len === 0) {
47
- return [];
48
- }
49
-
50
- if (len === 1) {
51
- return micromatch.match(list, patterns[0], options);
52
- }
53
-
54
- var omit = [];
55
- var keep = [];
56
- var idx = -1;
57
-
58
- while (++idx < len) {
59
- var pattern = patterns[idx];
31
+ let omit = new Set();
32
+ let keep = new Set();
33
+ let items = new Set();
34
+ let negatives = 0;
60
35
 
61
- if (typeof pattern === 'string' && pattern.charCodeAt(0) === 33 /* ! */) {
62
- omit.push.apply(omit, micromatch.match(list, pattern.slice(1), options));
63
- } else {
64
- keep.push.apply(keep, micromatch.match(list, pattern, options));
36
+ let onResult = state => {
37
+ items.add(state.output);
38
+ if (options && options.onResult) {
39
+ options.onResult(state);
65
40
  }
66
- }
67
-
68
- var matches = utils.diff(keep, omit);
69
- if (!options || options.nodupes !== false) {
70
- return utils.unique(matches);
71
- }
72
-
73
- return matches;
74
- }
41
+ };
75
42
 
76
- /**
77
- * Similar to the main function, but `pattern` must be a string.
78
- *
79
- * ```js
80
- * var mm = require('micromatch');
81
- * mm.match(list, pattern[, options]);
82
- *
83
- * console.log(mm.match(['a.a', 'a.aa', 'a.b', 'a.c'], '*.a'));
84
- * //=> ['a.a', 'a.aa']
85
- * ```
86
- * @param {Array} `list` Array of strings to match
87
- * @param {String} `pattern` Glob pattern to use for matching.
88
- * @param {Object} `options` See available [options](#options) for changing how matches are performed
89
- * @return {Array} Returns an array of matches
90
- * @api public
91
- */
43
+ for (let i = 0; i < patterns.length; i++) {
44
+ let isMatch = picomatch(String(patterns[i]), { ...options, onResult }, true);
45
+ let negated = isMatch.state.negated || isMatch.state.negatedExtglob;
46
+ if (negated) negatives++;
92
47
 
93
- micromatch.match = function(list, pattern, options) {
94
- if (Array.isArray(pattern)) {
95
- throw new TypeError('expected pattern to be a string');
96
- }
97
-
98
- var unixify = utils.unixify(options);
99
- var isMatch = memoize('match', pattern, options, micromatch.matcher);
100
- var matches = [];
48
+ for (let item of list) {
49
+ let matched = isMatch(item, true);
101
50
 
102
- list = utils.arrayify(list);
103
- var len = list.length;
104
- var idx = -1;
51
+ let match = negated ? !matched.isMatch : matched.isMatch;
52
+ if (!match) continue;
105
53
 
106
- while (++idx < len) {
107
- var ele = list[idx];
108
- if (ele === pattern || isMatch(ele)) {
109
- matches.push(utils.value(ele, unixify, options));
54
+ if (negated) {
55
+ omit.add(matched.output);
56
+ } else {
57
+ omit.delete(matched.output);
58
+ keep.add(matched.output);
59
+ }
110
60
  }
111
61
  }
112
62
 
113
- // if no options were passed, uniquify results and return
114
- if (typeof options === 'undefined') {
115
- return utils.unique(matches);
116
- }
63
+ let result = negatives === patterns.length ? [...items] : [...keep];
64
+ let matches = result.filter(item => !omit.has(item));
117
65
 
118
- if (matches.length === 0) {
66
+ if (options && matches.length === 0) {
119
67
  if (options.failglob === true) {
120
- throw new Error('no matches found for "' + pattern + '"');
68
+ throw new Error(`No matches found for "${patterns.join(', ')}"`);
121
69
  }
70
+
122
71
  if (options.nonull === true || options.nullglob === true) {
123
- return [options.unescape ? utils.unescape(pattern) : pattern];
72
+ return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns;
124
73
  }
125
74
  }
126
75
 
127
- // if `opts.ignore` was defined, diff ignored list
128
- if (options.ignore) {
129
- matches = micromatch.not(matches, options.ignore, options);
130
- }
131
-
132
- return options.nodupes !== false ? utils.unique(matches) : matches;
133
- };
134
-
135
- /**
136
- * Returns true if the specified `string` matches the given glob `pattern`.
137
- *
138
- * ```js
139
- * var mm = require('micromatch');
140
- * mm.isMatch(string, pattern[, options]);
141
- *
142
- * console.log(mm.isMatch('a.a', '*.a'));
143
- * //=> true
144
- * console.log(mm.isMatch('a.b', '*.a'));
145
- * //=> false
146
- * ```
147
- * @param {String} `string` String to match
148
- * @param {String} `pattern` Glob pattern to use for matching.
149
- * @param {Object} `options` See available [options](#options) for changing how matches are performed
150
- * @return {Boolean} Returns true if the string matches the glob pattern.
151
- * @api public
152
- */
153
-
154
- micromatch.isMatch = function(str, pattern, options) {
155
- if (typeof str !== 'string') {
156
- throw new TypeError('expected a string: "' + util.inspect(str) + '"');
157
- }
158
-
159
- if (isEmptyString(str) || isEmptyString(pattern)) {
160
- return false;
161
- }
162
-
163
- var equals = utils.equalsPattern(options);
164
- if (equals(str)) {
165
- return true;
166
- }
167
-
168
- var isMatch = memoize('isMatch', pattern, options, micromatch.matcher);
169
- return isMatch(str);
76
+ return matches;
170
77
  };
171
78
 
172
79
  /**
173
- * Returns true if some of the strings in the given `list` match any of the
174
- * given glob `patterns`.
175
- *
176
- * ```js
177
- * var mm = require('micromatch');
178
- * mm.some(list, patterns[, options]);
179
- *
180
- * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js']));
181
- * // true
182
- * console.log(mm.some(['foo.js'], ['*.js', '!foo.js']));
183
- * // false
184
- * ```
185
- * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found.
186
- * @param {String|Array} `patterns` One or more glob patterns to use for matching.
187
- * @param {Object} `options` See available [options](#options) for changing how matches are performed
188
- * @return {Boolean} Returns true if any patterns match `str`
189
- * @api public
80
+ * Backwards compatibility
190
81
  */
191
82
 
192
- micromatch.some = function(list, patterns, options) {
193
- if (typeof list === 'string') {
194
- list = [list];
195
- }
196
- for (var i = 0; i < list.length; i++) {
197
- if (micromatch(list[i], patterns, options).length === 1) {
198
- return true;
199
- }
200
- }
201
- return false;
202
- };
83
+ micromatch.match = micromatch;
203
84
 
204
85
  /**
205
- * Returns true if every string in the given `list` matches
206
- * any of the given glob `patterns`.
86
+ * Returns a matcher function from the given glob `pattern` and `options`.
87
+ * The returned function takes a string to match as its only argument and returns
88
+ * true if the string is a match.
207
89
  *
208
90
  * ```js
209
- * var mm = require('micromatch');
210
- * mm.every(list, patterns[, options]);
91
+ * const mm = require('micromatch');
92
+ * // mm.matcher(pattern[, options]);
211
93
  *
212
- * console.log(mm.every('foo.js', ['foo.js']));
213
- * // true
214
- * console.log(mm.every(['foo.js', 'bar.js'], ['*.js']));
215
- * // true
216
- * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js']));
217
- * // false
218
- * console.log(mm.every(['foo.js'], ['*.js', '!foo.js']));
219
- * // false
94
+ * const isMatch = mm.matcher('*.!(*a)');
95
+ * console.log(isMatch('a.a')); //=> false
96
+ * console.log(isMatch('a.b')); //=> true
220
97
  * ```
221
- * @param {String|Array} `list` The string or array of strings to test.
222
- * @param {String|Array} `patterns` One or more glob patterns to use for matching.
223
- * @param {Object} `options` See available [options](#options) for changing how matches are performed
224
- * @return {Boolean} Returns true if any patterns match `str`
98
+ * @param {String} `pattern` Glob pattern
99
+ * @param {Object} `options`
100
+ * @return {Function} Returns a matcher function.
225
101
  * @api public
226
102
  */
227
103
 
228
- micromatch.every = function(list, patterns, options) {
229
- if (typeof list === 'string') {
230
- list = [list];
231
- }
232
- for (var i = 0; i < list.length; i++) {
233
- if (micromatch(list[i], patterns, options).length !== 1) {
234
- return false;
235
- }
236
- }
237
- return true;
238
- };
104
+ micromatch.matcher = (pattern, options) => picomatch(pattern, options);
239
105
 
240
106
  /**
241
- * Returns true if **any** of the given glob `patterns`
242
- * match the specified `string`.
107
+ * Returns true if **any** of the given glob `patterns` match the specified `string`.
243
108
  *
244
109
  * ```js
245
- * var mm = require('micromatch');
246
- * mm.any(string, patterns[, options]);
110
+ * const mm = require('micromatch');
111
+ * // mm.isMatch(string, patterns[, options]);
247
112
  *
248
- * console.log(mm.any('a.a', ['b.*', '*.a']));
249
- * //=> true
250
- * console.log(mm.any('a.a', 'b.*'));
251
- * //=> false
113
+ * console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true
114
+ * console.log(mm.isMatch('a.a', 'b.*')); //=> false
252
115
  * ```
253
- * @param {String|Array} `str` The string to test.
254
- * @param {String|Array} `patterns` One or more glob patterns to use for matching.
255
- * @param {Object} `options` See available [options](#options) for changing how matches are performed
116
+ * @param {String} str The string to test.
117
+ * @param {String|Array} patterns One or more glob patterns to use for matching.
118
+ * @param {Object} [options] See available [options](#options).
256
119
  * @return {Boolean} Returns true if any patterns match `str`
257
120
  * @api public
258
121
  */
259
122
 
260
- micromatch.any = function(str, patterns, options) {
261
- if (typeof str !== 'string') {
262
- throw new TypeError('expected a string: "' + util.inspect(str) + '"');
263
- }
264
-
265
- if (isEmptyString(str) || isEmptyString(patterns)) {
266
- return false;
267
- }
268
-
269
- if (typeof patterns === 'string') {
270
- patterns = [patterns];
271
- }
272
-
273
- for (var i = 0; i < patterns.length; i++) {
274
- if (micromatch.isMatch(str, patterns[i], options)) {
275
- return true;
276
- }
277
- }
278
- return false;
279
- };
123
+ micromatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
280
124
 
281
125
  /**
282
- * Returns true if **all** of the given `patterns` match
283
- * the specified string.
284
- *
285
- * ```js
286
- * var mm = require('micromatch');
287
- * mm.all(string, patterns[, options]);
288
- *
289
- * console.log(mm.all('foo.js', ['foo.js']));
290
- * // true
291
- *
292
- * console.log(mm.all('foo.js', ['*.js', '!foo.js']));
293
- * // false
294
- *
295
- * console.log(mm.all('foo.js', ['*.js', 'foo.js']));
296
- * // true
297
- *
298
- * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js']));
299
- * // true
300
- * ```
301
- * @param {String|Array} `str` The string to test.
302
- * @param {String|Array} `patterns` One or more glob patterns to use for matching.
303
- * @param {Object} `options` See available [options](#options) for changing how matches are performed
304
- * @return {Boolean} Returns true if any patterns match `str`
305
- * @api public
126
+ * Backwards compatibility
306
127
  */
307
128
 
308
- micromatch.all = function(str, patterns, options) {
309
- if (typeof str !== 'string') {
310
- throw new TypeError('expected a string: "' + util.inspect(str) + '"');
311
- }
312
- if (typeof patterns === 'string') {
313
- patterns = [patterns];
314
- }
315
- for (var i = 0; i < patterns.length; i++) {
316
- if (!micromatch.isMatch(str, patterns[i], options)) {
317
- return false;
318
- }
319
- }
320
- return true;
321
- };
129
+ micromatch.any = micromatch.isMatch;
322
130
 
323
131
  /**
324
132
  * Returns a list of strings that _**do not match any**_ of the given `patterns`.
325
133
  *
326
134
  * ```js
327
- * var mm = require('micromatch');
328
- * mm.not(list, patterns[, options]);
135
+ * const mm = require('micromatch');
136
+ * // mm.not(list, patterns[, options]);
329
137
  *
330
138
  * console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a'));
331
139
  * //=> ['b.b', 'c.c']
@@ -337,20 +145,24 @@ micromatch.all = function(str, patterns, options) {
337
145
  * @api public
338
146
  */
339
147
 
340
- micromatch.not = function(list, patterns, options) {
341
- var opts = extend({}, options);
342
- var ignore = opts.ignore;
343
- delete opts.ignore;
148
+ micromatch.not = (list, patterns, options = {}) => {
149
+ patterns = [].concat(patterns).map(String);
150
+ let result = new Set();
151
+ let items = [];
344
152
 
345
- var unixify = utils.unixify(opts);
346
- list = utils.arrayify(list).map(unixify);
153
+ let onResult = state => {
154
+ if (options.onResult) options.onResult(state);
155
+ items.push(state.output);
156
+ };
347
157
 
348
- var matches = utils.diff(list, micromatch(list, patterns, opts));
349
- if (ignore) {
350
- matches = utils.diff(matches, micromatch(list, ignore));
351
- }
158
+ let matches = micromatch(list, patterns, { ...options, onResult });
352
159
 
353
- return opts.nodupes !== false ? utils.unique(matches) : matches;
160
+ for (let item of items) {
161
+ if (!matches.includes(item)) {
162
+ result.add(item);
163
+ }
164
+ }
165
+ return [...result];
354
166
  };
355
167
 
356
168
  /**
@@ -359,7 +171,7 @@ micromatch.not = function(list, patterns, options) {
359
171
  *
360
172
  * ```js
361
173
  * var mm = require('micromatch');
362
- * mm.contains(string, pattern[, options]);
174
+ * // mm.contains(string, pattern[, options]);
363
175
  *
364
176
  * console.log(mm.contains('aa/bb/cc', '*b'));
365
177
  * //=> true
@@ -373,40 +185,26 @@ micromatch.not = function(list, patterns, options) {
373
185
  * @api public
374
186
  */
375
187
 
376
- micromatch.contains = function(str, patterns, options) {
188
+ micromatch.contains = (str, pattern, options) => {
377
189
  if (typeof str !== 'string') {
378
- throw new TypeError('expected a string: "' + util.inspect(str) + '"');
190
+ throw new TypeError(`Expected a string: "${util.inspect(str)}"`);
379
191
  }
380
192
 
381
- if (typeof patterns === 'string') {
382
- if (isEmptyString(str) || isEmptyString(patterns)) {
193
+ if (Array.isArray(pattern)) {
194
+ return pattern.some(p => micromatch.contains(str, p, options));
195
+ }
196
+
197
+ if (typeof pattern === 'string') {
198
+ if (isEmptyString(str) || isEmptyString(pattern)) {
383
199
  return false;
384
200
  }
385
201
 
386
- var equals = utils.equalsPattern(patterns, options);
387
- if (equals(str)) {
388
- return true;
389
- }
390
- var contains = utils.containsPattern(patterns, options);
391
- if (contains(str)) {
202
+ if (str.includes(pattern) || (str.startsWith('./') && str.slice(2).includes(pattern))) {
392
203
  return true;
393
204
  }
394
205
  }
395
206
 
396
- var opts = extend({}, options, {contains: true});
397
- return micromatch.any(str, patterns, opts);
398
- };
399
-
400
- /**
401
- * Returns true if the given pattern and options should enable
402
- * the `matchBase` option.
403
- * @return {Boolean}
404
- * @api private
405
- */
406
-
407
- micromatch.matchBase = function(pattern, options) {
408
- if (pattern && pattern.indexOf('/') !== -1 || !options) return false;
409
- return options.basename === true || options.matchBase === true;
207
+ return micromatch.isMatch(str, pattern, { ...options, contains: true });
410
208
  };
411
209
 
412
210
  /**
@@ -415,10 +213,10 @@ micromatch.matchBase = function(pattern, options) {
415
213
  * use [glob-object][] instead.
416
214
  *
417
215
  * ```js
418
- * var mm = require('micromatch');
419
- * mm.matchKeys(object, patterns[, options]);
216
+ * const mm = require('micromatch');
217
+ * // mm.matchKeys(object, patterns[, options]);
420
218
  *
421
- * var obj = { aa: 'a', ab: 'b', ac: 'c' };
219
+ * const obj = { aa: 'a', ab: 'b', ac: 'c' };
422
220
  * console.log(mm.matchKeys(obj, '*b'));
423
221
  * //=> { ab: 'b' }
424
222
  * ```
@@ -429,449 +227,241 @@ micromatch.matchBase = function(pattern, options) {
429
227
  * @api public
430
228
  */
431
229
 
432
- micromatch.matchKeys = function(obj, patterns, options) {
230
+ micromatch.matchKeys = (obj, patterns, options) => {
433
231
  if (!utils.isObject(obj)) {
434
- throw new TypeError('expected the first argument to be an object');
232
+ throw new TypeError('Expected the first argument to be an object');
435
233
  }
436
- var keys = micromatch(Object.keys(obj), patterns, options);
437
- return utils.pick(obj, keys);
234
+ let keys = micromatch(Object.keys(obj), patterns, options);
235
+ let res = {};
236
+ for (let key of keys) res[key] = obj[key];
237
+ return res;
438
238
  };
439
239
 
440
240
  /**
441
- * Returns a memoized matcher function from the given glob `pattern` and `options`.
442
- * The returned function takes a string to match as its only argument and returns
443
- * true if the string is a match.
241
+ * Returns true if some of the strings in the given `list` match any of the given glob `patterns`.
444
242
  *
445
243
  * ```js
446
- * var mm = require('micromatch');
447
- * mm.matcher(pattern[, options]);
244
+ * const mm = require('micromatch');
245
+ * // mm.some(list, patterns[, options]);
448
246
  *
449
- * var isMatch = mm.matcher('*.!(*a)');
450
- * console.log(isMatch('a.a'));
451
- * //=> false
452
- * console.log(isMatch('a.b'));
453
- * //=> true
247
+ * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js']));
248
+ * // true
249
+ * console.log(mm.some(['foo.js'], ['*.js', '!foo.js']));
250
+ * // false
454
251
  * ```
455
- * @param {String} `pattern` Glob pattern
456
- * @param {Object} `options` See available [options](#options) for changing how matches are performed.
457
- * @return {Function} Returns a matcher function.
252
+ * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found.
253
+ * @param {String|Array} `patterns` One or more glob patterns to use for matching.
254
+ * @param {Object} `options` See available [options](#options) for changing how matches are performed
255
+ * @return {Boolean} Returns true if any patterns match `str`
458
256
  * @api public
459
257
  */
460
258
 
461
- micromatch.matcher = function matcher(pattern, options) {
462
- if (Array.isArray(pattern)) {
463
- return compose(pattern, options, matcher);
464
- }
465
-
466
- // if pattern is a regex
467
- if (pattern instanceof RegExp) {
468
- return test(pattern);
469
- }
470
-
471
- // if pattern is invalid
472
- if (!utils.isString(pattern)) {
473
- throw new TypeError('expected pattern to be an array, string or regex');
474
- }
259
+ micromatch.some = (list, patterns, options) => {
260
+ let items = [].concat(list);
475
261
 
476
- // if pattern is a non-glob string
477
- if (!utils.hasSpecialChars(pattern)) {
478
- if (options && options.nocase === true) {
479
- pattern = pattern.toLowerCase();
262
+ for (let pattern of [].concat(patterns)) {
263
+ let isMatch = picomatch(String(pattern), options);
264
+ if (items.some(item => isMatch(item))) {
265
+ return true;
480
266
  }
481
- return utils.matchPath(pattern, options);
482
- }
483
-
484
- // if pattern is a glob string
485
- var re = micromatch.makeRe(pattern, options);
486
-
487
- // if `options.matchBase` or `options.basename` is defined
488
- if (micromatch.matchBase(pattern, options)) {
489
- return utils.matchBasename(re, options);
490
- }
491
-
492
- function test(regex) {
493
- var equals = utils.equalsPattern(options);
494
- var unixify = utils.unixify(options);
495
-
496
- return function(str) {
497
- if (equals(str)) {
498
- return true;
499
- }
500
-
501
- if (regex.test(unixify(str))) {
502
- return true;
503
- }
504
- return false;
505
- };
506
267
  }
507
-
508
- var fn = test(re);
509
- Object.defineProperty(fn, 'result', {
510
- configurable: true,
511
- enumerable: false,
512
- value: re.result
513
- });
514
- return fn;
268
+ return false;
515
269
  };
516
270
 
517
271
  /**
518
- * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match.
272
+ * Returns true if every string in the given `list` matches
273
+ * any of the given glob `patterns`.
519
274
  *
520
275
  * ```js
521
- * var mm = require('micromatch');
522
- * mm.capture(pattern, string[, options]);
276
+ * const mm = require('micromatch');
277
+ * // mm.every(list, patterns[, options]);
523
278
  *
524
- * console.log(mm.capture('test/*.js', 'test/foo.js'));
525
- * //=> ['foo']
526
- * console.log(mm.capture('test/*.js', 'foo/bar.css'));
527
- * //=> null
279
+ * console.log(mm.every('foo.js', ['foo.js']));
280
+ * // true
281
+ * console.log(mm.every(['foo.js', 'bar.js'], ['*.js']));
282
+ * // true
283
+ * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js']));
284
+ * // false
285
+ * console.log(mm.every(['foo.js'], ['*.js', '!foo.js']));
286
+ * // false
528
287
  * ```
529
- * @param {String} `pattern` Glob pattern to use for matching.
530
- * @param {String} `string` String to match
288
+ * @param {String|Array} `list` The string or array of strings to test.
289
+ * @param {String|Array} `patterns` One or more glob patterns to use for matching.
531
290
  * @param {Object} `options` See available [options](#options) for changing how matches are performed
532
- * @return {Boolean} Returns an array of captures if the string matches the glob pattern, otherwise `null`.
291
+ * @return {Boolean} Returns true if any patterns match `str`
533
292
  * @api public
534
293
  */
535
294
 
536
- micromatch.capture = function(pattern, str, options) {
537
- var re = micromatch.makeRe(pattern, extend({capture: true}, options));
538
- var unixify = utils.unixify(options);
539
-
540
- function match() {
541
- return function(string) {
542
- var match = re.exec(unixify(string));
543
- if (!match) {
544
- return null;
545
- }
295
+ micromatch.every = (list, patterns, options) => {
296
+ let items = [].concat(list);
546
297
 
547
- return match.slice(1);
548
- };
298
+ for (let pattern of [].concat(patterns)) {
299
+ let isMatch = picomatch(String(pattern), options);
300
+ if (!items.every(item => isMatch(item))) {
301
+ return false;
302
+ }
549
303
  }
550
-
551
- var capture = memoize('capture', pattern, options, match);
552
- return capture(str);
304
+ return true;
553
305
  };
554
306
 
555
307
  /**
556
- * Create a regular expression from the given glob `pattern`.
308
+ * Returns true if **all** of the given `patterns` match
309
+ * the specified string.
557
310
  *
558
311
  * ```js
559
- * var mm = require('micromatch');
560
- * mm.makeRe(pattern[, options]);
312
+ * const mm = require('micromatch');
313
+ * // mm.all(string, patterns[, options]);
561
314
  *
562
- * console.log(mm.makeRe('*.js'));
563
- * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/
315
+ * console.log(mm.all('foo.js', ['foo.js']));
316
+ * // true
317
+ *
318
+ * console.log(mm.all('foo.js', ['*.js', '!foo.js']));
319
+ * // false
320
+ *
321
+ * console.log(mm.all('foo.js', ['*.js', 'foo.js']));
322
+ * // true
323
+ *
324
+ * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js']));
325
+ * // true
564
326
  * ```
565
- * @param {String} `pattern` A glob pattern to convert to regex.
566
- * @param {Object} `options` See available [options](#options) for changing how matches are performed.
567
- * @return {RegExp} Returns a regex created from the given pattern.
327
+ * @param {String|Array} `str` The string to test.
328
+ * @param {String|Array} `patterns` One or more glob patterns to use for matching.
329
+ * @param {Object} `options` See available [options](#options) for changing how matches are performed
330
+ * @return {Boolean} Returns true if any patterns match `str`
568
331
  * @api public
569
332
  */
570
333
 
571
- micromatch.makeRe = function(pattern, options) {
572
- if (typeof pattern !== 'string') {
573
- throw new TypeError('expected pattern to be a string');
574
- }
575
-
576
- if (pattern.length > MAX_LENGTH) {
577
- throw new Error('expected pattern to be less than ' + MAX_LENGTH + ' characters');
578
- }
579
-
580
- function makeRe() {
581
- var result = micromatch.create(pattern, options);
582
- var ast_array = [];
583
- var output = result.map(function(obj) {
584
- obj.ast.state = obj.state;
585
- ast_array.push(obj.ast);
586
- return obj.output;
587
- });
588
-
589
- var regex = toRegex(output.join('|'), options);
590
- Object.defineProperty(regex, 'result', {
591
- configurable: true,
592
- enumerable: false,
593
- value: ast_array
594
- });
595
- return regex;
334
+ micromatch.all = (str, patterns, options) => {
335
+ if (typeof str !== 'string') {
336
+ throw new TypeError(`Expected a string: "${util.inspect(str)}"`);
596
337
  }
597
338
 
598
- return memoize('makeRe', pattern, options, makeRe);
339
+ return [].concat(patterns).every(p => picomatch(p, options)(str));
599
340
  };
600
341
 
601
342
  /**
602
- * Expand the given brace `pattern`.
343
+ * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match.
603
344
  *
604
345
  * ```js
605
- * var mm = require('micromatch');
606
- * console.log(mm.braces('foo/{a,b}/bar'));
607
- * //=> ['foo/(a|b)/bar']
346
+ * const mm = require('micromatch');
347
+ * // mm.capture(pattern, string[, options]);
608
348
  *
609
- * console.log(mm.braces('foo/{a,b}/bar', {expand: true}));
610
- * //=> ['foo/(a|b)/bar']
349
+ * console.log(mm.capture('test/*.js', 'test/foo.js'));
350
+ * //=> ['foo']
351
+ * console.log(mm.capture('test/*.js', 'foo/bar.css'));
352
+ * //=> null
611
353
  * ```
612
- * @param {String} `pattern` String with brace pattern to expand.
613
- * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options.
614
- * @return {Array}
354
+ * @param {String} `glob` Glob pattern to use for matching.
355
+ * @param {String} `input` String to match
356
+ * @param {Object} `options` See available [options](#options) for changing how matches are performed
357
+ * @return {Boolean} Returns an array of captures if the input matches the glob pattern, otherwise `null`.
615
358
  * @api public
616
359
  */
617
360
 
618
- micromatch.braces = function(pattern, options) {
619
- if (typeof pattern !== 'string' && !Array.isArray(pattern)) {
620
- throw new TypeError('expected pattern to be an array or string');
621
- }
361
+ micromatch.capture = (glob, input, options) => {
362
+ let posix = utils.isWindows(options);
363
+ let regex = picomatch.makeRe(String(glob), { ...options, capture: true });
364
+ let match = regex.exec(posix ? utils.toPosixSlashes(input) : input);
622
365
 
623
- function expand() {
624
- if (options && options.nobrace === true || !/\{.*\}/.test(pattern)) {
625
- return utils.arrayify(pattern);
626
- }
627
- return braces(pattern, options);
366
+ if (match) {
367
+ return match.slice(1).map(v => v === void 0 ? '' : v);
628
368
  }
629
-
630
- return memoize('braces', pattern, options, expand);
631
- };
632
-
633
- /**
634
- * Proxy to the [micromatch.braces](#method), for parity with
635
- * minimatch.
636
- */
637
-
638
- micromatch.braceExpand = function(pattern, options) {
639
- var opts = extend({}, options, {expand: true});
640
- return micromatch.braces(pattern, opts);
641
369
  };
642
370
 
643
371
  /**
644
- * Parses the given glob `pattern` and returns an array of abstract syntax
645
- * trees (ASTs), with the compiled `output` and optional source `map` on
646
- * each AST.
372
+ * Create a regular expression from the given glob `pattern`.
647
373
  *
648
374
  * ```js
649
- * var mm = require('micromatch');
650
- * mm.create(pattern[, options]);
375
+ * const mm = require('micromatch');
376
+ * // mm.makeRe(pattern[, options]);
651
377
  *
652
- * console.log(mm.create('abc/*.js'));
653
- * // [{ options: { source: 'string', sourcemap: true },
654
- * // state: {},
655
- * // compilers:
656
- * // { ... },
657
- * // output: '(\\.[\\\\\\/])?abc\\/(?!\\.)(?=.)[^\\/]*?\\.js',
658
- * // ast:
659
- * // { type: 'root',
660
- * // errors: [],
661
- * // nodes:
662
- * // [ ... ],
663
- * // dot: false,
664
- * // input: 'abc/*.js' },
665
- * // parsingErrors: [],
666
- * // map:
667
- * // { version: 3,
668
- * // sources: [ 'string' ],
669
- * // names: [],
670
- * // mappings: 'AAAA,GAAG,EAAC,kBAAC,EAAC,EAAE',
671
- * // sourcesContent: [ 'abc/*.js' ] },
672
- * // position: { line: 1, column: 28 },
673
- * // content: {},
674
- * // files: {},
675
- * // idx: 6 }]
378
+ * console.log(mm.makeRe('*.js'));
379
+ * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/
676
380
  * ```
677
- * @param {String} `pattern` Glob pattern to parse and compile.
678
- * @param {Object} `options` Any [options](#options) to change how parsing and compiling is performed.
679
- * @return {Object} Returns an object with the parsed AST, compiled string and optional source map.
381
+ * @param {String} `pattern` A glob pattern to convert to regex.
382
+ * @param {Object} `options`
383
+ * @return {RegExp} Returns a regex created from the given pattern.
680
384
  * @api public
681
385
  */
682
386
 
683
- micromatch.create = function(pattern, options) {
684
- return memoize('create', pattern, options, function() {
685
- function create(str, opts) {
686
- return micromatch.compile(micromatch.parse(str, opts), opts);
687
- }
688
-
689
- pattern = micromatch.braces(pattern, options);
690
- var len = pattern.length;
691
- var idx = -1;
692
- var res = [];
693
-
694
- while (++idx < len) {
695
- res.push(create(pattern[idx], options));
696
- }
697
- return res;
698
- });
699
- };
387
+ micromatch.makeRe = (...args) => picomatch.makeRe(...args);
700
388
 
701
389
  /**
702
- * Parse the given `str` with the given `options`.
390
+ * Scan a glob pattern to separate the pattern into segments. Used
391
+ * by the [split](#split) method.
703
392
  *
704
393
  * ```js
705
- * var mm = require('micromatch');
706
- * mm.parse(pattern[, options]);
707
- *
708
- * var ast = mm.parse('a/{b,c}/d');
709
- * console.log(ast);
710
- * // { type: 'root',
711
- * // errors: [],
712
- * // input: 'a/{b,c}/d',
713
- * // nodes:
714
- * // [ { type: 'bos', val: '' },
715
- * // { type: 'text', val: 'a/' },
716
- * // { type: 'brace',
717
- * // nodes:
718
- * // [ { type: 'brace.open', val: '{' },
719
- * // { type: 'text', val: 'b,c' },
720
- * // { type: 'brace.close', val: '}' } ] },
721
- * // { type: 'text', val: '/d' },
722
- * // { type: 'eos', val: '' } ] }
394
+ * const mm = require('micromatch');
395
+ * const state = mm.scan(pattern[, options]);
723
396
  * ```
724
- * @param {String} `str`
397
+ * @param {String} `pattern`
725
398
  * @param {Object} `options`
726
- * @return {Object} Returns an AST
399
+ * @return {Object} Returns an object with
727
400
  * @api public
728
401
  */
729
402
 
730
- micromatch.parse = function(pattern, options) {
731
- if (typeof pattern !== 'string') {
732
- throw new TypeError('expected a string');
733
- }
734
-
735
- function parse() {
736
- var snapdragon = utils.instantiate(null, options);
737
- parsers(snapdragon, options);
738
-
739
- var ast = snapdragon.parse(pattern, options);
740
- utils.define(ast, 'snapdragon', snapdragon);
741
- ast.input = pattern;
742
- return ast;
743
- }
744
-
745
- return memoize('parse', pattern, options, parse);
746
- };
403
+ micromatch.scan = (...args) => picomatch.scan(...args);
747
404
 
748
405
  /**
749
- * Compile the given `ast` or string with the given `options`.
406
+ * Parse a glob pattern to create the source string for a regular
407
+ * expression.
750
408
  *
751
409
  * ```js
752
- * var mm = require('micromatch');
753
- * mm.compile(ast[, options]);
754
- *
755
- * var ast = mm.parse('a/{b,c}/d');
756
- * console.log(mm.compile(ast));
757
- * // { options: { source: 'string' },
758
- * // state: {},
759
- * // compilers:
760
- * // { eos: [Function],
761
- * // noop: [Function],
762
- * // bos: [Function],
763
- * // brace: [Function],
764
- * // 'brace.open': [Function],
765
- * // text: [Function],
766
- * // 'brace.close': [Function] },
767
- * // output: [ 'a/(b|c)/d' ],
768
- * // ast:
769
- * // { ... },
770
- * // parsingErrors: [] }
410
+ * const mm = require('micromatch');
411
+ * const state = mm(pattern[, options]);
771
412
  * ```
772
- * @param {Object|String} `ast`
413
+ * @param {String} `glob`
773
414
  * @param {Object} `options`
774
- * @return {Object} Returns an object that has an `output` property with the compiled string.
415
+ * @return {Object} Returns an object with useful properties and output to be used as regex source string.
775
416
  * @api public
776
417
  */
777
418
 
778
- micromatch.compile = function(ast, options) {
779
- if (typeof ast === 'string') {
780
- ast = micromatch.parse(ast, options);
419
+ micromatch.parse = (patterns, options) => {
420
+ let res = [];
421
+ for (let pattern of [].concat(patterns || [])) {
422
+ for (let str of braces(String(pattern), options)) {
423
+ res.push(picomatch.parse(str, options));
424
+ }
781
425
  }
782
-
783
- return memoize('compile', ast.input, options, function() {
784
- var snapdragon = utils.instantiate(ast, options);
785
- compilers(snapdragon, options);
786
- return snapdragon.compile(ast, options);
787
- });
426
+ return res;
788
427
  };
789
428
 
790
429
  /**
791
- * Clear the regex cache.
430
+ * Process the given brace `pattern`.
792
431
  *
793
432
  * ```js
794
- * mm.clearCache();
433
+ * const { braces } = require('micromatch');
434
+ * console.log(braces('foo/{a,b,c}/bar'));
435
+ * //=> [ 'foo/(a|b|c)/bar' ]
436
+ *
437
+ * console.log(braces('foo/{a,b,c}/bar', { expand: true }));
438
+ * //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ]
795
439
  * ```
440
+ * @param {String} `pattern` String with brace pattern to process.
441
+ * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options.
442
+ * @return {Array}
796
443
  * @api public
797
444
  */
798
445
 
799
- micromatch.clearCache = function() {
800
- micromatch.cache.caches = {};
801
- };
802
-
803
- /**
804
- * Returns true if the given value is effectively an empty string
805
- */
806
-
807
- function isEmptyString(val) {
808
- return String(val) === '' || String(val) === './';
809
- }
810
-
811
- /**
812
- * Compose a matcher function with the given patterns.
813
- * This allows matcher functions to be compiled once and
814
- * called multiple times.
815
- */
816
-
817
- function compose(patterns, options, matcher) {
818
- var matchers;
819
-
820
- return memoize('compose', String(patterns), options, function() {
821
- return function(file) {
822
- // delay composition until it's invoked the first time,
823
- // after that it won't be called again
824
- if (!matchers) {
825
- matchers = [];
826
- for (var i = 0; i < patterns.length; i++) {
827
- matchers.push(matcher(patterns[i], options));
828
- }
829
- }
830
-
831
- var len = matchers.length;
832
- while (len--) {
833
- if (matchers[len](file) === true) {
834
- return true;
835
- }
836
- }
837
- return false;
838
- };
839
- });
840
- }
841
-
842
- /**
843
- * Memoize a generated regex or function. A unique key is generated
844
- * from the `type` (usually method name), the `pattern`, and
845
- * user-defined options.
846
- */
847
-
848
- function memoize(type, pattern, options, fn) {
849
- var key = utils.createKey(type + '=' + pattern, options);
850
-
851
- if (options && options.cache === false) {
852
- return fn(pattern, options);
446
+ micromatch.braces = (pattern, options) => {
447
+ if (typeof pattern !== 'string') throw new TypeError('Expected a string');
448
+ if ((options && options.nobrace === true) || !/\{.*\}/.test(pattern)) {
449
+ return [pattern];
853
450
  }
854
-
855
- if (cache.has(type, key)) {
856
- return cache.get(type, key);
857
- }
858
-
859
- var val = fn(pattern, options);
860
- cache.set(type, key, val);
861
- return val;
862
- }
451
+ return braces(pattern, options);
452
+ };
863
453
 
864
454
  /**
865
- * Expose compiler, parser and cache on `micromatch`
455
+ * Expand braces
866
456
  */
867
457
 
868
- micromatch.compilers = compilers;
869
- micromatch.parsers = parsers;
870
- micromatch.caches = cache.caches;
458
+ micromatch.braceExpand = (pattern, options) => {
459
+ if (typeof pattern !== 'string') throw new TypeError('Expected a string');
460
+ return micromatch.braces(pattern, { ...options, expand: true });
461
+ };
871
462
 
872
463
  /**
873
- * Expose `micromatch`
874
- * @type {Function}
464
+ * Expose micromatch
875
465
  */
876
466
 
877
467
  module.exports = micromatch;