UNPKG

190 kBJavaScriptView Raw
1/*
2 @license
3 Rollup.js v2.0.4
4 Thu, 12 Mar 2020 04:44:15 GMT - commit 2895a55872e1735da87c5be5ec9612e3df96c09c
5
6
7 https://github.com/rollup/rollup
8
9 Released under the MIT License.
10*/
11'use strict';
12
13var rollup_js = require('./rollup.js');
14var path = require('path');
15var fs = require('fs');
16require('crypto');
17require('events');
18require('util');
19var _events_commonjsExternal = require('./_events_commonjs-external.js');
20var stream = require('stream');
21var os = require('os');
22
23var utils = rollup_js.createCommonjsModule(function (module, exports) {
24
25exports.isInteger = num => {
26 if (typeof num === 'number') {
27 return Number.isInteger(num);
28 }
29 if (typeof num === 'string' && num.trim() !== '') {
30 return Number.isInteger(Number(num));
31 }
32 return false;
33};
34
35/**
36 * Find a node of the given type
37 */
38
39exports.find = (node, type) => node.nodes.find(node => node.type === type);
40
41/**
42 * Find a node of the given type
43 */
44
45exports.exceedsLimit = (min, max, step = 1, limit) => {
46 if (limit === false) return false;
47 if (!exports.isInteger(min) || !exports.isInteger(max)) return false;
48 return ((Number(max) - Number(min)) / Number(step)) >= limit;
49};
50
51/**
52 * Escape the given node with '\\' before node.value
53 */
54
55exports.escapeNode = (block, n = 0, type) => {
56 let node = block.nodes[n];
57 if (!node) return;
58
59 if ((type && node.type === type) || node.type === 'open' || node.type === 'close') {
60 if (node.escaped !== true) {
61 node.value = '\\' + node.value;
62 node.escaped = true;
63 }
64 }
65};
66
67/**
68 * Returns true if the given brace node should be enclosed in literal braces
69 */
70
71exports.encloseBrace = node => {
72 if (node.type !== 'brace') return false;
73 if ((node.commas >> 0 + node.ranges >> 0) === 0) {
74 node.invalid = true;
75 return true;
76 }
77 return false;
78};
79
80/**
81 * Returns true if a brace node is invalid.
82 */
83
84exports.isInvalidBrace = block => {
85 if (block.type !== 'brace') return false;
86 if (block.invalid === true || block.dollar) return true;
87 if ((block.commas >> 0 + block.ranges >> 0) === 0) {
88 block.invalid = true;
89 return true;
90 }
91 if (block.open !== true || block.close !== true) {
92 block.invalid = true;
93 return true;
94 }
95 return false;
96};
97
98/**
99 * Returns true if a node is an open or close node
100 */
101
102exports.isOpenOrClose = node => {
103 if (node.type === 'open' || node.type === 'close') {
104 return true;
105 }
106 return node.open === true || node.close === true;
107};
108
109/**
110 * Reduce an array of text nodes.
111 */
112
113exports.reduce = nodes => nodes.reduce((acc, node) => {
114 if (node.type === 'text') acc.push(node.value);
115 if (node.type === 'range') node.type = 'text';
116 return acc;
117}, []);
118
119/**
120 * Flatten an array
121 */
122
123exports.flatten = (...args) => {
124 const result = [];
125 const flat = arr => {
126 for (let i = 0; i < arr.length; i++) {
127 let ele = arr[i];
128 Array.isArray(ele) ? flat(ele) : ele !== void 0 && result.push(ele);
129 }
130 return result;
131 };
132 flat(args);
133 return result;
134};
135});
136
137var stringify = (ast, options = {}) => {
138 let stringify = (node, parent = {}) => {
139 let invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent);
140 let invalidNode = node.invalid === true && options.escapeInvalid === true;
141 let output = '';
142
143 if (node.value) {
144 if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) {
145 return '\\' + node.value;
146 }
147 return node.value;
148 }
149
150 if (node.value) {
151 return node.value;
152 }
153
154 if (node.nodes) {
155 for (let child of node.nodes) {
156 output += stringify(child);
157 }
158 }
159 return output;
160 };
161
162 return stringify(ast);
163};
164
165/*!
166 * is-number <https://github.com/jonschlinkert/is-number>
167 *
168 * Copyright (c) 2014-present, Jon Schlinkert.
169 * Released under the MIT License.
170 */
171
172var isNumber = function(num) {
173 if (typeof num === 'number') {
174 return num - num === 0;
175 }
176 if (typeof num === 'string' && num.trim() !== '') {
177 return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
178 }
179 return false;
180};
181
182const toRegexRange = (min, max, options) => {
183 if (isNumber(min) === false) {
184 throw new TypeError('toRegexRange: expected the first argument to be a number');
185 }
186
187 if (max === void 0 || min === max) {
188 return String(min);
189 }
190
191 if (isNumber(max) === false) {
192 throw new TypeError('toRegexRange: expected the second argument to be a number.');
193 }
194
195 let opts = { relaxZeros: true, ...options };
196 if (typeof opts.strictZeros === 'boolean') {
197 opts.relaxZeros = opts.strictZeros === false;
198 }
199
200 let relax = String(opts.relaxZeros);
201 let shorthand = String(opts.shorthand);
202 let capture = String(opts.capture);
203 let wrap = String(opts.wrap);
204 let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap;
205
206 if (toRegexRange.cache.hasOwnProperty(cacheKey)) {
207 return toRegexRange.cache[cacheKey].result;
208 }
209
210 let a = Math.min(min, max);
211 let b = Math.max(min, max);
212
213 if (Math.abs(a - b) === 1) {
214 let result = min + '|' + max;
215 if (opts.capture) {
216 return `(${result})`;
217 }
218 if (opts.wrap === false) {
219 return result;
220 }
221 return `(?:${result})`;
222 }
223
224 let isPadded = hasPadding(min) || hasPadding(max);
225 let state = { min, max, a, b };
226 let positives = [];
227 let negatives = [];
228
229 if (isPadded) {
230 state.isPadded = isPadded;
231 state.maxLen = String(state.max).length;
232 }
233
234 if (a < 0) {
235 let newMin = b < 0 ? Math.abs(b) : 1;
236 negatives = splitToPatterns(newMin, Math.abs(a), state, opts);
237 a = state.a = 0;
238 }
239
240 if (b >= 0) {
241 positives = splitToPatterns(a, b, state, opts);
242 }
243
244 state.negatives = negatives;
245 state.positives = positives;
246 state.result = collatePatterns(negatives, positives);
247
248 if (opts.capture === true) {
249 state.result = `(${state.result})`;
250 } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) {
251 state.result = `(?:${state.result})`;
252 }
253
254 toRegexRange.cache[cacheKey] = state;
255 return state.result;
256};
257
258function collatePatterns(neg, pos, options) {
259 let onlyNegative = filterPatterns(neg, pos, '-', false) || [];
260 let onlyPositive = filterPatterns(pos, neg, '', false) || [];
261 let intersected = filterPatterns(neg, pos, '-?', true) || [];
262 let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive);
263 return subpatterns.join('|');
264}
265
266function splitToRanges(min, max) {
267 let nines = 1;
268 let zeros = 1;
269
270 let stop = countNines(min, nines);
271 let stops = new Set([max]);
272
273 while (min <= stop && stop <= max) {
274 stops.add(stop);
275 nines += 1;
276 stop = countNines(min, nines);
277 }
278
279 stop = countZeros(max + 1, zeros) - 1;
280
281 while (min < stop && stop <= max) {
282 stops.add(stop);
283 zeros += 1;
284 stop = countZeros(max + 1, zeros) - 1;
285 }
286
287 stops = [...stops];
288 stops.sort(compare);
289 return stops;
290}
291
292/**
293 * Convert a range to a regex pattern
294 * @param {Number} `start`
295 * @param {Number} `stop`
296 * @return {String}
297 */
298
299function rangeToPattern(start, stop, options) {
300 if (start === stop) {
301 return { pattern: start, count: [], digits: 0 };
302 }
303
304 let zipped = zip(start, stop);
305 let digits = zipped.length;
306 let pattern = '';
307 let count = 0;
308
309 for (let i = 0; i < digits; i++) {
310 let [startDigit, stopDigit] = zipped[i];
311
312 if (startDigit === stopDigit) {
313 pattern += startDigit;
314
315 } else if (startDigit !== '0' || stopDigit !== '9') {
316 pattern += toCharacterClass(startDigit, stopDigit);
317
318 } else {
319 count++;
320 }
321 }
322
323 if (count) {
324 pattern += options.shorthand === true ? '\\d' : '[0-9]';
325 }
326
327 return { pattern, count: [count], digits };
328}
329
330function splitToPatterns(min, max, tok, options) {
331 let ranges = splitToRanges(min, max);
332 let tokens = [];
333 let start = min;
334 let prev;
335
336 for (let i = 0; i < ranges.length; i++) {
337 let max = ranges[i];
338 let obj = rangeToPattern(String(start), String(max), options);
339 let zeros = '';
340
341 if (!tok.isPadded && prev && prev.pattern === obj.pattern) {
342 if (prev.count.length > 1) {
343 prev.count.pop();
344 }
345
346 prev.count.push(obj.count[0]);
347 prev.string = prev.pattern + toQuantifier(prev.count);
348 start = max + 1;
349 continue;
350 }
351
352 if (tok.isPadded) {
353 zeros = padZeros(max, tok, options);
354 }
355
356 obj.string = zeros + obj.pattern + toQuantifier(obj.count);
357 tokens.push(obj);
358 start = max + 1;
359 prev = obj;
360 }
361
362 return tokens;
363}
364
365function filterPatterns(arr, comparison, prefix, intersection, options) {
366 let result = [];
367
368 for (let ele of arr) {
369 let { string } = ele;
370
371 // only push if _both_ are negative...
372 if (!intersection && !contains(comparison, 'string', string)) {
373 result.push(prefix + string);
374 }
375
376 // or _both_ are positive
377 if (intersection && contains(comparison, 'string', string)) {
378 result.push(prefix + string);
379 }
380 }
381 return result;
382}
383
384/**
385 * Zip strings
386 */
387
388function zip(a, b) {
389 let arr = [];
390 for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]);
391 return arr;
392}
393
394function compare(a, b) {
395 return a > b ? 1 : b > a ? -1 : 0;
396}
397
398function contains(arr, key, val) {
399 return arr.some(ele => ele[key] === val);
400}
401
402function countNines(min, len) {
403 return Number(String(min).slice(0, -len) + '9'.repeat(len));
404}
405
406function countZeros(integer, zeros) {
407 return integer - (integer % Math.pow(10, zeros));
408}
409
410function toQuantifier(digits) {
411 let [start = 0, stop = ''] = digits;
412 if (stop || start > 1) {
413 return `{${start + (stop ? ',' + stop : '')}}`;
414 }
415 return '';
416}
417
418function toCharacterClass(a, b, options) {
419 return `[${a}${(b - a === 1) ? '' : '-'}${b}]`;
420}
421
422function hasPadding(str) {
423 return /^-?(0+)\d/.test(str);
424}
425
426function padZeros(value, tok, options) {
427 if (!tok.isPadded) {
428 return value;
429 }
430
431 let diff = Math.abs(tok.maxLen - String(value).length);
432 let relax = options.relaxZeros !== false;
433
434 switch (diff) {
435 case 0:
436 return '';
437 case 1:
438 return relax ? '0?' : '0';
439 case 2:
440 return relax ? '0{0,2}' : '00';
441 default: {
442 return relax ? `0{0,${diff}}` : `0{${diff}}`;
443 }
444 }
445}
446
447/**
448 * Cache
449 */
450
451toRegexRange.cache = {};
452toRegexRange.clearCache = () => (toRegexRange.cache = {});
453
454/**
455 * Expose `toRegexRange`
456 */
457
458var toRegexRange_1 = toRegexRange;
459
460const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
461
462const transform = toNumber => {
463 return value => toNumber === true ? Number(value) : String(value);
464};
465
466const isValidValue = value => {
467 return typeof value === 'number' || (typeof value === 'string' && value !== '');
468};
469
470const isNumber$1 = num => Number.isInteger(+num);
471
472const zeros = input => {
473 let value = `${input}`;
474 let index = -1;
475 if (value[0] === '-') value = value.slice(1);
476 if (value === '0') return false;
477 while (value[++index] === '0');
478 return index > 0;
479};
480
481const stringify$1 = (start, end, options) => {
482 if (typeof start === 'string' || typeof end === 'string') {
483 return true;
484 }
485 return options.stringify === true;
486};
487
488const pad = (input, maxLength, toNumber) => {
489 if (maxLength > 0) {
490 let dash = input[0] === '-' ? '-' : '';
491 if (dash) input = input.slice(1);
492 input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0'));
493 }
494 if (toNumber === false) {
495 return String(input);
496 }
497 return input;
498};
499
500const toMaxLen = (input, maxLength) => {
501 let negative = input[0] === '-' ? '-' : '';
502 if (negative) {
503 input = input.slice(1);
504 maxLength--;
505 }
506 while (input.length < maxLength) input = '0' + input;
507 return negative ? ('-' + input) : input;
508};
509
510const toSequence = (parts, options) => {
511 parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
512 parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
513
514 let prefix = options.capture ? '' : '?:';
515 let positives = '';
516 let negatives = '';
517 let result;
518
519 if (parts.positives.length) {
520 positives = parts.positives.join('|');
521 }
522
523 if (parts.negatives.length) {
524 negatives = `-(${prefix}${parts.negatives.join('|')})`;
525 }
526
527 if (positives && negatives) {
528 result = `${positives}|${negatives}`;
529 } else {
530 result = positives || negatives;
531 }
532
533 if (options.wrap) {
534 return `(${prefix}${result})`;
535 }
536
537 return result;
538};
539
540const toRange = (a, b, isNumbers, options) => {
541 if (isNumbers) {
542 return toRegexRange_1(a, b, { wrap: false, ...options });
543 }
544
545 let start = String.fromCharCode(a);
546 if (a === b) return start;
547
548 let stop = String.fromCharCode(b);
549 return `[${start}-${stop}]`;
550};
551
552const toRegex = (start, end, options) => {
553 if (Array.isArray(start)) {
554 let wrap = options.wrap === true;
555 let prefix = options.capture ? '' : '?:';
556 return wrap ? `(${prefix}${start.join('|')})` : start.join('|');
557 }
558 return toRegexRange_1(start, end, options);
559};
560
561const rangeError = (...args) => {
562 return new RangeError('Invalid range arguments: ' + _events_commonjsExternal.require$$1.inspect(...args));
563};
564
565const invalidRange = (start, end, options) => {
566 if (options.strictRanges === true) throw rangeError([start, end]);
567 return [];
568};
569
570const invalidStep = (step, options) => {
571 if (options.strictRanges === true) {
572 throw new TypeError(`Expected step "${step}" to be a number`);
573 }
574 return [];
575};
576
577const fillNumbers = (start, end, step = 1, options = {}) => {
578 let a = Number(start);
579 let b = Number(end);
580
581 if (!Number.isInteger(a) || !Number.isInteger(b)) {
582 if (options.strictRanges === true) throw rangeError([start, end]);
583 return [];
584 }
585
586 // fix negative zero
587 if (a === 0) a = 0;
588 if (b === 0) b = 0;
589
590 let descending = a > b;
591 let startString = String(start);
592 let endString = String(end);
593 let stepString = String(step);
594 step = Math.max(Math.abs(step), 1);
595
596 let padded = zeros(startString) || zeros(endString) || zeros(stepString);
597 let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0;
598 let toNumber = padded === false && stringify$1(start, end, options) === false;
599 let format = options.transform || transform(toNumber);
600
601 if (options.toRegex && step === 1) {
602 return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options);
603 }
604
605 let parts = { negatives: [], positives: [] };
606 let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num));
607 let range = [];
608 let index = 0;
609
610 while (descending ? a >= b : a <= b) {
611 if (options.toRegex === true && step > 1) {
612 push(a);
613 } else {
614 range.push(pad(format(a, index), maxLen, toNumber));
615 }
616 a = descending ? a - step : a + step;
617 index++;
618 }
619
620 if (options.toRegex === true) {
621 return step > 1
622 ? toSequence(parts, options)
623 : toRegex(range, null, { wrap: false, ...options });
624 }
625
626 return range;
627};
628
629const fillLetters = (start, end, step = 1, options = {}) => {
630 if ((!isNumber$1(start) && start.length > 1) || (!isNumber$1(end) && end.length > 1)) {
631 return invalidRange(start, end, options);
632 }
633
634
635 let format = options.transform || (val => String.fromCharCode(val));
636 let a = `${start}`.charCodeAt(0);
637 let b = `${end}`.charCodeAt(0);
638
639 let descending = a > b;
640 let min = Math.min(a, b);
641 let max = Math.max(a, b);
642
643 if (options.toRegex && step === 1) {
644 return toRange(min, max, false, options);
645 }
646
647 let range = [];
648 let index = 0;
649
650 while (descending ? a >= b : a <= b) {
651 range.push(format(a, index));
652 a = descending ? a - step : a + step;
653 index++;
654 }
655
656 if (options.toRegex === true) {
657 return toRegex(range, null, { wrap: false, options });
658 }
659
660 return range;
661};
662
663const fill = (start, end, step, options = {}) => {
664 if (end == null && isValidValue(start)) {
665 return [start];
666 }
667
668 if (!isValidValue(start) || !isValidValue(end)) {
669 return invalidRange(start, end, options);
670 }
671
672 if (typeof step === 'function') {
673 return fill(start, end, 1, { transform: step });
674 }
675
676 if (isObject(step)) {
677 return fill(start, end, 0, step);
678 }
679
680 let opts = { ...options };
681 if (opts.capture === true) opts.wrap = true;
682 step = step || opts.step || 1;
683
684 if (!isNumber$1(step)) {
685 if (step != null && !isObject(step)) return invalidStep(step, opts);
686 return fill(start, end, 1, step);
687 }
688
689 if (isNumber$1(start) && isNumber$1(end)) {
690 return fillNumbers(start, end, step, opts);
691 }
692
693 return fillLetters(start, end, Math.max(Math.abs(step), 1), opts);
694};
695
696var fillRange = fill;
697
698const compile = (ast, options = {}) => {
699 let walk = (node, parent = {}) => {
700 let invalidBlock = utils.isInvalidBrace(parent);
701 let invalidNode = node.invalid === true && options.escapeInvalid === true;
702 let invalid = invalidBlock === true || invalidNode === true;
703 let prefix = options.escapeInvalid === true ? '\\' : '';
704 let output = '';
705
706 if (node.isOpen === true) {
707 return prefix + node.value;
708 }
709 if (node.isClose === true) {
710 return prefix + node.value;
711 }
712
713 if (node.type === 'open') {
714 return invalid ? (prefix + node.value) : '(';
715 }
716
717 if (node.type === 'close') {
718 return invalid ? (prefix + node.value) : ')';
719 }
720
721 if (node.type === 'comma') {
722 return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|');
723 }
724
725 if (node.value) {
726 return node.value;
727 }
728
729 if (node.nodes && node.ranges > 0) {
730 let args = utils.reduce(node.nodes);
731 let range = fillRange(...args, { ...options, wrap: false, toRegex: true });
732
733 if (range.length !== 0) {
734 return args.length > 1 && range.length > 1 ? `(${range})` : range;
735 }
736 }
737
738 if (node.nodes) {
739 for (let child of node.nodes) {
740 output += walk(child, node);
741 }
742 }
743 return output;
744 };
745
746 return walk(ast);
747};
748
749var compile_1 = compile;
750
751const append = (queue = '', stash = '', enclose = false) => {
752 let result = [];
753
754 queue = [].concat(queue);
755 stash = [].concat(stash);
756
757 if (!stash.length) return queue;
758 if (!queue.length) {
759 return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash;
760 }
761
762 for (let item of queue) {
763 if (Array.isArray(item)) {
764 for (let value of item) {
765 result.push(append(value, stash, enclose));
766 }
767 } else {
768 for (let ele of stash) {
769 if (enclose === true && typeof ele === 'string') ele = `{${ele}}`;
770 result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele));
771 }
772 }
773 }
774 return utils.flatten(result);
775};
776
777const expand = (ast, options = {}) => {
778 let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit;
779
780 let walk = (node, parent = {}) => {
781 node.queue = [];
782
783 let p = parent;
784 let q = parent.queue;
785
786 while (p.type !== 'brace' && p.type !== 'root' && p.parent) {
787 p = p.parent;
788 q = p.queue;
789 }
790
791 if (node.invalid || node.dollar) {
792 q.push(append(q.pop(), stringify(node, options)));
793 return;
794 }
795
796 if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) {
797 q.push(append(q.pop(), ['{}']));
798 return;
799 }
800
801 if (node.nodes && node.ranges > 0) {
802 let args = utils.reduce(node.nodes);
803
804 if (utils.exceedsLimit(...args, options.step, rangeLimit)) {
805 throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.');
806 }
807
808 let range = fillRange(...args, options);
809 if (range.length === 0) {
810 range = stringify(node, options);
811 }
812
813 q.push(append(q.pop(), range));
814 node.nodes = [];
815 return;
816 }
817
818 let enclose = utils.encloseBrace(node);
819 let queue = node.queue;
820 let block = node;
821
822 while (block.type !== 'brace' && block.type !== 'root' && block.parent) {
823 block = block.parent;
824 queue = block.queue;
825 }
826
827 for (let i = 0; i < node.nodes.length; i++) {
828 let child = node.nodes[i];
829
830 if (child.type === 'comma' && node.type === 'brace') {
831 if (i === 1) queue.push('');
832 queue.push('');
833 continue;
834 }
835
836 if (child.type === 'close') {
837 q.push(append(q.pop(), queue, enclose));
838 continue;
839 }
840
841 if (child.value && child.type !== 'open') {
842 queue.push(append(queue.pop(), child.value));
843 continue;
844 }
845
846 if (child.nodes) {
847 walk(child, node);
848 }
849 }
850
851 return queue;
852 };
853
854 return utils.flatten(walk(ast));
855};
856
857var expand_1 = expand;
858
859var constants = {
860 MAX_LENGTH: 1024 * 64,
861
862 // Digits
863 CHAR_0: '0', /* 0 */
864 CHAR_9: '9', /* 9 */
865
866 // Alphabet chars.
867 CHAR_UPPERCASE_A: 'A', /* A */
868 CHAR_LOWERCASE_A: 'a', /* a */
869 CHAR_UPPERCASE_Z: 'Z', /* Z */
870 CHAR_LOWERCASE_Z: 'z', /* z */
871
872 CHAR_LEFT_PARENTHESES: '(', /* ( */
873 CHAR_RIGHT_PARENTHESES: ')', /* ) */
874
875 CHAR_ASTERISK: '*', /* * */
876
877 // Non-alphabetic chars.
878 CHAR_AMPERSAND: '&', /* & */
879 CHAR_AT: '@', /* @ */
880 CHAR_BACKSLASH: '\\', /* \ */
881 CHAR_BACKTICK: '`', /* ` */
882 CHAR_CARRIAGE_RETURN: '\r', /* \r */
883 CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */
884 CHAR_COLON: ':', /* : */
885 CHAR_COMMA: ',', /* , */
886 CHAR_DOLLAR: '$', /* . */
887 CHAR_DOT: '.', /* . */
888 CHAR_DOUBLE_QUOTE: '"', /* " */
889 CHAR_EQUAL: '=', /* = */
890 CHAR_EXCLAMATION_MARK: '!', /* ! */
891 CHAR_FORM_FEED: '\f', /* \f */
892 CHAR_FORWARD_SLASH: '/', /* / */
893 CHAR_HASH: '#', /* # */
894 CHAR_HYPHEN_MINUS: '-', /* - */
895 CHAR_LEFT_ANGLE_BRACKET: '<', /* < */
896 CHAR_LEFT_CURLY_BRACE: '{', /* { */
897 CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */
898 CHAR_LINE_FEED: '\n', /* \n */
899 CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */
900 CHAR_PERCENT: '%', /* % */
901 CHAR_PLUS: '+', /* + */
902 CHAR_QUESTION_MARK: '?', /* ? */
903 CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */
904 CHAR_RIGHT_CURLY_BRACE: '}', /* } */
905 CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */
906 CHAR_SEMICOLON: ';', /* ; */
907 CHAR_SINGLE_QUOTE: '\'', /* ' */
908 CHAR_SPACE: ' ', /* */
909 CHAR_TAB: '\t', /* \t */
910 CHAR_UNDERSCORE: '_', /* _ */
911 CHAR_VERTICAL_LINE: '|', /* | */
912 CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */
913};
914
915/**
916 * Constants
917 */
918
919const {
920 MAX_LENGTH,
921 CHAR_BACKSLASH, /* \ */
922 CHAR_BACKTICK, /* ` */
923 CHAR_COMMA, /* , */
924 CHAR_DOT, /* . */
925 CHAR_LEFT_PARENTHESES, /* ( */
926 CHAR_RIGHT_PARENTHESES, /* ) */
927 CHAR_LEFT_CURLY_BRACE, /* { */
928 CHAR_RIGHT_CURLY_BRACE, /* } */
929 CHAR_LEFT_SQUARE_BRACKET, /* [ */
930 CHAR_RIGHT_SQUARE_BRACKET, /* ] */
931 CHAR_DOUBLE_QUOTE, /* " */
932 CHAR_SINGLE_QUOTE, /* ' */
933 CHAR_NO_BREAK_SPACE,
934 CHAR_ZERO_WIDTH_NOBREAK_SPACE
935} = constants;
936
937/**
938 * parse
939 */
940
941const parse = (input, options = {}) => {
942 if (typeof input !== 'string') {
943 throw new TypeError('Expected a string');
944 }
945
946 let opts = options || {};
947 let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
948 if (input.length > max) {
949 throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`);
950 }
951
952 let ast = { type: 'root', input, nodes: [] };
953 let stack = [ast];
954 let block = ast;
955 let prev = ast;
956 let brackets = 0;
957 let length = input.length;
958 let index = 0;
959 let depth = 0;
960 let value;
961
962 /**
963 * Helpers
964 */
965
966 const advance = () => input[index++];
967 const push = node => {
968 if (node.type === 'text' && prev.type === 'dot') {
969 prev.type = 'text';
970 }
971
972 if (prev && prev.type === 'text' && node.type === 'text') {
973 prev.value += node.value;
974 return;
975 }
976
977 block.nodes.push(node);
978 node.parent = block;
979 node.prev = prev;
980 prev = node;
981 return node;
982 };
983
984 push({ type: 'bos' });
985
986 while (index < length) {
987 block = stack[stack.length - 1];
988 value = advance();
989
990 /**
991 * Invalid chars
992 */
993
994 if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) {
995 continue;
996 }
997
998 /**
999 * Escaped chars
1000 */
1001
1002 if (value === CHAR_BACKSLASH) {
1003 push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() });
1004 continue;
1005 }
1006
1007 /**
1008 * Right square bracket (literal): ']'
1009 */
1010
1011 if (value === CHAR_RIGHT_SQUARE_BRACKET) {
1012 push({ type: 'text', value: '\\' + value });
1013 continue;
1014 }
1015
1016 /**
1017 * Left square bracket: '['
1018 */
1019
1020 if (value === CHAR_LEFT_SQUARE_BRACKET) {
1021 brackets++;
1022 let next;
1023
1024 while (index < length && (next = advance())) {
1025 value += next;
1026
1027 if (next === CHAR_LEFT_SQUARE_BRACKET) {
1028 brackets++;
1029 continue;
1030 }
1031
1032 if (next === CHAR_BACKSLASH) {
1033 value += advance();
1034 continue;
1035 }
1036
1037 if (next === CHAR_RIGHT_SQUARE_BRACKET) {
1038 brackets--;
1039
1040 if (brackets === 0) {
1041 break;
1042 }
1043 }
1044 }
1045
1046 push({ type: 'text', value });
1047 continue;
1048 }
1049
1050 /**
1051 * Parentheses
1052 */
1053
1054 if (value === CHAR_LEFT_PARENTHESES) {
1055 block = push({ type: 'paren', nodes: [] });
1056 stack.push(block);
1057 push({ type: 'text', value });
1058 continue;
1059 }
1060
1061 if (value === CHAR_RIGHT_PARENTHESES) {
1062 if (block.type !== 'paren') {
1063 push({ type: 'text', value });
1064 continue;
1065 }
1066 block = stack.pop();
1067 push({ type: 'text', value });
1068 block = stack[stack.length - 1];
1069 continue;
1070 }
1071
1072 /**
1073 * Quotes: '|"|`
1074 */
1075
1076 if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) {
1077 let open = value;
1078 let next;
1079
1080 if (options.keepQuotes !== true) {
1081 value = '';
1082 }
1083
1084 while (index < length && (next = advance())) {
1085 if (next === CHAR_BACKSLASH) {
1086 value += next + advance();
1087 continue;
1088 }
1089
1090 if (next === open) {
1091 if (options.keepQuotes === true) value += next;
1092 break;
1093 }
1094
1095 value += next;
1096 }
1097
1098 push({ type: 'text', value });
1099 continue;
1100 }
1101
1102 /**
1103 * Left curly brace: '{'
1104 */
1105
1106 if (value === CHAR_LEFT_CURLY_BRACE) {
1107 depth++;
1108
1109 let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true;
1110 let brace = {
1111 type: 'brace',
1112 open: true,
1113 close: false,
1114 dollar,
1115 depth,
1116 commas: 0,
1117 ranges: 0,
1118 nodes: []
1119 };
1120
1121 block = push(brace);
1122 stack.push(block);
1123 push({ type: 'open', value });
1124 continue;
1125 }
1126
1127 /**
1128 * Right curly brace: '}'
1129 */
1130
1131 if (value === CHAR_RIGHT_CURLY_BRACE) {
1132 if (block.type !== 'brace') {
1133 push({ type: 'text', value });
1134 continue;
1135 }
1136
1137 let type = 'close';
1138 block = stack.pop();
1139 block.close = true;
1140
1141 push({ type, value });
1142 depth--;
1143
1144 block = stack[stack.length - 1];
1145 continue;
1146 }
1147
1148 /**
1149 * Comma: ','
1150 */
1151
1152 if (value === CHAR_COMMA && depth > 0) {
1153 if (block.ranges > 0) {
1154 block.ranges = 0;
1155 let open = block.nodes.shift();
1156 block.nodes = [open, { type: 'text', value: stringify(block) }];
1157 }
1158
1159 push({ type: 'comma', value });
1160 block.commas++;
1161 continue;
1162 }
1163
1164 /**
1165 * Dot: '.'
1166 */
1167
1168 if (value === CHAR_DOT && depth > 0 && block.commas === 0) {
1169 let siblings = block.nodes;
1170
1171 if (depth === 0 || siblings.length === 0) {
1172 push({ type: 'text', value });
1173 continue;
1174 }
1175
1176 if (prev.type === 'dot') {
1177 block.range = [];
1178 prev.value += value;
1179 prev.type = 'range';
1180
1181 if (block.nodes.length !== 3 && block.nodes.length !== 5) {
1182 block.invalid = true;
1183 block.ranges = 0;
1184 prev.type = 'text';
1185 continue;
1186 }
1187
1188 block.ranges++;
1189 block.args = [];
1190 continue;
1191 }
1192
1193 if (prev.type === 'range') {
1194 siblings.pop();
1195
1196 let before = siblings[siblings.length - 1];
1197 before.value += prev.value + value;
1198 prev = before;
1199 block.ranges--;
1200 continue;
1201 }
1202
1203 push({ type: 'dot', value });
1204 continue;
1205 }
1206
1207 /**
1208 * Text
1209 */
1210
1211 push({ type: 'text', value });
1212 }
1213
1214 // Mark imbalanced braces and brackets as invalid
1215 do {
1216 block = stack.pop();
1217
1218 if (block.type !== 'root') {
1219 block.nodes.forEach(node => {
1220 if (!node.nodes) {
1221 if (node.type === 'open') node.isOpen = true;
1222 if (node.type === 'close') node.isClose = true;
1223 if (!node.nodes) node.type = 'text';
1224 node.invalid = true;
1225 }
1226 });
1227
1228 // get the location of the block on parent.nodes (block's siblings)
1229 let parent = stack[stack.length - 1];
1230 let index = parent.nodes.indexOf(block);
1231 // replace the (invalid) block with it's nodes
1232 parent.nodes.splice(index, 1, ...block.nodes);
1233 }
1234 } while (stack.length > 0);
1235
1236 push({ type: 'eos' });
1237 return ast;
1238};
1239
1240var parse_1 = parse;
1241
1242/**
1243 * Expand the given pattern or create a regex-compatible string.
1244 *
1245 * ```js
1246 * const braces = require('braces');
1247 * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)']
1248 * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c']
1249 * ```
1250 * @param {String} `str`
1251 * @param {Object} `options`
1252 * @return {String}
1253 * @api public
1254 */
1255
1256const braces = (input, options = {}) => {
1257 let output = [];
1258
1259 if (Array.isArray(input)) {
1260 for (let pattern of input) {
1261 let result = braces.create(pattern, options);
1262 if (Array.isArray(result)) {
1263 output.push(...result);
1264 } else {
1265 output.push(result);
1266 }
1267 }
1268 } else {
1269 output = [].concat(braces.create(input, options));
1270 }
1271
1272 if (options && options.expand === true && options.nodupes === true) {
1273 output = [...new Set(output)];
1274 }
1275 return output;
1276};
1277
1278/**
1279 * Parse the given `str` with the given `options`.
1280 *
1281 * ```js
1282 * // braces.parse(pattern, [, options]);
1283 * const ast = braces.parse('a/{b,c}/d');
1284 * console.log(ast);
1285 * ```
1286 * @param {String} pattern Brace pattern to parse
1287 * @param {Object} options
1288 * @return {Object} Returns an AST
1289 * @api public
1290 */
1291
1292braces.parse = (input, options = {}) => parse_1(input, options);
1293
1294/**
1295 * Creates a braces string from an AST, or an AST node.
1296 *
1297 * ```js
1298 * const braces = require('braces');
1299 * let ast = braces.parse('foo/{a,b}/bar');
1300 * console.log(stringify(ast.nodes[2])); //=> '{a,b}'
1301 * ```
1302 * @param {String} `input` Brace pattern or AST.
1303 * @param {Object} `options`
1304 * @return {Array} Returns an array of expanded values.
1305 * @api public
1306 */
1307
1308braces.stringify = (input, options = {}) => {
1309 if (typeof input === 'string') {
1310 return stringify(braces.parse(input, options), options);
1311 }
1312 return stringify(input, options);
1313};
1314
1315/**
1316 * Compiles a brace pattern into a regex-compatible, optimized string.
1317 * This method is called by the main [braces](#braces) function by default.
1318 *
1319 * ```js
1320 * const braces = require('braces');
1321 * console.log(braces.compile('a/{b,c}/d'));
1322 * //=> ['a/(b|c)/d']
1323 * ```
1324 * @param {String} `input` Brace pattern or AST.
1325 * @param {Object} `options`
1326 * @return {Array} Returns an array of expanded values.
1327 * @api public
1328 */
1329
1330braces.compile = (input, options = {}) => {
1331 if (typeof input === 'string') {
1332 input = braces.parse(input, options);
1333 }
1334 return compile_1(input, options);
1335};
1336
1337/**
1338 * Expands a brace pattern into an array. This method is called by the
1339 * main [braces](#braces) function when `options.expand` is true. Before
1340 * using this method it's recommended that you read the [performance notes](#performance))
1341 * and advantages of using [.compile](#compile) instead.
1342 *
1343 * ```js
1344 * const braces = require('braces');
1345 * console.log(braces.expand('a/{b,c}/d'));
1346 * //=> ['a/b/d', 'a/c/d'];
1347 * ```
1348 * @param {String} `pattern` Brace pattern
1349 * @param {Object} `options`
1350 * @return {Array} Returns an array of expanded values.
1351 * @api public
1352 */
1353
1354braces.expand = (input, options = {}) => {
1355 if (typeof input === 'string') {
1356 input = braces.parse(input, options);
1357 }
1358
1359 let result = expand_1(input, options);
1360
1361 // filter out empty strings if specified
1362 if (options.noempty === true) {
1363 result = result.filter(Boolean);
1364 }
1365
1366 // filter out duplicates if specified
1367 if (options.nodupes === true) {
1368 result = [...new Set(result)];
1369 }
1370
1371 return result;
1372};
1373
1374/**
1375 * Processes a brace pattern and returns either an expanded array
1376 * (if `options.expand` is true), a highly optimized regex-compatible string.
1377 * This method is called by the main [braces](#braces) function.
1378 *
1379 * ```js
1380 * const braces = require('braces');
1381 * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}'))
1382 * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)'
1383 * ```
1384 * @param {String} `pattern` Brace pattern
1385 * @param {Object} `options`
1386 * @return {Array} Returns an array of expanded values.
1387 * @api public
1388 */
1389
1390braces.create = (input, options = {}) => {
1391 if (input === '' || input.length < 3) {
1392 return [input];
1393 }
1394
1395 return options.expand !== true
1396 ? braces.compile(input, options)
1397 : braces.expand(input, options);
1398};
1399
1400/**
1401 * Expose "braces"
1402 */
1403
1404var braces_1 = braces;
1405
1406const WIN_SLASH = '\\\\/';
1407const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
1408
1409/**
1410 * Posix glob regex
1411 */
1412
1413const DOT_LITERAL = '\\.';
1414const PLUS_LITERAL = '\\+';
1415const QMARK_LITERAL = '\\?';
1416const SLASH_LITERAL = '\\/';
1417const ONE_CHAR = '(?=.)';
1418const QMARK = '[^/]';
1419const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
1420const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
1421const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
1422const NO_DOT = `(?!${DOT_LITERAL})`;
1423const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
1424const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
1425const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
1426const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
1427const STAR = `${QMARK}*?`;
1428
1429const POSIX_CHARS = {
1430 DOT_LITERAL,
1431 PLUS_LITERAL,
1432 QMARK_LITERAL,
1433 SLASH_LITERAL,
1434 ONE_CHAR,
1435 QMARK,
1436 END_ANCHOR,
1437 DOTS_SLASH,
1438 NO_DOT,
1439 NO_DOTS,
1440 NO_DOT_SLASH,
1441 NO_DOTS_SLASH,
1442 QMARK_NO_DOT,
1443 STAR,
1444 START_ANCHOR
1445};
1446
1447/**
1448 * Windows glob regex
1449 */
1450
1451const WINDOWS_CHARS = {
1452 ...POSIX_CHARS,
1453
1454 SLASH_LITERAL: `[${WIN_SLASH}]`,
1455 QMARK: WIN_NO_SLASH,
1456 STAR: `${WIN_NO_SLASH}*?`,
1457 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
1458 NO_DOT: `(?!${DOT_LITERAL})`,
1459 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
1460 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
1461 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
1462 QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
1463 START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
1464 END_ANCHOR: `(?:[${WIN_SLASH}]|$)`
1465};
1466
1467/**
1468 * POSIX Bracket Regex
1469 */
1470
1471const POSIX_REGEX_SOURCE = {
1472 alnum: 'a-zA-Z0-9',
1473 alpha: 'a-zA-Z',
1474 ascii: '\\x00-\\x7F',
1475 blank: ' \\t',
1476 cntrl: '\\x00-\\x1F\\x7F',
1477 digit: '0-9',
1478 graph: '\\x21-\\x7E',
1479 lower: 'a-z',
1480 print: '\\x20-\\x7E ',
1481 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
1482 space: ' \\t\\r\\n\\v\\f',
1483 upper: 'A-Z',
1484 word: 'A-Za-z0-9_',
1485 xdigit: 'A-Fa-f0-9'
1486};
1487
1488var constants$1 = {
1489 MAX_LENGTH: 1024 * 64,
1490 POSIX_REGEX_SOURCE,
1491
1492 // regular expressions
1493 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
1494 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
1495 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
1496 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
1497 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
1498 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
1499
1500 // Replace globs with equivalent patterns to reduce parsing time.
1501 REPLACEMENTS: {
1502 '***': '*',
1503 '**/**': '**',
1504 '**/**/**': '**'
1505 },
1506
1507 // Digits
1508 CHAR_0: 48, /* 0 */
1509 CHAR_9: 57, /* 9 */
1510
1511 // Alphabet chars.
1512 CHAR_UPPERCASE_A: 65, /* A */
1513 CHAR_LOWERCASE_A: 97, /* a */
1514 CHAR_UPPERCASE_Z: 90, /* Z */
1515 CHAR_LOWERCASE_Z: 122, /* z */
1516
1517 CHAR_LEFT_PARENTHESES: 40, /* ( */
1518 CHAR_RIGHT_PARENTHESES: 41, /* ) */
1519
1520 CHAR_ASTERISK: 42, /* * */
1521
1522 // Non-alphabetic chars.
1523 CHAR_AMPERSAND: 38, /* & */
1524 CHAR_AT: 64, /* @ */
1525 CHAR_BACKWARD_SLASH: 92, /* \ */
1526 CHAR_CARRIAGE_RETURN: 13, /* \r */
1527 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */
1528 CHAR_COLON: 58, /* : */
1529 CHAR_COMMA: 44, /* , */
1530 CHAR_DOT: 46, /* . */
1531 CHAR_DOUBLE_QUOTE: 34, /* " */
1532 CHAR_EQUAL: 61, /* = */
1533 CHAR_EXCLAMATION_MARK: 33, /* ! */
1534 CHAR_FORM_FEED: 12, /* \f */
1535 CHAR_FORWARD_SLASH: 47, /* / */
1536 CHAR_GRAVE_ACCENT: 96, /* ` */
1537 CHAR_HASH: 35, /* # */
1538 CHAR_HYPHEN_MINUS: 45, /* - */
1539 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */
1540 CHAR_LEFT_CURLY_BRACE: 123, /* { */
1541 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */
1542 CHAR_LINE_FEED: 10, /* \n */
1543 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */
1544 CHAR_PERCENT: 37, /* % */
1545 CHAR_PLUS: 43, /* + */
1546 CHAR_QUESTION_MARK: 63, /* ? */
1547 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */
1548 CHAR_RIGHT_CURLY_BRACE: 125, /* } */
1549 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */
1550 CHAR_SEMICOLON: 59, /* ; */
1551 CHAR_SINGLE_QUOTE: 39, /* ' */
1552 CHAR_SPACE: 32, /* */
1553 CHAR_TAB: 9, /* \t */
1554 CHAR_UNDERSCORE: 95, /* _ */
1555 CHAR_VERTICAL_LINE: 124, /* | */
1556 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */
1557
1558 SEP: _events_commonjsExternal.sysPath.sep,
1559
1560 /**
1561 * Create EXTGLOB_CHARS
1562 */
1563
1564 extglobChars(chars) {
1565 return {
1566 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },
1567 '?': { type: 'qmark', open: '(?:', close: ')?' },
1568 '+': { type: 'plus', open: '(?:', close: ')+' },
1569 '*': { type: 'star', open: '(?:', close: ')*' },
1570 '@': { type: 'at', open: '(?:', close: ')' }
1571 };
1572 },
1573
1574 /**
1575 * Create GLOB_CHARS
1576 */
1577
1578 globChars(win32) {
1579 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
1580 }
1581};
1582
1583var utils$1 = rollup_js.createCommonjsModule(function (module, exports) {
1584
1585
1586const win32 = process.platform === 'win32';
1587const {
1588 REGEX_BACKSLASH,
1589 REGEX_REMOVE_BACKSLASH,
1590 REGEX_SPECIAL_CHARS,
1591 REGEX_SPECIAL_CHARS_GLOBAL
1592} = constants$1;
1593
1594exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
1595exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);
1596exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);
1597exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
1598exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');
1599
1600exports.removeBackslashes = str => {
1601 return str.replace(REGEX_REMOVE_BACKSLASH, match => {
1602 return match === '\\' ? '' : match;
1603 });
1604};
1605
1606exports.supportsLookbehinds = () => {
1607 const segs = process.version.slice(1).split('.').map(Number);
1608 if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {
1609 return true;
1610 }
1611 return false;
1612};
1613
1614exports.isWindows = options => {
1615 if (options && typeof options.windows === 'boolean') {
1616 return options.windows;
1617 }
1618 return win32 === true || _events_commonjsExternal.sysPath.sep === '\\';
1619};
1620
1621exports.escapeLast = (input, char, lastIdx) => {
1622 const idx = input.lastIndexOf(char, lastIdx);
1623 if (idx === -1) return input;
1624 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1);
1625 return `${input.slice(0, idx)}\\${input.slice(idx)}`;
1626};
1627
1628exports.removePrefix = (input, state = {}) => {
1629 let output = input;
1630 if (output.startsWith('./')) {
1631 output = output.slice(2);
1632 state.prefix = './';
1633 }
1634 return output;
1635};
1636
1637exports.wrapOutput = (input, state = {}, options = {}) => {
1638 const prepend = options.contains ? '' : '^';
1639 const append = options.contains ? '' : '$';
1640
1641 let output = `${prepend}(?:${input})${append}`;
1642 if (state.negated === true) {
1643 output = `(?:^(?!${output}).*$)`;
1644 }
1645 return output;
1646};
1647});
1648
1649const {
1650 CHAR_ASTERISK, /* * */
1651 CHAR_AT, /* @ */
1652 CHAR_BACKWARD_SLASH, /* \ */
1653 CHAR_COMMA: CHAR_COMMA$1, /* , */
1654 CHAR_DOT: CHAR_DOT$1, /* . */
1655 CHAR_EXCLAMATION_MARK, /* ! */
1656 CHAR_FORWARD_SLASH, /* / */
1657 CHAR_LEFT_CURLY_BRACE: CHAR_LEFT_CURLY_BRACE$1, /* { */
1658 CHAR_LEFT_PARENTHESES: CHAR_LEFT_PARENTHESES$1, /* ( */
1659 CHAR_LEFT_SQUARE_BRACKET: CHAR_LEFT_SQUARE_BRACKET$1, /* [ */
1660 CHAR_PLUS, /* + */
1661 CHAR_QUESTION_MARK, /* ? */
1662 CHAR_RIGHT_CURLY_BRACE: CHAR_RIGHT_CURLY_BRACE$1, /* } */
1663 CHAR_RIGHT_PARENTHESES: CHAR_RIGHT_PARENTHESES$1, /* ) */
1664 CHAR_RIGHT_SQUARE_BRACKET: CHAR_RIGHT_SQUARE_BRACKET$1 /* ] */
1665} = constants$1;
1666
1667const isPathSeparator = code => {
1668 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
1669};
1670
1671const depth = token => {
1672 if (token.isPrefix !== true) {
1673 token.depth = token.isGlobstar ? Infinity : 1;
1674 }
1675};
1676
1677/**
1678 * Quickly scans a glob pattern and returns an object with a handful of
1679 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
1680 * `glob` (the actual pattern), and `negated` (true if the path starts with `!`).
1681 *
1682 * ```js
1683 * const pm = require('picomatch');
1684 * console.log(pm.scan('foo/bar/*.js'));
1685 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
1686 * ```
1687 * @param {String} `str`
1688 * @param {Object} `options`
1689 * @return {Object} Returns an object with tokens and regex source string.
1690 * @api public
1691 */
1692
1693const scan = (input, options) => {
1694 const opts = options || {};
1695
1696 const length = input.length - 1;
1697 const scanToEnd = opts.parts === true || opts.scanToEnd === true;
1698 const slashes = [];
1699 const tokens = [];
1700 const parts = [];
1701
1702 let str = input;
1703 let index = -1;
1704 let start = 0;
1705 let lastIndex = 0;
1706 let isBrace = false;
1707 let isBracket = false;
1708 let isGlob = false;
1709 let isExtglob = false;
1710 let isGlobstar = false;
1711 let braceEscaped = false;
1712 let backslashes = false;
1713 let negated = false;
1714 let finished = false;
1715 let braces = 0;
1716 let prev;
1717 let code;
1718 let token = { value: '', depth: 0, isGlob: false };
1719
1720 const eos = () => index >= length;
1721 const peek = () => str.charCodeAt(index + 1);
1722 const advance = () => {
1723 prev = code;
1724 return str.charCodeAt(++index);
1725 };
1726
1727 while (index < length) {
1728 code = advance();
1729 let next;
1730
1731 if (code === CHAR_BACKWARD_SLASH) {
1732 backslashes = token.backslashes = true;
1733 code = advance();
1734
1735 if (code === CHAR_LEFT_CURLY_BRACE$1) {
1736 braceEscaped = true;
1737 }
1738 continue;
1739 }
1740
1741 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE$1) {
1742 braces++;
1743
1744 while (eos() !== true && (code = advance())) {
1745 if (code === CHAR_BACKWARD_SLASH) {
1746 backslashes = token.backslashes = true;
1747 advance();
1748 continue;
1749 }
1750
1751 if (code === CHAR_LEFT_CURLY_BRACE$1) {
1752 braces++;
1753 continue;
1754 }
1755
1756 if (braceEscaped !== true && code === CHAR_DOT$1 && (code = advance()) === CHAR_DOT$1) {
1757 isBrace = token.isBrace = true;
1758 isGlob = token.isGlob = true;
1759 finished = true;
1760
1761 if (scanToEnd === true) {
1762 continue;
1763 }
1764
1765 break;
1766 }
1767
1768 if (braceEscaped !== true && code === CHAR_COMMA$1) {
1769 isBrace = token.isBrace = true;
1770 isGlob = token.isGlob = true;
1771 finished = true;
1772
1773 if (scanToEnd === true) {
1774 continue;
1775 }
1776
1777 break;
1778 }
1779
1780 if (code === CHAR_RIGHT_CURLY_BRACE$1) {
1781 braces--;
1782
1783 if (braces === 0) {
1784 braceEscaped = false;
1785 isBrace = token.isBrace = true;
1786 finished = true;
1787 break;
1788 }
1789 }
1790 }
1791
1792 if (scanToEnd === true) {
1793 continue;
1794 }
1795
1796 break;
1797 }
1798
1799 if (code === CHAR_FORWARD_SLASH) {
1800 slashes.push(index);
1801 tokens.push(token);
1802 token = { value: '', depth: 0, isGlob: false };
1803
1804 if (finished === true) continue;
1805 if (prev === CHAR_DOT$1 && index === (start + 1)) {
1806 start += 2;
1807 continue;
1808 }
1809
1810 lastIndex = index + 1;
1811 continue;
1812 }
1813
1814 if (opts.noext !== true) {
1815 const isExtglobChar = code === CHAR_PLUS
1816 || code === CHAR_AT
1817 || code === CHAR_ASTERISK
1818 || code === CHAR_QUESTION_MARK
1819 || code === CHAR_EXCLAMATION_MARK;
1820
1821 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES$1) {
1822 isGlob = token.isGlob = true;
1823 isExtglob = token.isExtglob = true;
1824 finished = true;
1825
1826 if (scanToEnd === true) {
1827 while (eos() !== true && (code = advance())) {
1828 if (code === CHAR_BACKWARD_SLASH) {
1829 backslashes = token.backslashes = true;
1830 code = advance();
1831 continue;
1832 }
1833
1834 if (code === CHAR_RIGHT_PARENTHESES$1) {
1835 isGlob = token.isGlob = true;
1836 finished = true;
1837 break;
1838 }
1839 }
1840 continue;
1841 }
1842 break;
1843 }
1844 }
1845
1846 if (code === CHAR_ASTERISK) {
1847 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;
1848 isGlob = token.isGlob = true;
1849 finished = true;
1850
1851 if (scanToEnd === true) {
1852 continue;
1853 }
1854 break;
1855 }
1856
1857 if (code === CHAR_QUESTION_MARK) {
1858 isGlob = token.isGlob = true;
1859 finished = true;
1860
1861 if (scanToEnd === true) {
1862 continue;
1863 }
1864 break;
1865 }
1866
1867 if (code === CHAR_LEFT_SQUARE_BRACKET$1) {
1868 while (eos() !== true && (next = advance())) {
1869 if (next === CHAR_BACKWARD_SLASH) {
1870 backslashes = token.backslashes = true;
1871 advance();
1872 continue;
1873 }
1874
1875 if (next === CHAR_RIGHT_SQUARE_BRACKET$1) {
1876 isBracket = token.isBracket = true;
1877 isGlob = token.isGlob = true;
1878 finished = true;
1879
1880 if (scanToEnd === true) {
1881 continue;
1882 }
1883 break;
1884 }
1885 }
1886 }
1887
1888 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {
1889 negated = token.negated = true;
1890 start++;
1891 continue;
1892 }
1893
1894 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES$1) {
1895 while (eos() !== true && (code = advance())) {
1896 if (code === CHAR_BACKWARD_SLASH) {
1897 backslashes = token.backslashes = true;
1898 code = advance();
1899 continue;
1900 }
1901
1902 if (code === CHAR_RIGHT_PARENTHESES$1) {
1903 isGlob = token.isGlob = true;
1904 finished = true;
1905
1906 if (scanToEnd === true) {
1907 continue;
1908 }
1909 break;
1910 }
1911 }
1912 }
1913
1914 if (isGlob === true) {
1915 finished = true;
1916
1917 if (scanToEnd === true) {
1918 continue;
1919 }
1920
1921 break;
1922 }
1923 }
1924
1925 if (opts.noext === true) {
1926 isExtglob = false;
1927 isGlob = false;
1928 }
1929
1930 let base = str;
1931 let prefix = '';
1932 let glob = '';
1933
1934 if (start > 0) {
1935 prefix = str.slice(0, start);
1936 str = str.slice(start);
1937 lastIndex -= start;
1938 }
1939
1940 if (base && isGlob === true && lastIndex > 0) {
1941 base = str.slice(0, lastIndex);
1942 glob = str.slice(lastIndex);
1943 } else if (isGlob === true) {
1944 base = '';
1945 glob = str;
1946 } else {
1947 base = str;
1948 }
1949
1950 if (base && base !== '' && base !== '/' && base !== str) {
1951 if (isPathSeparator(base.charCodeAt(base.length - 1))) {
1952 base = base.slice(0, -1);
1953 }
1954 }
1955
1956 if (opts.unescape === true) {
1957 if (glob) glob = utils$1.removeBackslashes(glob);
1958
1959 if (base && backslashes === true) {
1960 base = utils$1.removeBackslashes(base);
1961 }
1962 }
1963
1964 const state = {
1965 prefix,
1966 input,
1967 start,
1968 base,
1969 glob,
1970 isBrace,
1971 isBracket,
1972 isGlob,
1973 isExtglob,
1974 isGlobstar,
1975 negated
1976 };
1977
1978 if (opts.tokens === true) {
1979 state.maxDepth = 0;
1980 if (!isPathSeparator(code)) {
1981 tokens.push(token);
1982 }
1983 state.tokens = tokens;
1984 }
1985
1986 if (opts.parts === true || opts.tokens === true) {
1987 let prevIndex;
1988
1989 for (let idx = 0; idx < slashes.length; idx++) {
1990 const n = prevIndex ? prevIndex + 1 : start;
1991 const i = slashes[idx];
1992 const value = input.slice(n, i);
1993 if (opts.tokens) {
1994 if (idx === 0 && start !== 0) {
1995 tokens[idx].isPrefix = true;
1996 tokens[idx].value = prefix;
1997 } else {
1998 tokens[idx].value = value;
1999 }
2000 depth(tokens[idx]);
2001 state.maxDepth += tokens[idx].depth;
2002 }
2003 if (idx !== 0 || value !== '') {
2004 parts.push(value);
2005 }
2006 prevIndex = i;
2007 }
2008
2009 if (prevIndex && prevIndex + 1 < input.length) {
2010 const value = input.slice(prevIndex + 1);
2011 parts.push(value);
2012
2013 if (opts.tokens) {
2014 tokens[tokens.length - 1].value = value;
2015 depth(tokens[tokens.length - 1]);
2016 state.maxDepth += tokens[tokens.length - 1].depth;
2017 }
2018 }
2019
2020 state.slashes = slashes;
2021 state.parts = parts;
2022 }
2023
2024 return state;
2025};
2026
2027var scan_1 = scan;
2028
2029/**
2030 * Constants
2031 */
2032
2033const {
2034 MAX_LENGTH: MAX_LENGTH$1,
2035 POSIX_REGEX_SOURCE: POSIX_REGEX_SOURCE$1,
2036 REGEX_NON_SPECIAL_CHARS,
2037 REGEX_SPECIAL_CHARS_BACKREF,
2038 REPLACEMENTS
2039} = constants$1;
2040
2041/**
2042 * Helpers
2043 */
2044
2045const expandRange = (args, options) => {
2046 if (typeof options.expandRange === 'function') {
2047 return options.expandRange(...args, options);
2048 }
2049
2050 args.sort();
2051 const value = `[${args.join('-')}]`;
2052
2053 return value;
2054};
2055
2056/**
2057 * Create the message for a syntax error
2058 */
2059
2060const syntaxError = (type, char) => {
2061 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
2062};
2063
2064/**
2065 * Parse the given input string.
2066 * @param {String} input
2067 * @param {Object} options
2068 * @return {Object}
2069 */
2070
2071const parse$1 = (input, options) => {
2072 if (typeof input !== 'string') {
2073 throw new TypeError('Expected a string');
2074 }
2075
2076 input = REPLACEMENTS[input] || input;
2077
2078 const opts = { ...options };
2079 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$1, opts.maxLength) : MAX_LENGTH$1;
2080
2081 let len = input.length;
2082 if (len > max) {
2083 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
2084 }
2085
2086 const bos = { type: 'bos', value: '', output: opts.prepend || '' };
2087 const tokens = [bos];
2088
2089 const capture = opts.capture ? '' : '?:';
2090 const win32 = utils$1.isWindows(options);
2091
2092 // create constants based on platform, for windows or posix
2093 const PLATFORM_CHARS = constants$1.globChars(win32);
2094 const EXTGLOB_CHARS = constants$1.extglobChars(PLATFORM_CHARS);
2095
2096 const {
2097 DOT_LITERAL,
2098 PLUS_LITERAL,
2099 SLASH_LITERAL,
2100 ONE_CHAR,
2101 DOTS_SLASH,
2102 NO_DOT,
2103 NO_DOT_SLASH,
2104 NO_DOTS_SLASH,
2105 QMARK,
2106 QMARK_NO_DOT,
2107 STAR,
2108 START_ANCHOR
2109 } = PLATFORM_CHARS;
2110
2111 const globstar = (opts) => {
2112 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
2113 };
2114
2115 const nodot = opts.dot ? '' : NO_DOT;
2116 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;
2117 let star = opts.bash === true ? globstar(opts) : STAR;
2118
2119 if (opts.capture) {
2120 star = `(${star})`;
2121 }
2122
2123 // minimatch options support
2124 if (typeof opts.noext === 'boolean') {
2125 opts.noextglob = opts.noext;
2126 }
2127
2128 const state = {
2129 input,
2130 index: -1,
2131 start: 0,
2132 dot: opts.dot === true,
2133 consumed: '',
2134 output: '',
2135 prefix: '',
2136 backtrack: false,
2137 negated: false,
2138 brackets: 0,
2139 braces: 0,
2140 parens: 0,
2141 quotes: 0,
2142 globstar: false,
2143 tokens
2144 };
2145
2146 input = utils$1.removePrefix(input, state);
2147 len = input.length;
2148
2149 const extglobs = [];
2150 const braces = [];
2151 const stack = [];
2152 let prev = bos;
2153 let value;
2154
2155 /**
2156 * Tokenizing helpers
2157 */
2158
2159 const eos = () => state.index === len - 1;
2160 const peek = state.peek = (n = 1) => input[state.index + n];
2161 const advance = state.advance = () => input[++state.index];
2162 const remaining = () => input.slice(state.index + 1);
2163 const consume = (value = '', num = 0) => {
2164 state.consumed += value;
2165 state.index += num;
2166 };
2167 const append = token => {
2168 state.output += token.output != null ? token.output : token.value;
2169 consume(token.value);
2170 };
2171
2172 const negate = () => {
2173 let count = 1;
2174
2175 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) {
2176 advance();
2177 state.start++;
2178 count++;
2179 }
2180
2181 if (count % 2 === 0) {
2182 return false;
2183 }
2184
2185 state.negated = true;
2186 state.start++;
2187 return true;
2188 };
2189
2190 const increment = type => {
2191 state[type]++;
2192 stack.push(type);
2193 };
2194
2195 const decrement = type => {
2196 state[type]--;
2197 stack.pop();
2198 };
2199
2200 /**
2201 * Push tokens onto the tokens array. This helper speeds up
2202 * tokenizing by 1) helping us avoid backtracking as much as possible,
2203 * and 2) helping us avoid creating extra tokens when consecutive
2204 * characters are plain text. This improves performance and simplifies
2205 * lookbehinds.
2206 */
2207
2208 const push = tok => {
2209 if (prev.type === 'globstar') {
2210 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace');
2211 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'));
2212
2213 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) {
2214 state.output = state.output.slice(0, -prev.output.length);
2215 prev.type = 'star';
2216 prev.value = '*';
2217 prev.output = star;
2218 state.output += prev.output;
2219 }
2220 }
2221
2222 if (extglobs.length && tok.type !== 'paren' && !EXTGLOB_CHARS[tok.value]) {
2223 extglobs[extglobs.length - 1].inner += tok.value;
2224 }
2225
2226 if (tok.value || tok.output) append(tok);
2227 if (prev && prev.type === 'text' && tok.type === 'text') {
2228 prev.value += tok.value;
2229 prev.output = (prev.output || '') + tok.value;
2230 return;
2231 }
2232
2233 tok.prev = prev;
2234 tokens.push(tok);
2235 prev = tok;
2236 };
2237
2238 const extglobOpen = (type, value) => {
2239 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' };
2240
2241 token.prev = prev;
2242 token.parens = state.parens;
2243 token.output = state.output;
2244 const output = (opts.capture ? '(' : '') + token.open;
2245
2246 increment('parens');
2247
2248
2249 push({ type, value, output: state.output ? '' : ONE_CHAR });
2250 push({ type: 'paren', extglob: true, value: advance(), output });
2251 extglobs.push(token);
2252 };
2253
2254 const extglobClose = token => {
2255 let output = token.close + (opts.capture ? ')' : '');
2256
2257 if (token.type === 'negate') {
2258 let extglobStar = star;
2259
2260 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) {
2261 extglobStar = globstar(opts);
2262 }
2263
2264 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) {
2265 output = token.close = `)$))${extglobStar}`;
2266 }
2267
2268 if (token.prev.type === 'bos' && eos()) {
2269 state.negatedExtglob = true;
2270 }
2271 }
2272
2273 push({ type: 'paren', extglob: true, value, output });
2274 decrement('parens');
2275 };
2276
2277 /**
2278 * Fast paths
2279 */
2280
2281 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) {
2282 let backslashes = false;
2283
2284 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
2285 if (first === '\\') {
2286 backslashes = true;
2287 return m;
2288 }
2289
2290 if (first === '?') {
2291 if (esc) {
2292 return esc + first + (rest ? QMARK.repeat(rest.length) : '');
2293 }
2294 if (index === 0) {
2295 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '');
2296 }
2297 return QMARK.repeat(chars.length);
2298 }
2299
2300 if (first === '.') {
2301 return DOT_LITERAL.repeat(chars.length);
2302 }
2303
2304 if (first === '*') {
2305 if (esc) {
2306 return esc + first + (rest ? star : '');
2307 }
2308 return star;
2309 }
2310 return esc ? m : `\\${m}`;
2311 });
2312
2313 if (backslashes === true) {
2314 if (opts.unescape === true) {
2315 output = output.replace(/\\/g, '');
2316 } else {
2317 output = output.replace(/\\+/g, m => {
2318 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : '');
2319 });
2320 }
2321 }
2322
2323 if (output === input && opts.contains === true) {
2324 state.output = input;
2325 return state;
2326 }
2327
2328 state.output = utils$1.wrapOutput(output, state, options);
2329 return state;
2330 }
2331
2332 /**
2333 * Tokenize input until we reach end-of-string
2334 */
2335
2336 while (!eos()) {
2337 value = advance();
2338
2339 if (value === '\u0000') {
2340 continue;
2341 }
2342
2343 /**
2344 * Escaped characters
2345 */
2346
2347 if (value === '\\') {
2348 const next = peek();
2349
2350 if (next === '/' && opts.bash !== true) {
2351 continue;
2352 }
2353
2354 if (next === '.' || next === ';') {
2355 continue;
2356 }
2357
2358 if (!next) {
2359 value += '\\';
2360 push({ type: 'text', value });
2361 continue;
2362 }
2363
2364 // collapse slashes to reduce potential for exploits
2365 const match = /^\\+/.exec(remaining());
2366 let slashes = 0;
2367
2368 if (match && match[0].length > 2) {
2369 slashes = match[0].length;
2370 state.index += slashes;
2371 if (slashes % 2 !== 0) {
2372 value += '\\';
2373 }
2374 }
2375
2376 if (opts.unescape === true) {
2377 value = advance() || '';
2378 } else {
2379 value += advance() || '';
2380 }
2381
2382 if (state.brackets === 0) {
2383 push({ type: 'text', value });
2384 continue;
2385 }
2386 }
2387
2388 /**
2389 * If we're inside a regex character class, continue
2390 * until we reach the closing bracket.
2391 */
2392
2393 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) {
2394 if (opts.posix !== false && value === ':') {
2395 const inner = prev.value.slice(1);
2396 if (inner.includes('[')) {
2397 prev.posix = true;
2398
2399 if (inner.includes(':')) {
2400 const idx = prev.value.lastIndexOf('[');
2401 const pre = prev.value.slice(0, idx);
2402 const rest = prev.value.slice(idx + 2);
2403 const posix = POSIX_REGEX_SOURCE$1[rest];
2404 if (posix) {
2405 prev.value = pre + posix;
2406 state.backtrack = true;
2407 advance();
2408
2409 if (!bos.output && tokens.indexOf(prev) === 1) {
2410 bos.output = ONE_CHAR;
2411 }
2412 continue;
2413 }
2414 }
2415 }
2416 }
2417
2418 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) {
2419 value = `\\${value}`;
2420 }
2421
2422 if (value === ']' && (prev.value === '[' || prev.value === '[^')) {
2423 value = `\\${value}`;
2424 }
2425
2426 if (opts.posix === true && value === '!' && prev.value === '[') {
2427 value = '^';
2428 }
2429
2430 prev.value += value;
2431 append({ value });
2432 continue;
2433 }
2434
2435 /**
2436 * If we're inside a quoted string, continue
2437 * until we reach the closing double quote.
2438 */
2439
2440 if (state.quotes === 1 && value !== '"') {
2441 value = utils$1.escapeRegex(value);
2442 prev.value += value;
2443 append({ value });
2444 continue;
2445 }
2446
2447 /**
2448 * Double quotes
2449 */
2450
2451 if (value === '"') {
2452 state.quotes = state.quotes === 1 ? 0 : 1;
2453 if (opts.keepQuotes === true) {
2454 push({ type: 'text', value });
2455 }
2456 continue;
2457 }
2458
2459 /**
2460 * Parentheses
2461 */
2462
2463 if (value === '(') {
2464 increment('parens');
2465 push({ type: 'paren', value });
2466 continue;
2467 }
2468
2469 if (value === ')') {
2470 if (state.parens === 0 && opts.strictBrackets === true) {
2471 throw new SyntaxError(syntaxError('opening', '('));
2472 }
2473
2474 const extglob = extglobs[extglobs.length - 1];
2475 if (extglob && state.parens === extglob.parens + 1) {
2476 extglobClose(extglobs.pop());
2477 continue;
2478 }
2479
2480 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' });
2481 decrement('parens');
2482 continue;
2483 }
2484
2485 /**
2486 * Square brackets
2487 */
2488
2489 if (value === '[') {
2490 if (opts.nobracket === true || !remaining().includes(']')) {
2491 if (opts.nobracket !== true && opts.strictBrackets === true) {
2492 throw new SyntaxError(syntaxError('closing', ']'));
2493 }
2494
2495 value = `\\${value}`;
2496 } else {
2497 increment('brackets');
2498 }
2499
2500 push({ type: 'bracket', value });
2501 continue;
2502 }
2503
2504 if (value === ']') {
2505 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) {
2506 push({ type: 'text', value, output: `\\${value}` });
2507 continue;
2508 }
2509
2510 if (state.brackets === 0) {
2511 if (opts.strictBrackets === true) {
2512 throw new SyntaxError(syntaxError('opening', '['));
2513 }
2514
2515 push({ type: 'text', value, output: `\\${value}` });
2516 continue;
2517 }
2518
2519 decrement('brackets');
2520
2521 const prevValue = prev.value.slice(1);
2522 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) {
2523 value = `/${value}`;
2524 }
2525
2526 prev.value += value;
2527 append({ value });
2528
2529 // when literal brackets are explicitly disabled
2530 // assume we should match with a regex character class
2531 if (opts.literalBrackets === false || utils$1.hasRegexChars(prevValue)) {
2532 continue;
2533 }
2534
2535 const escaped = utils$1.escapeRegex(prev.value);
2536 state.output = state.output.slice(0, -prev.value.length);
2537
2538 // when literal brackets are explicitly enabled
2539 // assume we should escape the brackets to match literal characters
2540 if (opts.literalBrackets === true) {
2541 state.output += escaped;
2542 prev.value = escaped;
2543 continue;
2544 }
2545
2546 // when the user specifies nothing, try to match both
2547 prev.value = `(${capture}${escaped}|${prev.value})`;
2548 state.output += prev.value;
2549 continue;
2550 }
2551
2552 /**
2553 * Braces
2554 */
2555
2556 if (value === '{' && opts.nobrace !== true) {
2557 increment('braces');
2558
2559 const open = {
2560 type: 'brace',
2561 value,
2562 output: '(',
2563 outputIndex: state.output.length,
2564 tokensIndex: state.tokens.length
2565 };
2566
2567 braces.push(open);
2568 push(open);
2569 continue;
2570 }
2571
2572 if (value === '}') {
2573 const brace = braces[braces.length - 1];
2574
2575 if (opts.nobrace === true || !brace) {
2576 push({ type: 'text', value, output: value });
2577 continue;
2578 }
2579
2580 let output = ')';
2581
2582 if (brace.dots === true) {
2583 const arr = tokens.slice();
2584 const range = [];
2585
2586 for (let i = arr.length - 1; i >= 0; i--) {
2587 tokens.pop();
2588 if (arr[i].type === 'brace') {
2589 break;
2590 }
2591 if (arr[i].type !== 'dots') {
2592 range.unshift(arr[i].value);
2593 }
2594 }
2595
2596 output = expandRange(range, opts);
2597 state.backtrack = true;
2598 }
2599
2600 if (brace.comma !== true && brace.dots !== true) {
2601 const out = state.output.slice(0, brace.outputIndex);
2602 const toks = state.tokens.slice(brace.tokensIndex);
2603 brace.value = brace.output = '\\{';
2604 value = output = `\\}`;
2605 state.output = out;
2606 for (const t of toks) {
2607 state.output += (t.output || t.value);
2608 }
2609 }
2610
2611 push({ type: 'brace', value, output });
2612 decrement('braces');
2613 braces.pop();
2614 continue;
2615 }
2616
2617 /**
2618 * Pipes
2619 */
2620
2621 if (value === '|') {
2622 if (extglobs.length > 0) {
2623 extglobs[extglobs.length - 1].conditions++;
2624 }
2625 push({ type: 'text', value });
2626 continue;
2627 }
2628
2629 /**
2630 * Commas
2631 */
2632
2633 if (value === ',') {
2634 let output = value;
2635
2636 const brace = braces[braces.length - 1];
2637 if (brace && stack[stack.length - 1] === 'braces') {
2638 brace.comma = true;
2639 output = '|';
2640 }
2641
2642 push({ type: 'comma', value, output });
2643 continue;
2644 }
2645
2646 /**
2647 * Slashes
2648 */
2649
2650 if (value === '/') {
2651 // if the beginning of the glob is "./", advance the start
2652 // to the current index, and don't add the "./" characters
2653 // to the state. This greatly simplifies lookbehinds when
2654 // checking for BOS characters like "!" and "." (not "./")
2655 if (prev.type === 'dot' && state.index === state.start + 1) {
2656 state.start = state.index + 1;
2657 state.consumed = '';
2658 state.output = '';
2659 tokens.pop();
2660 prev = bos; // reset "prev" to the first token
2661 continue;
2662 }
2663
2664 push({ type: 'slash', value, output: SLASH_LITERAL });
2665 continue;
2666 }
2667
2668 /**
2669 * Dots
2670 */
2671
2672 if (value === '.') {
2673 if (state.braces > 0 && prev.type === 'dot') {
2674 if (prev.value === '.') prev.output = DOT_LITERAL;
2675 const brace = braces[braces.length - 1];
2676 prev.type = 'dots';
2677 prev.output += value;
2678 prev.value += value;
2679 brace.dots = true;
2680 continue;
2681 }
2682
2683 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') {
2684 push({ type: 'text', value, output: DOT_LITERAL });
2685 continue;
2686 }
2687
2688 push({ type: 'dot', value, output: DOT_LITERAL });
2689 continue;
2690 }
2691
2692 /**
2693 * Question marks
2694 */
2695
2696 if (value === '?') {
2697 const isGroup = prev && prev.value === '(';
2698 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
2699 extglobOpen('qmark', value);
2700 continue;
2701 }
2702
2703 if (prev && prev.type === 'paren') {
2704 const next = peek();
2705 let output = value;
2706
2707 if (next === '<' && !utils$1.supportsLookbehinds()) {
2708 throw new Error('Node.js v10 or higher is required for regex lookbehinds');
2709 }
2710
2711 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) {
2712 output = `\\${value}`;
2713 }
2714
2715 push({ type: 'text', value, output });
2716 continue;
2717 }
2718
2719 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) {
2720 push({ type: 'qmark', value, output: QMARK_NO_DOT });
2721 continue;
2722 }
2723
2724 push({ type: 'qmark', value, output: QMARK });
2725 continue;
2726 }
2727
2728 /**
2729 * Exclamation
2730 */
2731
2732 if (value === '!') {
2733 if (opts.noextglob !== true && peek() === '(') {
2734 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) {
2735 extglobOpen('negate', value);
2736 continue;
2737 }
2738 }
2739
2740 if (opts.nonegate !== true && state.index === 0) {
2741 negate();
2742 continue;
2743 }
2744 }
2745
2746 /**
2747 * Plus
2748 */
2749
2750 if (value === '+') {
2751 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
2752 extglobOpen('plus', value);
2753 continue;
2754 }
2755
2756 if ((prev && prev.value === '(') || opts.regex === false) {
2757 push({ type: 'plus', value, output: PLUS_LITERAL });
2758 continue;
2759 }
2760
2761 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) {
2762 push({ type: 'plus', value });
2763 continue;
2764 }
2765
2766 push({ type: 'plus', value: PLUS_LITERAL });
2767 continue;
2768 }
2769
2770 /**
2771 * Plain text
2772 */
2773
2774 if (value === '@') {
2775 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
2776 push({ type: 'at', extglob: true, value, output: '' });
2777 continue;
2778 }
2779
2780 push({ type: 'text', value });
2781 continue;
2782 }
2783
2784 /**
2785 * Plain text
2786 */
2787
2788 if (value !== '*') {
2789 if (value === '$' || value === '^') {
2790 value = `\\${value}`;
2791 }
2792
2793 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());
2794 if (match) {
2795 value += match[0];
2796 state.index += match[0].length;
2797 }
2798
2799 push({ type: 'text', value });
2800 continue;
2801 }
2802
2803 /**
2804 * Stars
2805 */
2806
2807 if (prev && (prev.type === 'globstar' || prev.star === true)) {
2808 prev.type = 'star';
2809 prev.star = true;
2810 prev.value += value;
2811 prev.output = star;
2812 state.backtrack = true;
2813 state.globstar = true;
2814 consume(value);
2815 continue;
2816 }
2817
2818 let rest = remaining();
2819 if (opts.noextglob !== true && /^\([^?]/.test(rest)) {
2820 extglobOpen('star', value);
2821 continue;
2822 }
2823
2824 if (prev.type === 'star') {
2825 if (opts.noglobstar === true) {
2826 consume(value);
2827 continue;
2828 }
2829
2830 const prior = prev.prev;
2831 const before = prior.prev;
2832 const isStart = prior.type === 'slash' || prior.type === 'bos';
2833 const afterStar = before && (before.type === 'star' || before.type === 'globstar');
2834
2835 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) {
2836 push({ type: 'star', value, output: '' });
2837 continue;
2838 }
2839
2840 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace');
2841 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren');
2842 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) {
2843 push({ type: 'star', value, output: '' });
2844 continue;
2845 }
2846
2847 // strip consecutive `/**/`
2848 while (rest.slice(0, 3) === '/**') {
2849 const after = input[state.index + 4];
2850 if (after && after !== '/') {
2851 break;
2852 }
2853 rest = rest.slice(3);
2854 consume('/**', 3);
2855 }
2856
2857 if (prior.type === 'bos' && eos()) {
2858 prev.type = 'globstar';
2859 prev.value += value;
2860 prev.output = globstar(opts);
2861 state.output = prev.output;
2862 state.globstar = true;
2863 consume(value);
2864 continue;
2865 }
2866
2867 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) {
2868 state.output = state.output.slice(0, -(prior.output + prev.output).length);
2869 prior.output = `(?:${prior.output}`;
2870
2871 prev.type = 'globstar';
2872 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)');
2873 prev.value += value;
2874 state.globstar = true;
2875 state.output += prior.output + prev.output;
2876 consume(value);
2877 continue;
2878 }
2879
2880 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') {
2881 const end = rest[1] !== void 0 ? '|$' : '';
2882
2883 state.output = state.output.slice(0, -(prior.output + prev.output).length);
2884 prior.output = `(?:${prior.output}`;
2885
2886 prev.type = 'globstar';
2887 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;
2888 prev.value += value;
2889
2890 state.output += prior.output + prev.output;
2891 state.globstar = true;
2892
2893 consume(value + advance());
2894
2895 push({ type: 'slash', value: '/', output: '' });
2896 continue;
2897 }
2898
2899 if (prior.type === 'bos' && rest[0] === '/') {
2900 prev.type = 'globstar';
2901 prev.value += value;
2902 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;
2903 state.output = prev.output;
2904 state.globstar = true;
2905 consume(value + advance());
2906 push({ type: 'slash', value: '/', output: '' });
2907 continue;
2908 }
2909
2910 // remove single star from output
2911 state.output = state.output.slice(0, -prev.output.length);
2912
2913 // reset previous token to globstar
2914 prev.type = 'globstar';
2915 prev.output = globstar(opts);
2916 prev.value += value;
2917
2918 // reset output with globstar
2919 state.output += prev.output;
2920 state.globstar = true;
2921 consume(value);
2922 continue;
2923 }
2924
2925 const token = { type: 'star', value, output: star };
2926
2927 if (opts.bash === true) {
2928 token.output = '.*?';
2929 if (prev.type === 'bos' || prev.type === 'slash') {
2930 token.output = nodot + token.output;
2931 }
2932 push(token);
2933 continue;
2934 }
2935
2936 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) {
2937 token.output = value;
2938 push(token);
2939 continue;
2940 }
2941
2942 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') {
2943 if (prev.type === 'dot') {
2944 state.output += NO_DOT_SLASH;
2945 prev.output += NO_DOT_SLASH;
2946
2947 } else if (opts.dot === true) {
2948 state.output += NO_DOTS_SLASH;
2949 prev.output += NO_DOTS_SLASH;
2950
2951 } else {
2952 state.output += nodot;
2953 prev.output += nodot;
2954 }
2955
2956 if (peek() !== '*') {
2957 state.output += ONE_CHAR;
2958 prev.output += ONE_CHAR;
2959 }
2960 }
2961
2962 push(token);
2963 }
2964
2965 while (state.brackets > 0) {
2966 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']'));
2967 state.output = utils$1.escapeLast(state.output, '[');
2968 decrement('brackets');
2969 }
2970
2971 while (state.parens > 0) {
2972 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')'));
2973 state.output = utils$1.escapeLast(state.output, '(');
2974 decrement('parens');
2975 }
2976
2977 while (state.braces > 0) {
2978 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}'));
2979 state.output = utils$1.escapeLast(state.output, '{');
2980 decrement('braces');
2981 }
2982
2983 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) {
2984 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` });
2985 }
2986
2987 // rebuild the output if we had to backtrack at any point
2988 if (state.backtrack === true) {
2989 state.output = '';
2990
2991 for (const token of state.tokens) {
2992 state.output += token.output != null ? token.output : token.value;
2993
2994 if (token.suffix) {
2995 state.output += token.suffix;
2996 }
2997 }
2998 }
2999
3000 return state;
3001};
3002
3003/**
3004 * Fast paths for creating regular expressions for common glob patterns.
3005 * This can significantly speed up processing and has very little downside
3006 * impact when none of the fast paths match.
3007 */
3008
3009parse$1.fastpaths = (input, options) => {
3010 const opts = { ...options };
3011 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$1, opts.maxLength) : MAX_LENGTH$1;
3012 const len = input.length;
3013 if (len > max) {
3014 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
3015 }
3016
3017 input = REPLACEMENTS[input] || input;
3018 const win32 = utils$1.isWindows(options);
3019
3020 // create constants based on platform, for windows or posix
3021 const {
3022 DOT_LITERAL,
3023 SLASH_LITERAL,
3024 ONE_CHAR,
3025 DOTS_SLASH,
3026 NO_DOT,
3027 NO_DOTS,
3028 NO_DOTS_SLASH,
3029 STAR,
3030 START_ANCHOR
3031 } = constants$1.globChars(win32);
3032
3033 const nodot = opts.dot ? NO_DOTS : NO_DOT;
3034 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
3035 const capture = opts.capture ? '' : '?:';
3036 const state = { negated: false, prefix: '' };
3037 let star = opts.bash === true ? '.*?' : STAR;
3038
3039 if (opts.capture) {
3040 star = `(${star})`;
3041 }
3042
3043 const globstar = (opts) => {
3044 if (opts.noglobstar === true) return star;
3045 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
3046 };
3047
3048 const create = str => {
3049 switch (str) {
3050 case '*':
3051 return `${nodot}${ONE_CHAR}${star}`;
3052
3053 case '.*':
3054 return `${DOT_LITERAL}${ONE_CHAR}${star}`;
3055
3056 case '*.*':
3057 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
3058
3059 case '*/*':
3060 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;
3061
3062 case '**':
3063 return nodot + globstar(opts);
3064
3065 case '**/*':
3066 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;
3067
3068 case '**/*.*':
3069 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
3070
3071 case '**/.*':
3072 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;
3073
3074 default: {
3075 const match = /^(.*?)\.(\w+)$/.exec(str);
3076 if (!match) return;
3077
3078 const source = create(match[1]);
3079 if (!source) return;
3080
3081 return source + DOT_LITERAL + match[2];
3082 }
3083 }
3084 };
3085
3086 const output = utils$1.removePrefix(input, state);
3087 let source = create(output);
3088
3089 if (source && opts.strictSlashes !== true) {
3090 source += `${SLASH_LITERAL}?`;
3091 }
3092
3093 return source;
3094};
3095
3096var parse_1$1 = parse$1;
3097
3098const isObject$1 = val => val && typeof val === 'object' && !Array.isArray(val);
3099
3100/**
3101 * Creates a matcher function from one or more glob patterns. The
3102 * returned function takes a string to match as its first argument,
3103 * and returns true if the string is a match. The returned matcher
3104 * function also takes a boolean as the second argument that, when true,
3105 * returns an object with additional information.
3106 *
3107 * ```js
3108 * const picomatch = require('picomatch');
3109 * // picomatch(glob[, options]);
3110 *
3111 * const isMatch = picomatch('*.!(*a)');
3112 * console.log(isMatch('a.a')); //=> false
3113 * console.log(isMatch('a.b')); //=> true
3114 * ```
3115 * @name picomatch
3116 * @param {String|Array} `globs` One or more glob patterns.
3117 * @param {Object=} `options`
3118 * @return {Function=} Returns a matcher function.
3119 * @api public
3120 */
3121
3122const picomatch = (glob, options, returnState = false) => {
3123 if (Array.isArray(glob)) {
3124 const fns = glob.map(input => picomatch(input, options, returnState));
3125 const arrayMatcher = str => {
3126 for (const isMatch of fns) {
3127 const state = isMatch(str);
3128 if (state) return state;
3129 }
3130 return false;
3131 };
3132 return arrayMatcher;
3133 }
3134
3135 const isState = isObject$1(glob) && glob.tokens && glob.input;
3136
3137 if (glob === '' || (typeof glob !== 'string' && !isState)) {
3138 throw new TypeError('Expected pattern to be a non-empty string');
3139 }
3140
3141 const opts = options || {};
3142 const posix = utils$1.isWindows(options);
3143 const regex = isState
3144 ? picomatch.compileRe(glob, options)
3145 : picomatch.makeRe(glob, options, false, true);
3146
3147 const state = regex.state;
3148 delete regex.state;
3149
3150 let isIgnored = () => false;
3151 if (opts.ignore) {
3152 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };
3153 isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
3154 }
3155
3156 const matcher = (input, returnObject = false) => {
3157 const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });
3158 const result = { glob, state, regex, posix, input, output, match, isMatch };
3159
3160 if (typeof opts.onResult === 'function') {
3161 opts.onResult(result);
3162 }
3163
3164 if (isMatch === false) {
3165 result.isMatch = false;
3166 return returnObject ? result : false;
3167 }
3168
3169 if (isIgnored(input)) {
3170 if (typeof opts.onIgnore === 'function') {
3171 opts.onIgnore(result);
3172 }
3173 result.isMatch = false;
3174 return returnObject ? result : false;
3175 }
3176
3177 if (typeof opts.onMatch === 'function') {
3178 opts.onMatch(result);
3179 }
3180 return returnObject ? result : true;
3181 };
3182
3183 if (returnState) {
3184 matcher.state = state;
3185 }
3186
3187 return matcher;
3188};
3189
3190/**
3191 * Test `input` with the given `regex`. This is used by the main
3192 * `picomatch()` function to test the input string.
3193 *
3194 * ```js
3195 * const picomatch = require('picomatch');
3196 * // picomatch.test(input, regex[, options]);
3197 *
3198 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
3199 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
3200 * ```
3201 * @param {String} `input` String to test.
3202 * @param {RegExp} `regex`
3203 * @return {Object} Returns an object with matching info.
3204 * @api public
3205 */
3206
3207picomatch.test = (input, regex, options, { glob, posix } = {}) => {
3208 if (typeof input !== 'string') {
3209 throw new TypeError('Expected input to be a string');
3210 }
3211
3212 if (input === '') {
3213 return { isMatch: false, output: '' };
3214 }
3215
3216 const opts = options || {};
3217 const format = opts.format || (posix ? utils$1.toPosixSlashes : null);
3218 let match = input === glob;
3219 let output = (match && format) ? format(input) : input;
3220
3221 if (match === false) {
3222 output = format ? format(input) : input;
3223 match = output === glob;
3224 }
3225
3226 if (match === false || opts.capture === true) {
3227 if (opts.matchBase === true || opts.basename === true) {
3228 match = picomatch.matchBase(input, regex, options, posix);
3229 } else {
3230 match = regex.exec(output);
3231 }
3232 }
3233
3234 return { isMatch: Boolean(match), match, output };
3235};
3236
3237/**
3238 * Match the basename of a filepath.
3239 *
3240 * ```js
3241 * const picomatch = require('picomatch');
3242 * // picomatch.matchBase(input, glob[, options]);
3243 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
3244 * ```
3245 * @param {String} `input` String to test.
3246 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).
3247 * @return {Boolean}
3248 * @api public
3249 */
3250
3251picomatch.matchBase = (input, glob, options, posix = utils$1.isWindows(options)) => {
3252 const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
3253 return regex.test(_events_commonjsExternal.sysPath.basename(input));
3254};
3255
3256/**
3257 * Returns true if **any** of the given glob `patterns` match the specified `string`.
3258 *
3259 * ```js
3260 * const picomatch = require('picomatch');
3261 * // picomatch.isMatch(string, patterns[, options]);
3262 *
3263 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
3264 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
3265 * ```
3266 * @param {String|Array} str The string to test.
3267 * @param {String|Array} patterns One or more glob patterns to use for matching.
3268 * @param {Object} [options] See available [options](#options).
3269 * @return {Boolean} Returns true if any patterns match `str`
3270 * @api public
3271 */
3272
3273picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
3274
3275/**
3276 * Parse a glob pattern to create the source string for a regular
3277 * expression.
3278 *
3279 * ```js
3280 * const picomatch = require('picomatch');
3281 * const result = picomatch.parse(pattern[, options]);
3282 * ```
3283 * @param {String} `pattern`
3284 * @param {Object} `options`
3285 * @return {Object} Returns an object with useful properties and output to be used as a regex source string.
3286 * @api public
3287 */
3288
3289picomatch.parse = (pattern, options) => {
3290 if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options));
3291 return parse_1$1(pattern, { ...options, fastpaths: false });
3292};
3293
3294/**
3295 * Scan a glob pattern to separate the pattern into segments.
3296 *
3297 * ```js
3298 * const picomatch = require('picomatch');
3299 * // picomatch.scan(input[, options]);
3300 *
3301 * const result = picomatch.scan('!./foo/*.js');
3302 * console.log(result);
3303 * { prefix: '!./',
3304 * input: '!./foo/*.js',
3305 * start: 3,
3306 * base: 'foo',
3307 * glob: '*.js',
3308 * isBrace: false,
3309 * isBracket: false,
3310 * isGlob: true,
3311 * isExtglob: false,
3312 * isGlobstar: false,
3313 * negated: true }
3314 * ```
3315 * @param {String} `input` Glob pattern to scan.
3316 * @param {Object} `options`
3317 * @return {Object} Returns an object with
3318 * @api public
3319 */
3320
3321picomatch.scan = (input, options) => scan_1(input, options);
3322
3323/**
3324 * Create a regular expression from a glob pattern.
3325 *
3326 * ```js
3327 * const picomatch = require('picomatch');
3328 * // picomatch.makeRe(input[, options]);
3329 *
3330 * console.log(picomatch.makeRe('*.js'));
3331 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
3332 * ```
3333 * @param {String} `input` A glob pattern to convert to regex.
3334 * @param {Object} `options`
3335 * @return {RegExp} Returns a regex created from the given pattern.
3336 * @api public
3337 */
3338
3339picomatch.compileRe = (parsed, options, returnOutput = false, returnState = false) => {
3340 if (returnOutput === true) {
3341 return parsed.output;
3342 }
3343
3344 const opts = options || {};
3345 const prepend = opts.contains ? '' : '^';
3346 const append = opts.contains ? '' : '$';
3347
3348 let source = `${prepend}(?:${parsed.output})${append}`;
3349 if (parsed && parsed.negated === true) {
3350 source = `^(?!${source}).*$`;
3351 }
3352
3353 const regex = picomatch.toRegex(source, options);
3354 if (returnState === true) {
3355 regex.state = parsed;
3356 }
3357
3358 return regex;
3359};
3360
3361picomatch.makeRe = (input, options, returnOutput = false, returnState = false) => {
3362 if (!input || typeof input !== 'string') {
3363 throw new TypeError('Expected a non-empty string');
3364 }
3365
3366 const opts = options || {};
3367 let parsed = { negated: false, fastpaths: true };
3368 let prefix = '';
3369 let output;
3370
3371 if (input.startsWith('./')) {
3372 input = input.slice(2);
3373 prefix = parsed.prefix = './';
3374 }
3375
3376 if (opts.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {
3377 output = parse_1$1.fastpaths(input, options);
3378 }
3379
3380 if (output === undefined) {
3381 parsed = parse_1$1(input, options);
3382 parsed.prefix = prefix + (parsed.prefix || '');
3383 } else {
3384 parsed.output = output;
3385 }
3386
3387 return picomatch.compileRe(parsed, options, returnOutput, returnState);
3388};
3389
3390/**
3391 * Create a regular expression from the given regex source string.
3392 *
3393 * ```js
3394 * const picomatch = require('picomatch');
3395 * // picomatch.toRegex(source[, options]);
3396 *
3397 * const { output } = picomatch.parse('*.js');
3398 * console.log(picomatch.toRegex(output));
3399 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
3400 * ```
3401 * @param {String} `source` Regular expression source string.
3402 * @param {Object} `options`
3403 * @return {RegExp}
3404 * @api public
3405 */
3406
3407picomatch.toRegex = (source, options) => {
3408 try {
3409 const opts = options || {};
3410 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));
3411 } catch (err) {
3412 if (options && options.debug === true) throw err;
3413 return /$^/;
3414 }
3415};
3416
3417/**
3418 * Picomatch constants.
3419 * @return {Object}
3420 */
3421
3422picomatch.constants = constants$1;
3423
3424/**
3425 * Expose "picomatch"
3426 */
3427
3428var picomatch_1 = picomatch;
3429
3430var picomatch$1 = picomatch_1;
3431
3432const isEmptyString = val => typeof val === 'string' && (val === '' || val === './');
3433
3434/**
3435 * Returns an array of strings that match one or more glob patterns.
3436 *
3437 * ```js
3438 * const mm = require('micromatch');
3439 * // mm(list, patterns[, options]);
3440 *
3441 * console.log(mm(['a.js', 'a.txt'], ['*.js']));
3442 * //=> [ 'a.js' ]
3443 * ```
3444 * @param {String|Array<string>} list List of strings to match.
3445 * @param {String|Array<string>} patterns One or more glob patterns to use for matching.
3446 * @param {Object} options See available [options](#options)
3447 * @return {Array} Returns an array of matches
3448 * @summary false
3449 * @api public
3450 */
3451
3452const micromatch = (list, patterns, options) => {
3453 patterns = [].concat(patterns);
3454 list = [].concat(list);
3455
3456 let omit = new Set();
3457 let keep = new Set();
3458 let items = new Set();
3459 let negatives = 0;
3460
3461 let onResult = state => {
3462 items.add(state.output);
3463 if (options && options.onResult) {
3464 options.onResult(state);
3465 }
3466 };
3467
3468 for (let i = 0; i < patterns.length; i++) {
3469 let isMatch = picomatch$1(String(patterns[i]), { ...options, onResult }, true);
3470 let negated = isMatch.state.negated || isMatch.state.negatedExtglob;
3471 if (negated) negatives++;
3472
3473 for (let item of list) {
3474 let matched = isMatch(item, true);
3475
3476 let match = negated ? !matched.isMatch : matched.isMatch;
3477 if (!match) continue;
3478
3479 if (negated) {
3480 omit.add(matched.output);
3481 } else {
3482 omit.delete(matched.output);
3483 keep.add(matched.output);
3484 }
3485 }
3486 }
3487
3488 let result = negatives === patterns.length ? [...items] : [...keep];
3489 let matches = result.filter(item => !omit.has(item));
3490
3491 if (options && matches.length === 0) {
3492 if (options.failglob === true) {
3493 throw new Error(`No matches found for "${patterns.join(', ')}"`);
3494 }
3495
3496 if (options.nonull === true || options.nullglob === true) {
3497 return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns;
3498 }
3499 }
3500
3501 return matches;
3502};
3503
3504/**
3505 * Backwards compatibility
3506 */
3507
3508micromatch.match = micromatch;
3509
3510/**
3511 * Returns a matcher function from the given glob `pattern` and `options`.
3512 * The returned function takes a string to match as its only argument and returns
3513 * true if the string is a match.
3514 *
3515 * ```js
3516 * const mm = require('micromatch');
3517 * // mm.matcher(pattern[, options]);
3518 *
3519 * const isMatch = mm.matcher('*.!(*a)');
3520 * console.log(isMatch('a.a')); //=> false
3521 * console.log(isMatch('a.b')); //=> true
3522 * ```
3523 * @param {String} `pattern` Glob pattern
3524 * @param {Object} `options`
3525 * @return {Function} Returns a matcher function.
3526 * @api public
3527 */
3528
3529micromatch.matcher = (pattern, options) => picomatch$1(pattern, options);
3530
3531/**
3532 * Returns true if **any** of the given glob `patterns` match the specified `string`.
3533 *
3534 * ```js
3535 * const mm = require('micromatch');
3536 * // mm.isMatch(string, patterns[, options]);
3537 *
3538 * console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true
3539 * console.log(mm.isMatch('a.a', 'b.*')); //=> false
3540 * ```
3541 * @param {String} str The string to test.
3542 * @param {String|Array} patterns One or more glob patterns to use for matching.
3543 * @param {Object} [options] See available [options](#options).
3544 * @return {Boolean} Returns true if any patterns match `str`
3545 * @api public
3546 */
3547
3548micromatch.isMatch = (str, patterns, options) => picomatch$1(patterns, options)(str);
3549
3550/**
3551 * Backwards compatibility
3552 */
3553
3554micromatch.any = micromatch.isMatch;
3555
3556/**
3557 * Returns a list of strings that _**do not match any**_ of the given `patterns`.
3558 *
3559 * ```js
3560 * const mm = require('micromatch');
3561 * // mm.not(list, patterns[, options]);
3562 *
3563 * console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a'));
3564 * //=> ['b.b', 'c.c']
3565 * ```
3566 * @param {Array} `list` Array of strings to match.
3567 * @param {String|Array} `patterns` One or more glob pattern to use for matching.
3568 * @param {Object} `options` See available [options](#options) for changing how matches are performed
3569 * @return {Array} Returns an array of strings that **do not match** the given patterns.
3570 * @api public
3571 */
3572
3573micromatch.not = (list, patterns, options = {}) => {
3574 patterns = [].concat(patterns).map(String);
3575 let result = new Set();
3576 let items = [];
3577
3578 let onResult = state => {
3579 if (options.onResult) options.onResult(state);
3580 items.push(state.output);
3581 };
3582
3583 let matches = micromatch(list, patterns, { ...options, onResult });
3584
3585 for (let item of items) {
3586 if (!matches.includes(item)) {
3587 result.add(item);
3588 }
3589 }
3590 return [...result];
3591};
3592
3593/**
3594 * Returns true if the given `string` contains the given pattern. Similar
3595 * to [.isMatch](#isMatch) but the pattern can match any part of the string.
3596 *
3597 * ```js
3598 * var mm = require('micromatch');
3599 * // mm.contains(string, pattern[, options]);
3600 *
3601 * console.log(mm.contains('aa/bb/cc', '*b'));
3602 * //=> true
3603 * console.log(mm.contains('aa/bb/cc', '*d'));
3604 * //=> false
3605 * ```
3606 * @param {String} `str` The string to match.
3607 * @param {String|Array} `patterns` Glob pattern to use for matching.
3608 * @param {Object} `options` See available [options](#options) for changing how matches are performed
3609 * @return {Boolean} Returns true if the patter matches any part of `str`.
3610 * @api public
3611 */
3612
3613micromatch.contains = (str, pattern, options) => {
3614 if (typeof str !== 'string') {
3615 throw new TypeError(`Expected a string: "${_events_commonjsExternal.require$$1.inspect(str)}"`);
3616 }
3617
3618 if (Array.isArray(pattern)) {
3619 return pattern.some(p => micromatch.contains(str, p, options));
3620 }
3621
3622 if (typeof pattern === 'string') {
3623 if (isEmptyString(str) || isEmptyString(pattern)) {
3624 return false;
3625 }
3626
3627 if (str.includes(pattern) || (str.startsWith('./') && str.slice(2).includes(pattern))) {
3628 return true;
3629 }
3630 }
3631
3632 return micromatch.isMatch(str, pattern, { ...options, contains: true });
3633};
3634
3635/**
3636 * Filter the keys of the given object with the given `glob` pattern
3637 * and `options`. Does not attempt to match nested keys. If you need this feature,
3638 * use [glob-object][] instead.
3639 *
3640 * ```js
3641 * const mm = require('micromatch');
3642 * // mm.matchKeys(object, patterns[, options]);
3643 *
3644 * const obj = { aa: 'a', ab: 'b', ac: 'c' };
3645 * console.log(mm.matchKeys(obj, '*b'));
3646 * //=> { ab: 'b' }
3647 * ```
3648 * @param {Object} `object` The object with keys to filter.
3649 * @param {String|Array} `patterns` One or more glob patterns to use for matching.
3650 * @param {Object} `options` See available [options](#options) for changing how matches are performed
3651 * @return {Object} Returns an object with only keys that match the given patterns.
3652 * @api public
3653 */
3654
3655micromatch.matchKeys = (obj, patterns, options) => {
3656 if (!utils$1.isObject(obj)) {
3657 throw new TypeError('Expected the first argument to be an object');
3658 }
3659 let keys = micromatch(Object.keys(obj), patterns, options);
3660 let res = {};
3661 for (let key of keys) res[key] = obj[key];
3662 return res;
3663};
3664
3665/**
3666 * Returns true if some of the strings in the given `list` match any of the given glob `patterns`.
3667 *
3668 * ```js
3669 * const mm = require('micromatch');
3670 * // mm.some(list, patterns[, options]);
3671 *
3672 * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js']));
3673 * // true
3674 * console.log(mm.some(['foo.js'], ['*.js', '!foo.js']));
3675 * // false
3676 * ```
3677 * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found.
3678 * @param {String|Array} `patterns` One or more glob patterns to use for matching.
3679 * @param {Object} `options` See available [options](#options) for changing how matches are performed
3680 * @return {Boolean} Returns true if any patterns match `str`
3681 * @api public
3682 */
3683
3684micromatch.some = (list, patterns, options) => {
3685 let items = [].concat(list);
3686
3687 for (let pattern of [].concat(patterns)) {
3688 let isMatch = picomatch$1(String(pattern), options);
3689 if (items.some(item => isMatch(item))) {
3690 return true;
3691 }
3692 }
3693 return false;
3694};
3695
3696/**
3697 * Returns true if every string in the given `list` matches
3698 * any of the given glob `patterns`.
3699 *
3700 * ```js
3701 * const mm = require('micromatch');
3702 * // mm.every(list, patterns[, options]);
3703 *
3704 * console.log(mm.every('foo.js', ['foo.js']));
3705 * // true
3706 * console.log(mm.every(['foo.js', 'bar.js'], ['*.js']));
3707 * // true
3708 * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js']));
3709 * // false
3710 * console.log(mm.every(['foo.js'], ['*.js', '!foo.js']));
3711 * // false
3712 * ```
3713 * @param {String|Array} `list` The string or array of strings to test.
3714 * @param {String|Array} `patterns` One or more glob patterns to use for matching.
3715 * @param {Object} `options` See available [options](#options) for changing how matches are performed
3716 * @return {Boolean} Returns true if any patterns match `str`
3717 * @api public
3718 */
3719
3720micromatch.every = (list, patterns, options) => {
3721 let items = [].concat(list);
3722
3723 for (let pattern of [].concat(patterns)) {
3724 let isMatch = picomatch$1(String(pattern), options);
3725 if (!items.every(item => isMatch(item))) {
3726 return false;
3727 }
3728 }
3729 return true;
3730};
3731
3732/**
3733 * Returns true if **all** of the given `patterns` match
3734 * the specified string.
3735 *
3736 * ```js
3737 * const mm = require('micromatch');
3738 * // mm.all(string, patterns[, options]);
3739 *
3740 * console.log(mm.all('foo.js', ['foo.js']));
3741 * // true
3742 *
3743 * console.log(mm.all('foo.js', ['*.js', '!foo.js']));
3744 * // false
3745 *
3746 * console.log(mm.all('foo.js', ['*.js', 'foo.js']));
3747 * // true
3748 *
3749 * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js']));
3750 * // true
3751 * ```
3752 * @param {String|Array} `str` The string to test.
3753 * @param {String|Array} `patterns` One or more glob patterns to use for matching.
3754 * @param {Object} `options` See available [options](#options) for changing how matches are performed
3755 * @return {Boolean} Returns true if any patterns match `str`
3756 * @api public
3757 */
3758
3759micromatch.all = (str, patterns, options) => {
3760 if (typeof str !== 'string') {
3761 throw new TypeError(`Expected a string: "${_events_commonjsExternal.require$$1.inspect(str)}"`);
3762 }
3763
3764 return [].concat(patterns).every(p => picomatch$1(p, options)(str));
3765};
3766
3767/**
3768 * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match.
3769 *
3770 * ```js
3771 * const mm = require('micromatch');
3772 * // mm.capture(pattern, string[, options]);
3773 *
3774 * console.log(mm.capture('test/*.js', 'test/foo.js'));
3775 * //=> ['foo']
3776 * console.log(mm.capture('test/*.js', 'foo/bar.css'));
3777 * //=> null
3778 * ```
3779 * @param {String} `glob` Glob pattern to use for matching.
3780 * @param {String} `input` String to match
3781 * @param {Object} `options` See available [options](#options) for changing how matches are performed
3782 * @return {Boolean} Returns an array of captures if the input matches the glob pattern, otherwise `null`.
3783 * @api public
3784 */
3785
3786micromatch.capture = (glob, input, options) => {
3787 let posix = utils$1.isWindows(options);
3788 let regex = picomatch$1.makeRe(String(glob), { ...options, capture: true });
3789 let match = regex.exec(posix ? utils$1.toPosixSlashes(input) : input);
3790
3791 if (match) {
3792 return match.slice(1).map(v => v === void 0 ? '' : v);
3793 }
3794};
3795
3796/**
3797 * Create a regular expression from the given glob `pattern`.
3798 *
3799 * ```js
3800 * const mm = require('micromatch');
3801 * // mm.makeRe(pattern[, options]);
3802 *
3803 * console.log(mm.makeRe('*.js'));
3804 * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/
3805 * ```
3806 * @param {String} `pattern` A glob pattern to convert to regex.
3807 * @param {Object} `options`
3808 * @return {RegExp} Returns a regex created from the given pattern.
3809 * @api public
3810 */
3811
3812micromatch.makeRe = (...args) => picomatch$1.makeRe(...args);
3813
3814/**
3815 * Scan a glob pattern to separate the pattern into segments. Used
3816 * by the [split](#split) method.
3817 *
3818 * ```js
3819 * const mm = require('micromatch');
3820 * const state = mm.scan(pattern[, options]);
3821 * ```
3822 * @param {String} `pattern`
3823 * @param {Object} `options`
3824 * @return {Object} Returns an object with
3825 * @api public
3826 */
3827
3828micromatch.scan = (...args) => picomatch$1.scan(...args);
3829
3830/**
3831 * Parse a glob pattern to create the source string for a regular
3832 * expression.
3833 *
3834 * ```js
3835 * const mm = require('micromatch');
3836 * const state = mm(pattern[, options]);
3837 * ```
3838 * @param {String} `glob`
3839 * @param {Object} `options`
3840 * @return {Object} Returns an object with useful properties and output to be used as regex source string.
3841 * @api public
3842 */
3843
3844micromatch.parse = (patterns, options) => {
3845 let res = [];
3846 for (let pattern of [].concat(patterns || [])) {
3847 for (let str of braces_1(String(pattern), options)) {
3848 res.push(picomatch$1.parse(str, options));
3849 }
3850 }
3851 return res;
3852};
3853
3854/**
3855 * Process the given brace `pattern`.
3856 *
3857 * ```js
3858 * const { braces } = require('micromatch');
3859 * console.log(braces('foo/{a,b,c}/bar'));
3860 * //=> [ 'foo/(a|b|c)/bar' ]
3861 *
3862 * console.log(braces('foo/{a,b,c}/bar', { expand: true }));
3863 * //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ]
3864 * ```
3865 * @param {String} `pattern` String with brace pattern to process.
3866 * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options.
3867 * @return {Array}
3868 * @api public
3869 */
3870
3871micromatch.braces = (pattern, options) => {
3872 if (typeof pattern !== 'string') throw new TypeError('Expected a string');
3873 if ((options && options.nobrace === true) || !/\{.*\}/.test(pattern)) {
3874 return [pattern];
3875 }
3876 return braces_1(pattern, options);
3877};
3878
3879/**
3880 * Expand braces
3881 */
3882
3883micromatch.braceExpand = (pattern, options) => {
3884 if (typeof pattern !== 'string') throw new TypeError('Expected a string');
3885 return micromatch.braces(pattern, { ...options, expand: true });
3886};
3887
3888/**
3889 * Expose micromatch
3890 */
3891
3892var micromatch_1 = micromatch;
3893
3894function ensureArray(thing) {
3895 if (Array.isArray(thing))
3896 return thing;
3897 if (thing == undefined)
3898 return [];
3899 return [thing];
3900}
3901
3902function getMatcherString(id, resolutionBase) {
3903 if (resolutionBase === false) {
3904 return id;
3905 }
3906 return path.resolve(...(typeof resolutionBase === 'string' ? [resolutionBase, id] : [id]));
3907}
3908const createFilter = function createFilter(include, exclude, options) {
3909 const resolutionBase = options && options.resolve;
3910 const getMatcher = (id) => {
3911 return id instanceof RegExp
3912 ? id
3913 : {
3914 test: micromatch_1.matcher(getMatcherString(id, resolutionBase)
3915 .split(path.sep)
3916 .join('/'), { dot: true })
3917 };
3918 };
3919 const includeMatchers = ensureArray(include).map(getMatcher);
3920 const excludeMatchers = ensureArray(exclude).map(getMatcher);
3921 return function (id) {
3922 if (typeof id !== 'string')
3923 return false;
3924 if (/\0/.test(id))
3925 return false;
3926 id = id.split(path.sep).join('/');
3927 for (let i = 0; i < excludeMatchers.length; ++i) {
3928 const matcher = excludeMatchers[i];
3929 if (matcher.test(id))
3930 return false;
3931 }
3932 for (let i = 0; i < includeMatchers.length; ++i) {
3933 const matcher = includeMatchers[i];
3934 if (matcher.test(id))
3935 return true;
3936 }
3937 return !includeMatchers.length;
3938 };
3939};
3940
3941const { Readable } = stream;
3942
3943const { promisify } = _events_commonjsExternal.require$$1;
3944
3945
3946const readdir = promisify(fs.readdir);
3947const stat = promisify(fs.stat);
3948const lstat = promisify(fs.lstat);
3949
3950/**
3951 * @typedef {Object} EntryInfo
3952 * @property {String} path
3953 * @property {String} fullPath
3954 * @property {fs.Stats=} stats
3955 * @property {fs.Dirent=} dirent
3956 * @property {String} basename
3957 */
3958
3959const BANG = '!';
3960const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP']);
3961const FILE_TYPE = 'files';
3962const DIR_TYPE = 'directories';
3963const FILE_DIR_TYPE = 'files_directories';
3964const EVERYTHING_TYPE = 'all';
3965const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE];
3966
3967const isNormalFlowError = error => NORMAL_FLOW_ERRORS.has(error.code);
3968
3969const normalizeFilter = filter => {
3970 if (filter === undefined) return;
3971 if (typeof filter === 'function') return filter;
3972
3973 if (typeof filter === 'string') {
3974 const glob = picomatch$1(filter.trim());
3975 return entry => glob(entry.basename);
3976 }
3977
3978 if (Array.isArray(filter)) {
3979 const positive = [];
3980 const negative = [];
3981 for (const item of filter) {
3982 const trimmed = item.trim();
3983 if (trimmed.charAt(0) === BANG) {
3984 negative.push(picomatch$1(trimmed.slice(1)));
3985 } else {
3986 positive.push(picomatch$1(trimmed));
3987 }
3988 }
3989
3990 if (negative.length > 0) {
3991 if (positive.length > 0) {
3992 return entry =>
3993 positive.some(f => f(entry.basename)) && !negative.some(f => f(entry.basename));
3994 }
3995 return entry => !negative.some(f => f(entry.basename));
3996 }
3997 return entry => positive.some(f => f(entry.basename));
3998 }
3999};
4000
4001class ReaddirpStream extends Readable {
4002 static get defaultOptions() {
4003 return {
4004 root: '.',
4005 /* eslint-disable no-unused-vars */
4006 fileFilter: (path) => true,
4007 directoryFilter: (path) => true,
4008 /* eslint-enable no-unused-vars */
4009 type: FILE_TYPE,
4010 lstat: false,
4011 depth: 2147483648,
4012 alwaysStat: false
4013 };
4014 }
4015
4016 constructor(options = {}) {
4017 super({
4018 objectMode: true,
4019 autoDestroy: true,
4020 highWaterMark: options.highWaterMark || 4096
4021 });
4022 const opts = { ...ReaddirpStream.defaultOptions, ...options };
4023 const { root, type } = opts;
4024
4025 this._fileFilter = normalizeFilter(opts.fileFilter);
4026 this._directoryFilter = normalizeFilter(opts.directoryFilter);
4027
4028 const statMethod = opts.lstat ? lstat : stat;
4029 // Use bigint stats if it's windows and stat() supports options (node 10+).
4030 if (process.platform === 'win32' && stat.length === 3) {
4031 this._stat = path => statMethod(path, { bigint: true });
4032 } else {
4033 this._stat = statMethod;
4034 }
4035
4036 this._maxDepth = opts.depth;
4037 this._wantsDir = [DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type);
4038 this._wantsFile = [FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type);
4039 this._wantsEverything = type === EVERYTHING_TYPE;
4040 this._root = _events_commonjsExternal.sysPath.resolve(root);
4041 this._isDirent = ('Dirent' in fs) && !opts.alwaysStat;
4042 this._statsProp = this._isDirent ? 'dirent' : 'stats';
4043 this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent };
4044
4045 // Launch stream with one parent, the root dir.
4046 try {
4047 this.parents = [this._exploreDir(root, 1)];
4048 } catch (error) {
4049 this.destroy(error);
4050 }
4051 this.reading = false;
4052 this.parent = undefined;
4053 }
4054
4055 async _read(batch) {
4056 if (this.reading) return;
4057 this.reading = true;
4058
4059 try {
4060 while (!this.destroyed && batch > 0) {
4061 const { path, depth, files = [] } = this.parent || {};
4062
4063 if (files.length > 0) {
4064 const slice = files.splice(0, batch).map(dirent => this._formatEntry(dirent, path));
4065 for (const entry of await Promise.all(slice)) {
4066 if (this._isDirAndMatchesFilter(entry)) {
4067 if (depth <= this._maxDepth) {
4068 this.parents.push(this._exploreDir(entry.fullPath, depth + 1));
4069 }
4070
4071 if (this._wantsDir) {
4072 this.push(entry);
4073 batch--;
4074 }
4075 } else if (this._isFileAndMatchesFilter(entry)) {
4076 if (this._wantsFile) {
4077 this.push(entry);
4078 batch--;
4079 }
4080 }
4081 }
4082 } else {
4083 const parent = this.parents.pop();
4084 if (!parent) {
4085 this.push(null);
4086 break;
4087 }
4088 this.parent = await parent;
4089 }
4090 }
4091 } catch (error) {
4092 this.destroy(error);
4093 } finally {
4094 this.reading = false;
4095 }
4096 }
4097
4098 async _exploreDir(path, depth) {
4099 let files;
4100 try {
4101 files = await readdir(path, this._rdOptions);
4102 } catch (error) {
4103 this._onError(error);
4104 }
4105 return {files, depth, path};
4106 }
4107
4108 async _formatEntry(dirent, path) {
4109 const basename = this._isDirent ? dirent.name : dirent;
4110 const fullPath = _events_commonjsExternal.sysPath.resolve(_events_commonjsExternal.sysPath.join(path, basename));
4111 const entry = {path: _events_commonjsExternal.sysPath.relative(this._root, fullPath), fullPath, basename};
4112 try {
4113 entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
4114 } catch (err) {
4115 this._onError(err);
4116 }
4117 return entry;
4118 }
4119
4120 _onError(err) {
4121 if (isNormalFlowError(err) && !this.destroyed) {
4122 this.emit('warn', err);
4123 } else {
4124 throw err;
4125 }
4126 }
4127
4128 _isDirAndMatchesFilter(entry) {
4129 // entry may be undefined, because a warning or an error were emitted
4130 // and the statsProp is undefined
4131 const stats = entry && entry[this._statsProp];
4132 return stats && stats.isDirectory() && this._directoryFilter(entry);
4133 }
4134
4135 _isFileAndMatchesFilter(entry) {
4136 const stats = entry && entry[this._statsProp];
4137 const isFileType = stats && (
4138 (this._wantsEverything && !stats.isDirectory()) ||
4139 (stats.isFile() || stats.isSymbolicLink())
4140 );
4141 return isFileType && this._fileFilter(entry);
4142 }
4143}
4144
4145/**
4146 * @typedef {Object} ReaddirpArguments
4147 * @property {Function=} fileFilter
4148 * @property {Function=} directoryFilter
4149 * @property {String=} type
4150 * @property {Number=} depth
4151 * @property {String=} root
4152 * @property {Boolean=} lstat
4153 * @property {Boolean=} bigint
4154 */
4155
4156/**
4157 * Main function which ends up calling readdirRec and reads all files and directories in given root recursively.
4158 * @param {String} root Root directory
4159 * @param {ReaddirpArguments=} options Options to specify root (start directory), filters and recursion depth
4160 */
4161const readdirp = (root, options = {}) => {
4162 let type = options.entryType || options.type;
4163 if (type === 'both') type = FILE_DIR_TYPE; // backwards-compatibility
4164 if (type) options.type = type;
4165 if (!root) {
4166 throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)');
4167 } else if (typeof root !== 'string') {
4168 throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)');
4169 } else if (type && !ALL_TYPES.includes(type)) {
4170 throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`);
4171 }
4172
4173 options.root = root;
4174 return new ReaddirpStream(options);
4175};
4176
4177const readdirpPromise = (root, options = {}) => {
4178 return new Promise((resolve, reject) => {
4179 const files = [];
4180 readdirp(root, options)
4181 .on('data', entry => files.push(entry))
4182 .on('end', () => resolve(files))
4183 .on('error', error => reject(error));
4184 });
4185};
4186
4187readdirp.promise = readdirpPromise;
4188readdirp.ReaddirpStream = ReaddirpStream;
4189readdirp.default = readdirp;
4190
4191var readdirp_1 = readdirp;
4192
4193/*!
4194 * normalize-path <https://github.com/jonschlinkert/normalize-path>
4195 *
4196 * Copyright (c) 2014-2018, Jon Schlinkert.
4197 * Released under the MIT License.
4198 */
4199
4200var normalizePath = function(path, stripTrailing) {
4201 if (typeof path !== 'string') {
4202 throw new TypeError('expected path to be a string');
4203 }
4204
4205 if (path === '\\' || path === '/') return '/';
4206
4207 var len = path.length;
4208 if (len <= 1) return path;
4209
4210 // ensure that win32 namespaces has two leading slashes, so that the path is
4211 // handled properly by the win32 version of path.parse() after being normalized
4212 // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces
4213 var prefix = '';
4214 if (len > 4 && path[3] === '\\') {
4215 var ch = path[2];
4216 if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') {
4217 path = path.slice(2);
4218 prefix = '//';
4219 }
4220 }
4221
4222 var segs = path.split(/[/\\]+/);
4223 if (stripTrailing !== false && segs[segs.length - 1] === '') {
4224 segs.pop();
4225 }
4226 return prefix + segs.join('/');
4227};
4228
4229var anymatch_1 = rollup_js.createCommonjsModule(function (module, exports) {
4230
4231Object.defineProperty(exports, "__esModule", { value: true });
4232
4233
4234
4235
4236/**
4237 * @typedef {(testString: string) => boolean} AnymatchFn
4238 * @typedef {string|RegExp|AnymatchFn} AnymatchPattern
4239 * @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher
4240 */
4241const BANG = '!';
4242const DEFAULT_OPTIONS = {returnIndex: false};
4243const arrify = (item) => Array.isArray(item) ? item : [item];
4244
4245/**
4246 * @param {AnymatchPattern} matcher
4247 * @param {object} options
4248 * @returns {AnymatchFn}
4249 */
4250const createPattern = (matcher, options) => {
4251 if (typeof matcher === 'function') {
4252 return matcher;
4253 }
4254 if (typeof matcher === 'string') {
4255 const glob = picomatch$1(matcher, options);
4256 return (string) => matcher === string || glob(string);
4257 }
4258 if (matcher instanceof RegExp) {
4259 return (string) => matcher.test(string);
4260 }
4261 return (string) => false;
4262};
4263
4264/**
4265 * @param {Array<Function>} patterns
4266 * @param {Array<Function>} negPatterns
4267 * @param {String|Array} args
4268 * @param {Boolean} returnIndex
4269 * @returns {boolean|number}
4270 */
4271const matchPatterns = (patterns, negPatterns, args, returnIndex) => {
4272 const isList = Array.isArray(args);
4273 const _path = isList ? args[0] : args;
4274 if (!isList && typeof _path !== 'string') {
4275 throw new TypeError('anymatch: second argument must be a string: got ' +
4276 Object.prototype.toString.call(_path))
4277 }
4278 const path = normalizePath(_path);
4279
4280 for (let index = 0; index < negPatterns.length; index++) {
4281 const nglob = negPatterns[index];
4282 if (nglob(path)) {
4283 return returnIndex ? -1 : false;
4284 }
4285 }
4286
4287 const applied = isList && [path].concat(args.slice(1));
4288 for (let index = 0; index < patterns.length; index++) {
4289 const pattern = patterns[index];
4290 if (isList ? pattern(...applied) : pattern(path)) {
4291 return returnIndex ? index : true;
4292 }
4293 }
4294
4295 return returnIndex ? -1 : false;
4296};
4297
4298/**
4299 * @param {AnymatchMatcher} matchers
4300 * @param {Array|string} testString
4301 * @param {object} options
4302 * @returns {boolean|number|Function}
4303 */
4304const anymatch = (matchers, testString, options = DEFAULT_OPTIONS) => {
4305 if (matchers == null) {
4306 throw new TypeError('anymatch: specify first argument');
4307 }
4308 const opts = typeof options === 'boolean' ? {returnIndex: options} : options;
4309 const returnIndex = opts.returnIndex || false;
4310
4311 // Early cache for matchers.
4312 const mtchers = arrify(matchers);
4313 const negatedGlobs = mtchers
4314 .filter(item => typeof item === 'string' && item.charAt(0) === BANG)
4315 .map(item => item.slice(1))
4316 .map(item => picomatch$1(item, opts));
4317 const patterns = mtchers.map(matcher => createPattern(matcher, opts));
4318
4319 if (testString == null) {
4320 return (testString, ri = false) => {
4321 const returnIndex = typeof ri === 'boolean' ? ri : false;
4322 return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
4323 }
4324 }
4325
4326 return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
4327};
4328
4329anymatch.default = anymatch;
4330module.exports = anymatch;
4331});
4332
4333rollup_js.unwrapExports(anymatch_1);
4334
4335/*!
4336 * is-extglob <https://github.com/jonschlinkert/is-extglob>
4337 *
4338 * Copyright (c) 2014-2016, Jon Schlinkert.
4339 * Licensed under the MIT License.
4340 */
4341
4342var isExtglob = function isExtglob(str) {
4343 if (typeof str !== 'string' || str === '') {
4344 return false;
4345 }
4346
4347 var match;
4348 while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) {
4349 if (match[2]) return true;
4350 str = str.slice(match.index + match[0].length);
4351 }
4352
4353 return false;
4354};
4355
4356/*!
4357 * is-glob <https://github.com/jonschlinkert/is-glob>
4358 *
4359 * Copyright (c) 2014-2017, Jon Schlinkert.
4360 * Released under the MIT License.
4361 */
4362
4363
4364var chars = { '{': '}', '(': ')', '[': ']'};
4365var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/;
4366var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/;
4367
4368var isGlob = function isGlob(str, options) {
4369 if (typeof str !== 'string' || str === '') {
4370 return false;
4371 }
4372
4373 if (isExtglob(str)) {
4374 return true;
4375 }
4376
4377 var regex = strictRegex;
4378 var match;
4379
4380 // optionally relax regex
4381 if (options && options.strict === false) {
4382 regex = relaxedRegex;
4383 }
4384
4385 while ((match = regex.exec(str))) {
4386 if (match[2]) return true;
4387 var idx = match.index + match[0].length;
4388
4389 // if an open bracket/brace/paren is escaped,
4390 // set the index to the next closing character
4391 var open = match[1];
4392 var close = open ? chars[open] : null;
4393 if (open && close) {
4394 var n = str.indexOf(close, idx);
4395 if (n !== -1) {
4396 idx = n + 1;
4397 }
4398 }
4399
4400 str = str.slice(idx);
4401 }
4402 return false;
4403};
4404
4405var pathPosixDirname = _events_commonjsExternal.sysPath.posix.dirname;
4406var isWin32 = os.platform() === 'win32';
4407
4408var slash = '/';
4409var backslash = /\\/g;
4410var enclosure = /[\{\[].*[\/]*.*[\}\]]$/;
4411var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/;
4412var escaped = /\\([\*\?\|\[\]\(\)\{\}])/g;
4413
4414/**
4415 * @param {string} str
4416 * @param {Object} opts
4417 * @param {boolean} [opts.flipBackslashes=true]
4418 */
4419var globParent = function globParent(str, opts) {
4420 var options = Object.assign({ flipBackslashes: true }, opts);
4421
4422 // flip windows path separators
4423 if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) {
4424 str = str.replace(backslash, slash);
4425 }
4426
4427 // special case for strings ending in enclosure containing path separator
4428 if (enclosure.test(str)) {
4429 str += slash;
4430 }
4431
4432 // preserves full path in case of trailing path separator
4433 str += 'a';
4434
4435 // remove path parts that are globby
4436 do {
4437 str = pathPosixDirname(str);
4438 } while (isGlob(str) || globby.test(str));
4439
4440 // remove escape chars and return result
4441 return str.replace(escaped, '$1');
4442};
4443
4444var binaryExtensions = [
4445 "3dm",
4446 "3ds",
4447 "3g2",
4448 "3gp",
4449 "7z",
4450 "a",
4451 "aac",
4452 "adp",
4453 "ai",
4454 "aif",
4455 "aiff",
4456 "alz",
4457 "ape",
4458 "apk",
4459 "ar",
4460 "arj",
4461 "asf",
4462 "au",
4463 "avi",
4464 "bak",
4465 "baml",
4466 "bh",
4467 "bin",
4468 "bk",
4469 "bmp",
4470 "btif",
4471 "bz2",
4472 "bzip2",
4473 "cab",
4474 "caf",
4475 "cgm",
4476 "class",
4477 "cmx",
4478 "cpio",
4479 "cr2",
4480 "cur",
4481 "dat",
4482 "dcm",
4483 "deb",
4484 "dex",
4485 "djvu",
4486 "dll",
4487 "dmg",
4488 "dng",
4489 "doc",
4490 "docm",
4491 "docx",
4492 "dot",
4493 "dotm",
4494 "dra",
4495 "DS_Store",
4496 "dsk",
4497 "dts",
4498 "dtshd",
4499 "dvb",
4500 "dwg",
4501 "dxf",
4502 "ecelp4800",
4503 "ecelp7470",
4504 "ecelp9600",
4505 "egg",
4506 "eol",
4507 "eot",
4508 "epub",
4509 "exe",
4510 "f4v",
4511 "fbs",
4512 "fh",
4513 "fla",
4514 "flac",
4515 "fli",
4516 "flv",
4517 "fpx",
4518 "fst",
4519 "fvt",
4520 "g3",
4521 "gh",
4522 "gif",
4523 "graffle",
4524 "gz",
4525 "gzip",
4526 "h261",
4527 "h263",
4528 "h264",
4529 "icns",
4530 "ico",
4531 "ief",
4532 "img",
4533 "ipa",
4534 "iso",
4535 "jar",
4536 "jpeg",
4537 "jpg",
4538 "jpgv",
4539 "jpm",
4540 "jxr",
4541 "key",
4542 "ktx",
4543 "lha",
4544 "lib",
4545 "lvp",
4546 "lz",
4547 "lzh",
4548 "lzma",
4549 "lzo",
4550 "m3u",
4551 "m4a",
4552 "m4v",
4553 "mar",
4554 "mdi",
4555 "mht",
4556 "mid",
4557 "midi",
4558 "mj2",
4559 "mka",
4560 "mkv",
4561 "mmr",
4562 "mng",
4563 "mobi",
4564 "mov",
4565 "movie",
4566 "mp3",
4567 "mp4",
4568 "mp4a",
4569 "mpeg",
4570 "mpg",
4571 "mpga",
4572 "mxu",
4573 "nef",
4574 "npx",
4575 "numbers",
4576 "nupkg",
4577 "o",
4578 "oga",
4579 "ogg",
4580 "ogv",
4581 "otf",
4582 "pages",
4583 "pbm",
4584 "pcx",
4585 "pdb",
4586 "pdf",
4587 "pea",
4588 "pgm",
4589 "pic",
4590 "png",
4591 "pnm",
4592 "pot",
4593 "potm",
4594 "potx",
4595 "ppa",
4596 "ppam",
4597 "ppm",
4598 "pps",
4599 "ppsm",
4600 "ppsx",
4601 "ppt",
4602 "pptm",
4603 "pptx",
4604 "psd",
4605 "pya",
4606 "pyc",
4607 "pyo",
4608 "pyv",
4609 "qt",
4610 "rar",
4611 "ras",
4612 "raw",
4613 "resources",
4614 "rgb",
4615 "rip",
4616 "rlc",
4617 "rmf",
4618 "rmvb",
4619 "rtf",
4620 "rz",
4621 "s3m",
4622 "s7z",
4623 "scpt",
4624 "sgi",
4625 "shar",
4626 "sil",
4627 "sketch",
4628 "slk",
4629 "smv",
4630 "snk",
4631 "so",
4632 "stl",
4633 "suo",
4634 "sub",
4635 "swf",
4636 "tar",
4637 "tbz",
4638 "tbz2",
4639 "tga",
4640 "tgz",
4641 "thmx",
4642 "tif",
4643 "tiff",
4644 "tlz",
4645 "ttc",
4646 "ttf",
4647 "txz",
4648 "udf",
4649 "uvh",
4650 "uvi",
4651 "uvm",
4652 "uvp",
4653 "uvs",
4654 "uvu",
4655 "viv",
4656 "vob",
4657 "war",
4658 "wav",
4659 "wax",
4660 "wbmp",
4661 "wdp",
4662 "weba",
4663 "webm",
4664 "webp",
4665 "whl",
4666 "wim",
4667 "wm",
4668 "wma",
4669 "wmv",
4670 "wmx",
4671 "woff",
4672 "woff2",
4673 "wrm",
4674 "wvx",
4675 "xbm",
4676 "xif",
4677 "xla",
4678 "xlam",
4679 "xls",
4680 "xlsb",
4681 "xlsm",
4682 "xlsx",
4683 "xlt",
4684 "xltm",
4685 "xltx",
4686 "xm",
4687 "xmind",
4688 "xpi",
4689 "xpm",
4690 "xwd",
4691 "xz",
4692 "z",
4693 "zip",
4694 "zipx"
4695];
4696
4697var binaryExtensions$1 = {
4698 __proto__: null,
4699 'default': binaryExtensions
4700};
4701
4702var require$$0 = rollup_js.getCjsExportFromNamespace(binaryExtensions$1);
4703
4704var binaryExtensions$2 = require$$0;
4705
4706const extensions = new Set(binaryExtensions$2);
4707
4708var isBinaryPath = filePath => extensions.has(_events_commonjsExternal.sysPath.extname(filePath).slice(1).toLowerCase());
4709
4710var constants$2 = rollup_js.createCommonjsModule(function (module, exports) {
4711
4712const {sep} = _events_commonjsExternal.sysPath;
4713const {platform} = process;
4714
4715exports.EV_ALL = 'all';
4716exports.EV_READY = 'ready';
4717exports.EV_ADD = 'add';
4718exports.EV_CHANGE = 'change';
4719exports.EV_ADD_DIR = 'addDir';
4720exports.EV_UNLINK = 'unlink';
4721exports.EV_UNLINK_DIR = 'unlinkDir';
4722exports.EV_RAW = 'raw';
4723exports.EV_ERROR = 'error';
4724
4725exports.STR_DATA = 'data';
4726exports.STR_END = 'end';
4727exports.STR_CLOSE = 'close';
4728
4729exports.FSEVENT_CREATED = 'created';
4730exports.FSEVENT_MODIFIED = 'modified';
4731exports.FSEVENT_DELETED = 'deleted';
4732exports.FSEVENT_MOVED = 'moved';
4733exports.FSEVENT_CLONED = 'cloned';
4734exports.FSEVENT_UNKNOWN = 'unknown';
4735exports.FSEVENT_TYPE_DIRECTORY = 'directory';
4736exports.FSEVENT_TYPE_SYMLINK = 'symlink';
4737
4738exports.KEY_LISTENERS = 'listeners';
4739exports.KEY_ERR = 'errHandlers';
4740exports.KEY_RAW = 'rawEmitters';
4741exports.HANDLER_KEYS = [exports.KEY_LISTENERS, exports.KEY_ERR, exports.KEY_RAW];
4742
4743exports.DOT_SLASH = `.${sep}`;
4744
4745exports.BACK_SLASH_RE = /\\/g;
4746exports.DOUBLE_SLASH_RE = /\/\//;
4747exports.SLASH_OR_BACK_SLASH_RE = /[/\\]/;
4748exports.DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/;
4749exports.REPLACER_RE = /^\.[/\\]/;
4750
4751exports.SLASH = '/';
4752exports.BRACE_START = '{';
4753exports.BANG = '!';
4754exports.ONE_DOT = '.';
4755exports.TWO_DOTS = '..';
4756exports.STAR = '*';
4757exports.GLOBSTAR = '**';
4758exports.ROOT_GLOBSTAR = '/**/*';
4759exports.SLASH_GLOBSTAR = '/**';
4760exports.DIR_SUFFIX = 'Dir';
4761exports.ANYMATCH_OPTS = {dot: true};
4762exports.STRING_TYPE = 'string';
4763exports.FUNCTION_TYPE = 'function';
4764exports.EMPTY_STR = '';
4765exports.EMPTY_FN = () => {};
4766exports.IDENTITY_FN = val => val;
4767
4768exports.isWindows = platform === 'win32';
4769exports.isMacos = platform === 'darwin';
4770});
4771
4772const { promisify: promisify$1 } = _events_commonjsExternal.require$$1;
4773
4774const {
4775 isWindows,
4776 EMPTY_FN,
4777 EMPTY_STR,
4778 KEY_LISTENERS,
4779 KEY_ERR,
4780 KEY_RAW,
4781 HANDLER_KEYS,
4782 EV_CHANGE,
4783 EV_ADD,
4784 EV_ADD_DIR,
4785 EV_ERROR,
4786 STR_DATA,
4787 STR_END,
4788 BRACE_START,
4789 STAR: STAR$1
4790} = constants$2;
4791
4792const THROTTLE_MODE_WATCH = 'watch';
4793
4794const open = promisify$1(fs.open);
4795const stat$1 = promisify$1(fs.stat);
4796const lstat$1 = promisify$1(fs.lstat);
4797const close = promisify$1(fs.close);
4798const fsrealpath = promisify$1(fs.realpath);
4799
4800const statMethods = { lstat: lstat$1, stat: stat$1 };
4801
4802// TODO: emit errors properly. Example: EMFILE on Macos.
4803const foreach = (val, fn) => {
4804 if (val instanceof Set) {
4805 val.forEach(fn);
4806 } else {
4807 fn(val);
4808 }
4809};
4810
4811const addAndConvert = (main, prop, item) => {
4812 let container = main[prop];
4813 if (!(container instanceof Set)) {
4814 main[prop] = container = new Set([container]);
4815 }
4816 container.add(item);
4817};
4818
4819const clearItem = cont => key => {
4820 const set = cont[key];
4821 if (set instanceof Set) {
4822 set.clear();
4823 } else {
4824 delete cont[key];
4825 }
4826};
4827
4828const delFromSet = (main, prop, item) => {
4829 const container = main[prop];
4830 if (container instanceof Set) {
4831 container.delete(item);
4832 } else if (container === item) {
4833 delete main[prop];
4834 }
4835};
4836
4837const isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
4838
4839/**
4840 * @typedef {String} Path
4841 */
4842
4843// fs_watch helpers
4844
4845// object to hold per-process fs_watch instances
4846// (may be shared across chokidar FSWatcher instances)
4847
4848/**
4849 * @typedef {Object} FsWatchContainer
4850 * @property {Set} listeners
4851 * @property {Set} errHandlers
4852 * @property {Set} rawEmitters
4853 * @property {fs.FSWatcher=} watcher
4854 * @property {Boolean=} watcherUnusable
4855 */
4856
4857/**
4858 * @type {Map<String,FsWatchContainer>}
4859 */
4860const FsWatchInstances = new Map();
4861
4862/**
4863 * Instantiates the fs_watch interface
4864 * @param {String} path to be watched
4865 * @param {Object} options to be passed to fs_watch
4866 * @param {Function} listener main event handler
4867 * @param {Function} errHandler emits info about errors
4868 * @param {Function} emitRaw emits raw event data
4869 * @returns {fs.FSWatcher} new fsevents instance
4870 */
4871function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
4872 const handleEvent = (rawEvent, evPath) => {
4873 listener(path);
4874 emitRaw(rawEvent, evPath, {watchedPath: path});
4875
4876 // emit based on events occurring for files from a directory's watcher in
4877 // case the file's watcher misses it (and rely on throttling to de-dupe)
4878 if (evPath && path !== evPath) {
4879 fsWatchBroadcast(
4880 _events_commonjsExternal.sysPath.resolve(path, evPath), KEY_LISTENERS, _events_commonjsExternal.sysPath.join(path, evPath)
4881 );
4882 }
4883 };
4884 try {
4885 return fs.watch(path, options, handleEvent);
4886 } catch (error) {
4887 errHandler(error);
4888 }
4889}
4890
4891/**
4892 * Helper for passing fs_watch event data to a collection of listeners
4893 * @param {Path} fullPath absolute path bound to fs_watch instance
4894 * @param {String} type listener type
4895 * @param {*=} val1 arguments to be passed to listeners
4896 * @param {*=} val2
4897 * @param {*=} val3
4898 */
4899const fsWatchBroadcast = (fullPath, type, val1, val2, val3) => {
4900 const cont = FsWatchInstances.get(fullPath);
4901 if (!cont) return;
4902 foreach(cont[type], (listener) => {
4903 listener(val1, val2, val3);
4904 });
4905};
4906
4907/**
4908 * Instantiates the fs_watch interface or binds listeners
4909 * to an existing one covering the same file system entry
4910 * @param {String} path
4911 * @param {String} fullPath absolute path
4912 * @param {Object} options to be passed to fs_watch
4913 * @param {Object} handlers container for event listener functions
4914 */
4915const setFsWatchListener = (path, fullPath, options, handlers) => {
4916 const {listener, errHandler, rawEmitter} = handlers;
4917 let cont = FsWatchInstances.get(fullPath);
4918
4919 /** @type {fs.FSWatcher=} */
4920 let watcher;
4921 if (!options.persistent) {
4922 watcher = createFsWatchInstance(
4923 path, options, listener, errHandler, rawEmitter
4924 );
4925 return watcher.close.bind(watcher);
4926 }
4927 if (cont) {
4928 addAndConvert(cont, KEY_LISTENERS, listener);
4929 addAndConvert(cont, KEY_ERR, errHandler);
4930 addAndConvert(cont, KEY_RAW, rawEmitter);
4931 } else {
4932 watcher = createFsWatchInstance(
4933 path,
4934 options,
4935 fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
4936 errHandler, // no need to use broadcast here
4937 fsWatchBroadcast.bind(null, fullPath, KEY_RAW)
4938 );
4939 if (!watcher) return;
4940 watcher.on(EV_ERROR, async (error) => {
4941 const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR);
4942 cont.watcherUnusable = true; // documented since Node 10.4.1
4943 // Workaround for https://github.com/joyent/node/issues/4337
4944 if (isWindows && error.code === 'EPERM') {
4945 try {
4946 const fd = await open(path, 'r');
4947 await close(fd);
4948 broadcastErr(error);
4949 } catch (err) {}
4950 } else {
4951 broadcastErr(error);
4952 }
4953 });
4954 cont = {
4955 listeners: listener,
4956 errHandlers: errHandler,
4957 rawEmitters: rawEmitter,
4958 watcher
4959 };
4960 FsWatchInstances.set(fullPath, cont);
4961 }
4962 // const index = cont.listeners.indexOf(listener);
4963
4964 // removes this instance's listeners and closes the underlying fs_watch
4965 // instance if there are no more listeners left
4966 return () => {
4967 delFromSet(cont, KEY_LISTENERS, listener);
4968 delFromSet(cont, KEY_ERR, errHandler);
4969 delFromSet(cont, KEY_RAW, rawEmitter);
4970 if (isEmptySet(cont.listeners)) {
4971 // Check to protect against issue gh-730.
4972 // if (cont.watcherUnusable) {
4973 cont.watcher.close();
4974 // }
4975 FsWatchInstances.delete(fullPath);
4976 HANDLER_KEYS.forEach(clearItem(cont));
4977 cont.watcher = undefined;
4978 Object.freeze(cont);
4979 }
4980 };
4981};
4982
4983// fs_watchFile helpers
4984
4985// object to hold per-process fs_watchFile instances
4986// (may be shared across chokidar FSWatcher instances)
4987const FsWatchFileInstances = new Map();
4988
4989/**
4990 * Instantiates the fs_watchFile interface or binds listeners
4991 * to an existing one covering the same file system entry
4992 * @param {String} path to be watched
4993 * @param {String} fullPath absolute path
4994 * @param {Object} options options to be passed to fs_watchFile
4995 * @param {Object} handlers container for event listener functions
4996 * @returns {Function} closer
4997 */
4998const setFsWatchFileListener = (path, fullPath, options, handlers) => {
4999 const {listener, rawEmitter} = handlers;
5000 let cont = FsWatchFileInstances.get(fullPath);
5001
5002 const copts = cont && cont.options;
5003 if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
5004 fs.unwatchFile(fullPath);
5005 cont = undefined;
5006 }
5007
5008 /* eslint-enable no-unused-vars, prefer-destructuring */
5009
5010 if (cont) {
5011 addAndConvert(cont, KEY_LISTENERS, listener);
5012 addAndConvert(cont, KEY_RAW, rawEmitter);
5013 } else {
5014 // TODO
5015 // listeners.add(listener);
5016 // rawEmitters.add(rawEmitter);
5017 cont = {
5018 listeners: listener,
5019 rawEmitters: rawEmitter,
5020 options,
5021 watcher: fs.watchFile(fullPath, options, (curr, prev) => {
5022 foreach(cont.rawEmitters, (rawEmitter) => {
5023 rawEmitter(EV_CHANGE, fullPath, {curr, prev});
5024 });
5025 const currmtime = curr.mtimeMs;
5026 if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
5027 foreach(cont.listeners, (listener) => listener(path, curr));
5028 }
5029 })
5030 };
5031 FsWatchFileInstances.set(fullPath, cont);
5032 }
5033 // const index = cont.listeners.indexOf(listener);
5034
5035 // Removes this instance's listeners and closes the underlying fs_watchFile
5036 // instance if there are no more listeners left.
5037 return () => {
5038 delFromSet(cont, KEY_LISTENERS, listener);
5039 delFromSet(cont, KEY_RAW, rawEmitter);
5040 if (isEmptySet(cont.listeners)) {
5041 FsWatchFileInstances.delete(fullPath);
5042 fs.unwatchFile(fullPath);
5043 cont.options = cont.watcher = undefined;
5044 Object.freeze(cont);
5045 }
5046 };
5047};
5048
5049/**
5050 * @mixin
5051 */
5052class NodeFsHandler {
5053
5054/**
5055 * @param {import("../index").FSWatcher} fsW
5056 */
5057constructor(fsW) {
5058 this.fsw = fsW;
5059 this._boundHandleError = (error) => fsW._handleError(error);
5060}
5061
5062/**
5063 * Watch file for changes with fs_watchFile or fs_watch.
5064 * @param {String} path to file or dir
5065 * @param {Function} listener on fs change
5066 * @returns {Function} closer for the watcher instance
5067 */
5068_watchWithNodeFs(path, listener) {
5069 const opts = this.fsw.options;
5070 const directory = _events_commonjsExternal.sysPath.dirname(path);
5071 const basename = _events_commonjsExternal.sysPath.basename(path);
5072 const parent = this.fsw._getWatchedDir(directory);
5073 parent.add(basename);
5074 const absolutePath = _events_commonjsExternal.sysPath.resolve(path);
5075 const options = {persistent: opts.persistent};
5076 if (!listener) listener = EMPTY_FN;
5077
5078 let closer;
5079 if (opts.usePolling) {
5080 options.interval = opts.enableBinaryInterval && isBinaryPath(basename) ?
5081 opts.binaryInterval : opts.interval;
5082 closer = setFsWatchFileListener(path, absolutePath, options, {
5083 listener,
5084 rawEmitter: this.fsw._emitRaw
5085 });
5086 } else {
5087 closer = setFsWatchListener(path, absolutePath, options, {
5088 listener,
5089 errHandler: this._boundHandleError,
5090 rawEmitter: this.fsw._emitRaw
5091 });
5092 }
5093 return closer;
5094}
5095
5096/**
5097 * Watch a file and emit add event if warranted.
5098 * @param {Path} file Path
5099 * @param {fs.Stats} stats result of fs_stat
5100 * @param {Boolean} initialAdd was the file added at watch instantiation?
5101 * @returns {Function} closer for the watcher instance
5102 */
5103_handleFile(file, stats, initialAdd) {
5104 if (this.fsw.closed) {
5105 return;
5106 }
5107 const dirname = _events_commonjsExternal.sysPath.dirname(file);
5108 const basename = _events_commonjsExternal.sysPath.basename(file);
5109 const parent = this.fsw._getWatchedDir(dirname);
5110 // stats is always present
5111 let prevStats = stats;
5112
5113 // if the file is already being watched, do nothing
5114 if (parent.has(basename)) return;
5115
5116 // kick off the watcher
5117 const closer = this._watchWithNodeFs(file, async (path, newStats) => {
5118 if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5)) return;
5119 if (!newStats || newStats.mtimeMs === 0) {
5120 try {
5121 const newStats = await stat$1(file);
5122 if (this.fsw.closed) return;
5123 // Check that change event was not fired because of changed only accessTime.
5124 const at = newStats.atimeMs;
5125 const mt = newStats.mtimeMs;
5126 if (!at || at <= mt || mt !== prevStats.mtimeMs) {
5127 this.fsw._emit(EV_CHANGE, file, newStats);
5128 }
5129 prevStats = newStats;
5130 } catch (error) {
5131 // Fix issues where mtime is null but file is still present
5132 this.fsw._remove(dirname, basename);
5133 }
5134 // add is about to be emitted if file not already tracked in parent
5135 } else if (parent.has(basename)) {
5136 // Check that change event was not fired because of changed only accessTime.
5137 const at = newStats.atimeMs;
5138 const mt = newStats.mtimeMs;
5139 if (!at || at <= mt || mt !== prevStats.mtimeMs) {
5140 this.fsw._emit(EV_CHANGE, file, newStats);
5141 }
5142 prevStats = newStats;
5143 }
5144 });
5145
5146 // emit an add event if we're supposed to
5147 if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) {
5148 if (!this.fsw._throttle(EV_ADD, file, 0)) return;
5149 this.fsw._emit(EV_ADD, file, stats);
5150 }
5151
5152 return closer;
5153}
5154
5155/**
5156 * Handle symlinks encountered while reading a dir.
5157 * @param {Object} entry returned by readdirp
5158 * @param {String} directory path of dir being read
5159 * @param {String} path of this item
5160 * @param {String} item basename of this item
5161 * @returns {Promise<Boolean>} true if no more processing is needed for this entry.
5162 */
5163async _handleSymlink(entry, directory, path, item) {
5164 if (this.fsw.closed) {
5165 return;
5166 }
5167 const full = entry.fullPath;
5168 const dir = this.fsw._getWatchedDir(directory);
5169
5170 if (!this.fsw.options.followSymlinks) {
5171 // watch symlink directly (don't follow) and detect changes
5172 this.fsw._incrReadyCount();
5173 const linkPath = await fsrealpath(path);
5174 if (this.fsw.closed) return;
5175 if (dir.has(item)) {
5176 if (this.fsw._symlinkPaths.get(full) !== linkPath) {
5177 this.fsw._symlinkPaths.set(full, linkPath);
5178 this.fsw._emit(EV_CHANGE, path, entry.stats);
5179 }
5180 } else {
5181 dir.add(item);
5182 this.fsw._symlinkPaths.set(full, linkPath);
5183 this.fsw._emit(EV_ADD, path, entry.stats);
5184 }
5185 this.fsw._emitReady();
5186 return true;
5187 }
5188
5189 // don't follow the same symlink more than once
5190 if (this.fsw._symlinkPaths.has(full)) {
5191 return true;
5192 }
5193
5194 this.fsw._symlinkPaths.set(full, true);
5195}
5196
5197_handleRead(directory, initialAdd, wh, target, dir, depth, throttler) {
5198 // Normalize the directory name on Windows
5199 directory = _events_commonjsExternal.sysPath.join(directory, EMPTY_STR);
5200
5201 if (!wh.hasGlob) {
5202 throttler = this.fsw._throttle('readdir', directory, 1000);
5203 if (!throttler) return;
5204 }
5205
5206 const previous = this.fsw._getWatchedDir(wh.path);
5207 const current = new Set();
5208
5209 let stream = this.fsw._readdirp(directory, {
5210 fileFilter: entry => wh.filterPath(entry),
5211 directoryFilter: entry => wh.filterDir(entry),
5212 depth: 0
5213 }).on(STR_DATA, async (entry) => {
5214 if (this.fsw.closed) {
5215 stream = undefined;
5216 return;
5217 }
5218 const item = entry.path;
5219 let path = _events_commonjsExternal.sysPath.join(directory, item);
5220 current.add(item);
5221
5222 if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path, item)) {
5223 return;
5224 }
5225
5226 if (this.fsw.closed) {
5227 stream = undefined;
5228 return;
5229 }
5230 // Files that present in current directory snapshot
5231 // but absent in previous are added to watch list and
5232 // emit `add` event.
5233 if (item === target || !target && !previous.has(item)) {
5234 this.fsw._incrReadyCount();
5235
5236 // ensure relativeness of path is preserved in case of watcher reuse
5237 path = _events_commonjsExternal.sysPath.join(dir, _events_commonjsExternal.sysPath.relative(dir, path));
5238
5239 this._addToNodeFs(path, initialAdd, wh, depth + 1);
5240 }
5241 }).on(EV_ERROR, this._boundHandleError);
5242
5243 return new Promise(resolve =>
5244 stream.once(STR_END, () => {
5245 if (this.fsw.closed) {
5246 stream = undefined;
5247 return;
5248 }
5249 const wasThrottled = throttler ? throttler.clear() : false;
5250
5251 resolve();
5252
5253 // Files that absent in current directory snapshot
5254 // but present in previous emit `remove` event
5255 // and are removed from @watched[directory].
5256 previous.getChildren().filter((item) => {
5257 return item !== directory &&
5258 !current.has(item) &&
5259 // in case of intersecting globs;
5260 // a path may have been filtered out of this readdir, but
5261 // shouldn't be removed because it matches a different glob
5262 (!wh.hasGlob || wh.filterPath({
5263 fullPath: _events_commonjsExternal.sysPath.resolve(directory, item)
5264 }));
5265 }).forEach((item) => {
5266 this.fsw._remove(directory, item);
5267 });
5268
5269 stream = undefined;
5270
5271 // one more time for any missed in case changes came in extremely quickly
5272 if (wasThrottled) this._handleRead(directory, false, wh, target, dir, depth, throttler);
5273 })
5274 );
5275}
5276
5277/**
5278 * Read directory to add / remove files from `@watched` list and re-read it on change.
5279 * @param {String} dir fs path
5280 * @param {fs.Stats} stats
5281 * @param {Boolean} initialAdd
5282 * @param {Number} depth relative to user-supplied path
5283 * @param {String} target child path targeted for watch
5284 * @param {Object} wh Common watch helpers for this path
5285 * @param {String} realpath
5286 * @returns {Promise<Function>} closer for the watcher instance.
5287 */
5288async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath) {
5289 const parentDir = this.fsw._getWatchedDir(_events_commonjsExternal.sysPath.dirname(dir));
5290 const tracked = parentDir.has(_events_commonjsExternal.sysPath.basename(dir));
5291 if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) {
5292 if (!wh.hasGlob || wh.globFilter(dir)) this.fsw._emit(EV_ADD_DIR, dir, stats);
5293 }
5294
5295 // ensure dir is tracked (harmless if redundant)
5296 parentDir.add(_events_commonjsExternal.sysPath.basename(dir));
5297 this.fsw._getWatchedDir(dir);
5298 let throttler;
5299 let closer;
5300
5301 const oDepth = this.fsw.options.depth;
5302 if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath)) {
5303 if (!target) {
5304 await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler);
5305 if (this.fsw.closed) return;
5306 }
5307
5308 closer = this._watchWithNodeFs(dir, (dirPath, stats) => {
5309 // if current directory is removed, do nothing
5310 if (stats && stats.mtimeMs === 0) return;
5311
5312 this._handleRead(dirPath, false, wh, target, dir, depth, throttler);
5313 });
5314 }
5315 return closer;
5316}
5317
5318/**
5319 * Handle added file, directory, or glob pattern.
5320 * Delegates call to _handleFile / _handleDir after checks.
5321 * @param {String} path to file or ir
5322 * @param {Boolean} initialAdd was the file added at watch instantiation?
5323 * @param {Object} priorWh depth relative to user-supplied path
5324 * @param {Number} depth Child path actually targeted for watch
5325 * @param {String=} target Child path actually targeted for watch
5326 * @returns {Promise}
5327 */
5328async _addToNodeFs(path, initialAdd, priorWh, depth, target) {
5329 const ready = this.fsw._emitReady;
5330 if (this.fsw._isIgnored(path) || this.fsw.closed) {
5331 ready();
5332 return false;
5333 }
5334
5335 const wh = this.fsw._getWatchHelpers(path, depth);
5336 if (!wh.hasGlob && priorWh) {
5337 wh.hasGlob = priorWh.hasGlob;
5338 wh.globFilter = priorWh.globFilter;
5339 wh.filterPath = entry => priorWh.filterPath(entry);
5340 wh.filterDir = entry => priorWh.filterDir(entry);
5341 }
5342
5343 // evaluate what is at the path we're being asked to watch
5344 try {
5345 const stats = await statMethods[wh.statMethod](wh.watchPath);
5346 if (this.fsw.closed) return;
5347 if (this.fsw._isIgnored(wh.watchPath, stats)) {
5348 ready();
5349 return false;
5350 }
5351
5352 const follow = this.fsw.options.followSymlinks && !path.includes(STAR$1) && !path.includes(BRACE_START);
5353 let closer;
5354 if (stats.isDirectory()) {
5355 const targetPath = follow ? await fsrealpath(path) : path;
5356 if (this.fsw.closed) return;
5357 closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
5358 if (this.fsw.closed) return;
5359 // preserve this symlink's target path
5360 if (path !== targetPath && targetPath !== undefined) {
5361 this.fsw._symlinkPaths.set(targetPath, true);
5362 }
5363 } else if (stats.isSymbolicLink()) {
5364 const targetPath = follow ? await fsrealpath(path) : path;
5365 if (this.fsw.closed) return;
5366 const parent = _events_commonjsExternal.sysPath.dirname(wh.watchPath);
5367 this.fsw._getWatchedDir(parent).add(wh.watchPath);
5368 this.fsw._emit(EV_ADD, wh.watchPath, stats);
5369 closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath);
5370 if (this.fsw.closed) return;
5371
5372 // preserve this symlink's target path
5373 if (targetPath !== undefined) {
5374 this.fsw._symlinkPaths.set(_events_commonjsExternal.sysPath.resolve(path), targetPath);
5375 }
5376 } else {
5377 closer = this._handleFile(wh.watchPath, stats, initialAdd);
5378 }
5379 ready();
5380
5381 this.fsw._addPathCloser(path, closer);
5382 return false;
5383
5384 } catch (error) {
5385 if (this.fsw._handleError(error)) {
5386 ready();
5387 return path;
5388 }
5389 }
5390}
5391
5392}
5393
5394var nodefsHandler = NodeFsHandler;
5395
5396var require$$1 = rollup_js.getCjsExportFromNamespace(rollup_js.fseventsImporter);
5397
5398const { promisify: promisify$2 } = _events_commonjsExternal.require$$1;
5399
5400let fsevents;
5401try {
5402 fsevents = require$$1.getFsEvents();
5403} catch (error) {
5404 if (process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR) console.error(error);
5405}
5406
5407if (fsevents) {
5408 // TODO: real check
5409 const mtch = process.version.match(/v(\d+)\.(\d+)/);
5410 if (mtch && mtch[1] && mtch[2]) {
5411 const maj = Number.parseInt(mtch[1], 10);
5412 const min = Number.parseInt(mtch[2], 10);
5413 if (maj === 8 && min < 16) {
5414 fsevents = undefined;
5415 }
5416 }
5417}
5418
5419const {
5420 EV_ADD: EV_ADD$1,
5421 EV_CHANGE: EV_CHANGE$1,
5422 EV_ADD_DIR: EV_ADD_DIR$1,
5423 EV_UNLINK,
5424 EV_ERROR: EV_ERROR$1,
5425 STR_DATA: STR_DATA$1,
5426 STR_END: STR_END$1,
5427 FSEVENT_CREATED,
5428 FSEVENT_MODIFIED,
5429 FSEVENT_DELETED,
5430 FSEVENT_MOVED,
5431 // FSEVENT_CLONED,
5432 FSEVENT_UNKNOWN,
5433 FSEVENT_TYPE_DIRECTORY,
5434 FSEVENT_TYPE_SYMLINK,
5435
5436 ROOT_GLOBSTAR,
5437 DIR_SUFFIX,
5438 DOT_SLASH,
5439 FUNCTION_TYPE,
5440 EMPTY_FN: EMPTY_FN$1,
5441 IDENTITY_FN
5442} = constants$2;
5443const FS_MODE_READ = 'r';
5444
5445const Depth = (value) => isNaN(value) ? {} : {depth: value};
5446
5447const stat$2 = promisify$2(fs.stat);
5448const open$1 = promisify$2(fs.open);
5449const close$1 = promisify$2(fs.close);
5450const lstat$2 = promisify$2(fs.lstat);
5451const realpath = promisify$2(fs.realpath);
5452
5453const statMethods$1 = { stat: stat$2, lstat: lstat$2 };
5454
5455/**
5456 * @typedef {String} Path
5457 */
5458
5459/**
5460 * @typedef {Object} FsEventsWatchContainer
5461 * @property {Set<Function>} listeners
5462 * @property {Function} rawEmitter
5463 * @property {{stop: Function}} watcher
5464 */
5465
5466// fsevents instance helper functions
5467/**
5468 * Object to hold per-process fsevents instances (may be shared across chokidar FSWatcher instances)
5469 * @type {Map<Path,FsEventsWatchContainer>}
5470 */
5471const FSEventsWatchers = new Map();
5472
5473// Threshold of duplicate path prefixes at which to start
5474// consolidating going forward
5475const consolidateThreshhold = 10;
5476
5477const wrongEventFlags = new Set([
5478 69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912
5479]);
5480
5481/**
5482 * Instantiates the fsevents interface
5483 * @param {Path} path path to be watched
5484 * @param {Function} callback called when fsevents is bound and ready
5485 * @returns {{stop: Function}} new fsevents instance
5486 */
5487const createFSEventsInstance = (path, callback) => {
5488 const stop = fsevents.watch(path, callback);
5489 return {stop};
5490};
5491
5492/**
5493 * Instantiates the fsevents interface or binds listeners to an existing one covering
5494 * the same file tree.
5495 * @param {Path} path - to be watched
5496 * @param {Path} realPath - real path for symlinks
5497 * @param {Function} listener - called when fsevents emits events
5498 * @param {Function} rawEmitter - passes data to listeners of the 'raw' event
5499 * @returns {Function} closer
5500 */
5501function setFSEventsListener(path, realPath, listener, rawEmitter, fsw) {
5502 let watchPath = _events_commonjsExternal.sysPath.extname(path) ? _events_commonjsExternal.sysPath.dirname(path) : path;
5503 const parentPath = _events_commonjsExternal.sysPath.dirname(watchPath);
5504 let cont = FSEventsWatchers.get(watchPath);
5505
5506 // If we've accumulated a substantial number of paths that
5507 // could have been consolidated by watching one directory
5508 // above the current one, create a watcher on the parent
5509 // path instead, so that we do consolidate going forward.
5510 if (couldConsolidate(parentPath)) {
5511 watchPath = parentPath;
5512 }
5513
5514 const resolvedPath = _events_commonjsExternal.sysPath.resolve(path);
5515 const hasSymlink = resolvedPath !== realPath;
5516
5517 const filteredListener = (fullPath, flags, info) => {
5518 if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath);
5519 if (
5520 fullPath === resolvedPath ||
5521 !fullPath.indexOf(resolvedPath + _events_commonjsExternal.sysPath.sep)
5522 ) listener(fullPath, flags, info);
5523 };
5524
5525 // check if there is already a watcher on a parent path
5526 // modifies `watchPath` to the parent path when it finds a match
5527 let watchedParent = false;
5528 for (const watchedPath of FSEventsWatchers.keys()) {
5529 if (realPath.indexOf(_events_commonjsExternal.sysPath.resolve(watchedPath) + _events_commonjsExternal.sysPath.sep) === 0) {
5530 watchPath = watchedPath;
5531 cont = FSEventsWatchers.get(watchPath);
5532 watchedParent = true;
5533 break;
5534 }
5535 }
5536
5537 if (cont || watchedParent) {
5538 cont.listeners.add(filteredListener);
5539 } else {
5540 cont = {
5541 listeners: new Set([filteredListener]),
5542 rawEmitter,
5543 watcher: createFSEventsInstance(watchPath, (fullPath, flags) => {
5544 if (fsw.closed) return;
5545 const info = fsevents.getInfo(fullPath, flags);
5546 cont.listeners.forEach(list => {
5547 list(fullPath, flags, info);
5548 });
5549
5550 cont.rawEmitter(info.event, fullPath, info);
5551 })
5552 };
5553 FSEventsWatchers.set(watchPath, cont);
5554 }
5555
5556 // removes this instance's listeners and closes the underlying fsevents
5557 // instance if there are no more listeners left
5558 return () => {
5559 const lst = cont.listeners;
5560
5561 lst.delete(filteredListener);
5562 if (!lst.size) {
5563 FSEventsWatchers.delete(watchPath);
5564 if (cont.watcher) return cont.watcher.stop().then(() => {
5565 cont.rawEmitter = cont.watcher = undefined;
5566 Object.freeze(cont);
5567 });
5568 }
5569 };
5570}
5571
5572// Decide whether or not we should start a new higher-level
5573// parent watcher
5574const couldConsolidate = (path) => {
5575 let count = 0;
5576 for (const watchPath of FSEventsWatchers.keys()) {
5577 if (watchPath.indexOf(path) === 0) {
5578 count++;
5579 if (count >= consolidateThreshhold) {
5580 return true;
5581 }
5582 }
5583 }
5584
5585 return false;
5586};
5587
5588// returns boolean indicating whether fsevents can be used
5589const canUse = () => fsevents && FSEventsWatchers.size < 128;
5590
5591// determines subdirectory traversal levels from root to path
5592const calcDepth = (path, root) => {
5593 let i = 0;
5594 while (!path.indexOf(root) && (path = _events_commonjsExternal.sysPath.dirname(path)) !== root) i++;
5595 return i;
5596};
5597
5598/**
5599 * @mixin
5600 */
5601class FsEventsHandler {
5602
5603/**
5604 * @param {import('../index').FSWatcher} fsw
5605 */
5606constructor(fsw) {
5607 this.fsw = fsw;
5608}
5609checkIgnored(path, stats) {
5610 const ipaths = this.fsw._ignoredPaths;
5611 if (this.fsw._isIgnored(path, stats)) {
5612 ipaths.add(path);
5613 if (stats && stats.isDirectory()) {
5614 ipaths.add(path + ROOT_GLOBSTAR);
5615 }
5616 return true;
5617 }
5618
5619 ipaths.delete(path);
5620 ipaths.delete(path + ROOT_GLOBSTAR);
5621}
5622
5623addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts) {
5624 const event = watchedDir.has(item) ? EV_CHANGE$1 : EV_ADD$1;
5625 this.handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts);
5626}
5627
5628async checkFd(path, fullPath, realPath, parent, watchedDir, item, info, opts) {
5629 try {
5630 const fd = await open$1(path, FS_MODE_READ);
5631 if (this.fsw.closed) return;
5632 await close$1(fd);
5633 if (this.fsw.closed) return;
5634 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
5635 } catch (error) {
5636 if (error.code === 'EACCES') {
5637 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
5638 } else {
5639 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts);
5640 }
5641 }
5642}
5643
5644handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts) {
5645 if (this.fsw.closed || this.checkIgnored(path)) return;
5646
5647 if (event === EV_UNLINK) {
5648 // suppress unlink events on never before seen files
5649 if (info.type === FSEVENT_TYPE_DIRECTORY || watchedDir.has(item)) {
5650 this.fsw._remove(parent, item);
5651 }
5652 } else {
5653 if (event === EV_ADD$1) {
5654 // track new directories
5655 if (info.type === FSEVENT_TYPE_DIRECTORY) this.fsw._getWatchedDir(path);
5656
5657 if (info.type === FSEVENT_TYPE_SYMLINK && opts.followSymlinks) {
5658 // push symlinks back to the top of the stack to get handled
5659 const curDepth = opts.depth === undefined ?
5660 undefined : calcDepth(fullPath, realPath) + 1;
5661 return this._addToFsEvents(path, false, true, curDepth);
5662 }
5663
5664 // track new paths
5665 // (other than symlinks being followed, which will be tracked soon)
5666 this.fsw._getWatchedDir(parent).add(item);
5667 }
5668 /**
5669 * @type {'add'|'addDir'|'unlink'|'unlinkDir'}
5670 */
5671 const eventName = info.type === FSEVENT_TYPE_DIRECTORY ? event + DIR_SUFFIX : event;
5672 this.fsw._emit(eventName, path);
5673 if (eventName === EV_ADD_DIR$1) this._addToFsEvents(path, false, true);
5674 }
5675}
5676
5677/**
5678 * Handle symlinks encountered during directory scan
5679 * @param {String} watchPath - file/dir path to be watched with fsevents
5680 * @param {String} realPath - real path (in case of symlinks)
5681 * @param {Function} transform - path transformer
5682 * @param {Function} globFilter - path filter in case a glob pattern was provided
5683 * @returns {Function} closer for the watcher instance
5684*/
5685_watchWithFsEvents(watchPath, realPath, transform, globFilter) {
5686 if (this.fsw.closed) return;
5687 if (this.fsw._isIgnored(watchPath)) return;
5688 const opts = this.fsw.options;
5689 const watchCallback = async (fullPath, flags, info) => {
5690 if (this.fsw.closed) return;
5691 if (
5692 opts.depth !== undefined &&
5693 calcDepth(fullPath, realPath) > opts.depth
5694 ) return;
5695 const path = transform(_events_commonjsExternal.sysPath.join(
5696 watchPath, _events_commonjsExternal.sysPath.relative(watchPath, fullPath)
5697 ));
5698 if (globFilter && !globFilter(path)) return;
5699 // ensure directories are tracked
5700 const parent = _events_commonjsExternal.sysPath.dirname(path);
5701 const item = _events_commonjsExternal.sysPath.basename(path);
5702 const watchedDir = this.fsw._getWatchedDir(
5703 info.type === FSEVENT_TYPE_DIRECTORY ? path : parent
5704 );
5705
5706 // correct for wrong events emitted
5707 if (wrongEventFlags.has(flags) || info.event === FSEVENT_UNKNOWN) {
5708 if (typeof opts.ignored === FUNCTION_TYPE) {
5709 let stats;
5710 try {
5711 stats = await stat$2(path);
5712 } catch (error) {}
5713 if (this.fsw.closed) return;
5714 if (this.checkIgnored(path, stats)) return;
5715 if (stats) {
5716 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
5717 } else {
5718 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts);
5719 }
5720 } else {
5721 this.checkFd(path, fullPath, realPath, parent, watchedDir, item, info, opts);
5722 }
5723 } else {
5724 switch (info.event) {
5725 case FSEVENT_CREATED:
5726 case FSEVENT_MODIFIED:
5727 return this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
5728 case FSEVENT_DELETED:
5729 case FSEVENT_MOVED:
5730 return this.checkFd(path, fullPath, realPath, parent, watchedDir, item, info, opts);
5731 }
5732 }
5733 };
5734
5735 const closer = setFSEventsListener(
5736 watchPath,
5737 realPath,
5738 watchCallback,
5739 this.fsw._emitRaw,
5740 this.fsw
5741 );
5742
5743 this.fsw._emitReady();
5744 return closer;
5745}
5746
5747/**
5748 * Handle symlinks encountered during directory scan
5749 * @param {String} linkPath path to symlink
5750 * @param {String} fullPath absolute path to the symlink
5751 * @param {Function} transform pre-existing path transformer
5752 * @param {Number} curDepth level of subdirectories traversed to where symlink is
5753 * @returns {Promise<void>}
5754 */
5755async _handleFsEventsSymlink(linkPath, fullPath, transform, curDepth) {
5756 // don't follow the same symlink more than once
5757 if (this.fsw.closed || this.fsw._symlinkPaths.has(fullPath)) return;
5758
5759 this.fsw._symlinkPaths.set(fullPath, true);
5760 this.fsw._incrReadyCount();
5761
5762 try {
5763 const linkTarget = await realpath(linkPath);
5764 if (this.fsw.closed) return;
5765 if (this.fsw._isIgnored(linkTarget)) {
5766 return this.fsw._emitReady();
5767 }
5768
5769 this.fsw._incrReadyCount();
5770
5771 // add the linkTarget for watching with a wrapper for transform
5772 // that causes emitted paths to incorporate the link's path
5773 this._addToFsEvents(linkTarget || linkPath, (path) => {
5774 let aliasedPath = linkPath;
5775 if (linkTarget && linkTarget !== DOT_SLASH) {
5776 aliasedPath = path.replace(linkTarget, linkPath);
5777 } else if (path !== DOT_SLASH) {
5778 aliasedPath = _events_commonjsExternal.sysPath.join(linkPath, path);
5779 }
5780 return transform(aliasedPath);
5781 }, false, curDepth);
5782 } catch(error) {
5783 if (this.fsw._handleError(error)) {
5784 return this.fsw._emitReady();
5785 }
5786 }
5787}
5788
5789/**
5790 *
5791 * @param {Path} newPath
5792 * @param {fs.Stats} stats
5793 */
5794emitAdd(newPath, stats, processPath, opts, forceAdd) {
5795 const pp = processPath(newPath);
5796 const isDir = stats.isDirectory();
5797 const dirObj = this.fsw._getWatchedDir(_events_commonjsExternal.sysPath.dirname(pp));
5798 const base = _events_commonjsExternal.sysPath.basename(pp);
5799
5800 // ensure empty dirs get tracked
5801 if (isDir) this.fsw._getWatchedDir(pp);
5802 if (dirObj.has(base)) return;
5803 dirObj.add(base);
5804
5805 if (!opts.ignoreInitial || forceAdd === true) {
5806 this.fsw._emit(isDir ? EV_ADD_DIR$1 : EV_ADD$1, pp, stats);
5807 }
5808}
5809
5810initWatch(realPath, path, wh, processPath) {
5811 if (this.fsw.closed) return;
5812 const closer = this._watchWithFsEvents(
5813 wh.watchPath,
5814 _events_commonjsExternal.sysPath.resolve(realPath || wh.watchPath),
5815 processPath,
5816 wh.globFilter
5817 );
5818 this.fsw._addPathCloser(path, closer);
5819}
5820
5821/**
5822 * Handle added path with fsevents
5823 * @param {String} path file/dir path or glob pattern
5824 * @param {Function|Boolean=} transform converts working path to what the user expects
5825 * @param {Boolean=} forceAdd ensure add is emitted
5826 * @param {Number=} priorDepth Level of subdirectories already traversed.
5827 * @returns {Promise<void>}
5828 */
5829async _addToFsEvents(path, transform, forceAdd, priorDepth) {
5830 if (this.fsw.closed) {
5831 return;
5832 }
5833 const opts = this.fsw.options;
5834 const processPath = typeof transform === FUNCTION_TYPE ? transform : IDENTITY_FN;
5835
5836 const wh = this.fsw._getWatchHelpers(path);
5837
5838 // evaluate what is at the path we're being asked to watch
5839 try {
5840 const stats = await statMethods$1[wh.statMethod](wh.watchPath);
5841 if (this.fsw.closed) return;
5842 if (this.fsw._isIgnored(wh.watchPath, stats)) {
5843 throw null;
5844 }
5845 if (stats.isDirectory()) {
5846 // emit addDir unless this is a glob parent
5847 if (!wh.globFilter) this.emitAdd(processPath(path), stats, processPath, opts, forceAdd);
5848
5849 // don't recurse further if it would exceed depth setting
5850 if (priorDepth && priorDepth > opts.depth) return;
5851
5852 // scan the contents of the dir
5853 this.fsw._readdirp(wh.watchPath, {
5854 fileFilter: entry => wh.filterPath(entry),
5855 directoryFilter: entry => wh.filterDir(entry),
5856 ...Depth(opts.depth - (priorDepth || 0))
5857 }).on(STR_DATA$1, (entry) => {
5858 // need to check filterPath on dirs b/c filterDir is less restrictive
5859 if (this.fsw.closed) {
5860 return;
5861 }
5862 if (entry.stats.isDirectory() && !wh.filterPath(entry)) return;
5863
5864 const joinedPath = _events_commonjsExternal.sysPath.join(wh.watchPath, entry.path);
5865 const {fullPath} = entry;
5866
5867 if (wh.followSymlinks && entry.stats.isSymbolicLink()) {
5868 // preserve the current depth here since it can't be derived from
5869 // real paths past the symlink
5870 const curDepth = opts.depth === undefined ?
5871 undefined : calcDepth(joinedPath, _events_commonjsExternal.sysPath.resolve(wh.watchPath)) + 1;
5872
5873 this._handleFsEventsSymlink(joinedPath, fullPath, processPath, curDepth);
5874 } else {
5875 this.emitAdd(joinedPath, entry.stats, processPath, opts, forceAdd);
5876 }
5877 }).on(EV_ERROR$1, EMPTY_FN$1).on(STR_END$1, () => {
5878 this.fsw._emitReady();
5879 });
5880 } else {
5881 this.emitAdd(wh.watchPath, stats, processPath, opts, forceAdd);
5882 this.fsw._emitReady();
5883 }
5884 } catch (error) {
5885 if (!error || this.fsw._handleError(error)) {
5886 // TODO: Strange thing: "should not choke on an ignored watch path" will be failed without 2 ready calls -__-
5887 this.fsw._emitReady();
5888 this.fsw._emitReady();
5889 }
5890 }
5891
5892 if (opts.persistent && forceAdd !== true) {
5893 if (typeof transform === FUNCTION_TYPE) {
5894 // realpath has already been resolved
5895 this.initWatch(undefined, path, wh, processPath);
5896 } else {
5897 let realPath;
5898 try {
5899 realPath = await realpath(wh.watchPath);
5900 } catch (e) {}
5901 this.initWatch(realPath, path, wh, processPath);
5902 }
5903 }
5904}
5905
5906}
5907
5908var fseventsHandler = FsEventsHandler;
5909var canUse_1 = canUse;
5910fseventsHandler.canUse = canUse_1;
5911
5912const { EventEmitter } = _events_commonjsExternal.require$$0;
5913
5914
5915const { promisify: promisify$3 } = _events_commonjsExternal.require$$1;
5916
5917const anymatch = anymatch_1.default;
5918
5919
5920
5921
5922
5923
5924
5925const {
5926 EV_ALL,
5927 EV_READY,
5928 EV_ADD: EV_ADD$2,
5929 EV_CHANGE: EV_CHANGE$2,
5930 EV_UNLINK: EV_UNLINK$1,
5931 EV_ADD_DIR: EV_ADD_DIR$2,
5932 EV_UNLINK_DIR,
5933 EV_RAW,
5934 EV_ERROR: EV_ERROR$2,
5935
5936 STR_CLOSE,
5937 STR_END: STR_END$2,
5938
5939 BACK_SLASH_RE,
5940 DOUBLE_SLASH_RE,
5941 SLASH_OR_BACK_SLASH_RE,
5942 DOT_RE,
5943 REPLACER_RE,
5944
5945 SLASH,
5946 BRACE_START: BRACE_START$1,
5947 BANG: BANG$1,
5948 ONE_DOT,
5949 TWO_DOTS,
5950 GLOBSTAR,
5951 SLASH_GLOBSTAR,
5952 ANYMATCH_OPTS,
5953 STRING_TYPE,
5954 FUNCTION_TYPE: FUNCTION_TYPE$1,
5955 EMPTY_STR: EMPTY_STR$1,
5956 EMPTY_FN: EMPTY_FN$2,
5957
5958 isWindows: isWindows$1,
5959 isMacos
5960} = constants$2;
5961
5962const stat$3 = promisify$3(fs.stat);
5963const readdir$1 = promisify$3(fs.readdir);
5964
5965/**
5966 * @typedef {String} Path
5967 * @typedef {'all'|'add'|'addDir'|'change'|'unlink'|'unlinkDir'|'raw'|'error'|'ready'} EventName
5968 * @typedef {'readdir'|'watch'|'add'|'remove'|'change'} ThrottleType
5969 */
5970
5971/**
5972 *
5973 * @typedef {Object} WatchHelpers
5974 * @property {Boolean} followSymlinks
5975 * @property {'stat'|'lstat'} statMethod
5976 * @property {Path} path
5977 * @property {Path} watchPath
5978 * @property {Function} entryPath
5979 * @property {Boolean} hasGlob
5980 * @property {Object} globFilter
5981 * @property {Function} filterPath
5982 * @property {Function} filterDir
5983 */
5984
5985const arrify = (value = []) => Array.isArray(value) ? value : [value];
5986const flatten = (list, result = []) => {
5987 list.forEach(item => {
5988 if (Array.isArray(item)) {
5989 flatten(item, result);
5990 } else {
5991 result.push(item);
5992 }
5993 });
5994 return result;
5995};
5996
5997const unifyPaths = (paths_) => {
5998 /**
5999 * @type {Array<String>}
6000 */
6001 const paths = flatten(arrify(paths_));
6002 if (!paths.every(p => typeof p === STRING_TYPE)) {
6003 throw new TypeError(`Non-string provided as watch path: ${paths}`);
6004 }
6005 return paths.map(normalizePathToUnix);
6006};
6007
6008const toUnix = (string) => {
6009 let str = string.replace(BACK_SLASH_RE, SLASH);
6010 while (str.match(DOUBLE_SLASH_RE)) {
6011 str = str.replace(DOUBLE_SLASH_RE, SLASH);
6012 }
6013 return str;
6014};
6015
6016// Our version of upath.normalize
6017// TODO: this is not equal to path-normalize module - investigate why
6018const normalizePathToUnix = (path) => toUnix(_events_commonjsExternal.sysPath.normalize(toUnix(path)));
6019
6020const normalizeIgnored = (cwd = EMPTY_STR$1) => (path) => {
6021 if (typeof path !== STRING_TYPE) return path;
6022 return normalizePathToUnix(_events_commonjsExternal.sysPath.isAbsolute(path) ? path : _events_commonjsExternal.sysPath.join(cwd, path));
6023};
6024
6025const getAbsolutePath = (path, cwd) => {
6026 if (_events_commonjsExternal.sysPath.isAbsolute(path)) {
6027 return path;
6028 }
6029 if (path.startsWith(BANG$1)) {
6030 return BANG$1 + _events_commonjsExternal.sysPath.join(cwd, path.slice(1));
6031 }
6032 return _events_commonjsExternal.sysPath.join(cwd, path);
6033};
6034
6035const undef = (opts, key) => opts[key] === undefined;
6036
6037/**
6038 * Directory entry.
6039 * @property {Path} path
6040 * @property {Set<Path>} items
6041 */
6042class DirEntry {
6043 /**
6044 * @param {Path} dir
6045 * @param {Function} removeWatcher
6046 */
6047 constructor(dir, removeWatcher) {
6048 this.path = dir;
6049 this._removeWatcher = removeWatcher;
6050 /** @type {Set<Path>} */
6051 this.items = new Set();
6052 }
6053
6054 add(item) {
6055 const {items} = this;
6056 if (!items) return;
6057 if (item !== ONE_DOT && item !== TWO_DOTS) items.add(item);
6058 }
6059
6060 async remove(item) {
6061 const {items} = this;
6062 if (!items) return;
6063 items.delete(item);
6064
6065 if (!items.size) {
6066 const dir = this.path;
6067 try {
6068 await readdir$1(dir);
6069 } catch (err) {
6070 this._removeWatcher(_events_commonjsExternal.sysPath.dirname(dir), _events_commonjsExternal.sysPath.basename(dir));
6071 }
6072 }
6073 }
6074
6075 has(item) {
6076 const {items} = this;
6077 if (!items) return;
6078 return items.has(item);
6079 }
6080
6081 /**
6082 * @returns {Array<String>}
6083 */
6084 getChildren() {
6085 const {items} = this;
6086 if (!items) return;
6087 return [...items.values()];
6088 }
6089
6090 dispose() {
6091 this.items.clear();
6092 delete this.path;
6093 delete this._removeWatcher;
6094 delete this.items;
6095 Object.freeze(this);
6096 }
6097}
6098
6099const STAT_METHOD_F = 'stat';
6100const STAT_METHOD_L = 'lstat';
6101class WatchHelper {
6102 constructor(path, watchPath, follow, fsw) {
6103 this.fsw = fsw;
6104 this.path = path = path.replace(REPLACER_RE, EMPTY_STR$1);
6105 this.watchPath = watchPath;
6106 this.fullWatchPath = _events_commonjsExternal.sysPath.resolve(watchPath);
6107 this.hasGlob = watchPath !== path;
6108 /** @type {object|boolean} */
6109 if (path === EMPTY_STR$1) this.hasGlob = false;
6110 this.globSymlink = this.hasGlob && follow ? undefined : false;
6111 this.globFilter = this.hasGlob ? anymatch(path, undefined, ANYMATCH_OPTS) : false;
6112 this.dirParts = this.getDirParts(path);
6113 this.dirParts.forEach((parts) => {
6114 if (parts.length > 1) parts.pop();
6115 });
6116 this.followSymlinks = follow;
6117 this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L;
6118 }
6119
6120 checkGlobSymlink(entry) {
6121 // only need to resolve once
6122 // first entry should always have entry.parentDir === EMPTY_STR
6123 if (this.globSymlink === undefined) {
6124 this.globSymlink = entry.fullParentDir === this.fullWatchPath ?
6125 false : {realPath: entry.fullParentDir, linkPath: this.fullWatchPath};
6126 }
6127
6128 if (this.globSymlink) {
6129 return entry.fullPath.replace(this.globSymlink.realPath, this.globSymlink.linkPath);
6130 }
6131
6132 return entry.fullPath;
6133 }
6134
6135 entryPath(entry) {
6136 return _events_commonjsExternal.sysPath.join(this.watchPath,
6137 _events_commonjsExternal.sysPath.relative(this.watchPath, this.checkGlobSymlink(entry))
6138 );
6139 }
6140
6141 filterPath(entry) {
6142 const {stats} = entry;
6143 if (stats && stats.isSymbolicLink()) return this.filterDir(entry);
6144 const resolvedPath = this.entryPath(entry);
6145 const matchesGlob = this.hasGlob && typeof this.globFilter === FUNCTION_TYPE$1 ?
6146 this.globFilter(resolvedPath) : true;
6147 return matchesGlob &&
6148 this.fsw._isntIgnored(resolvedPath, stats) &&
6149 this.fsw._hasReadPermissions(stats);
6150 }
6151
6152 getDirParts(path) {
6153 if (!this.hasGlob) return [];
6154 const parts = [];
6155 const expandedPath = path.includes(BRACE_START$1) ? braces_1.expand(path) : [path];
6156 expandedPath.forEach((path) => {
6157 parts.push(_events_commonjsExternal.sysPath.relative(this.watchPath, path).split(SLASH_OR_BACK_SLASH_RE));
6158 });
6159 return parts;
6160 }
6161
6162 filterDir(entry) {
6163 if (this.hasGlob) {
6164 const entryParts = this.getDirParts(this.checkGlobSymlink(entry));
6165 let globstar = false;
6166 this.unmatchedGlob = !this.dirParts.some((parts) => {
6167 return parts.every((part, i) => {
6168 if (part === GLOBSTAR) globstar = true;
6169 return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i], ANYMATCH_OPTS);
6170 });
6171 });
6172 }
6173 return !this.unmatchedGlob && this.fsw._isntIgnored(this.entryPath(entry), entry.stats);
6174 }
6175}
6176
6177/**
6178 * Watches files & directories for changes. Emitted events:
6179 * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error`
6180 *
6181 * new FSWatcher()
6182 * .add(directories)
6183 * .on('add', path => log('File', path, 'was added'))
6184 */
6185class FSWatcher extends EventEmitter {
6186// Not indenting methods for history sake; for now.
6187constructor(_opts) {
6188 super();
6189
6190 const opts = {};
6191 if (_opts) Object.assign(opts, _opts); // for frozen objects
6192
6193 /** @type {Map<String, DirEntry>} */
6194 this._watched = new Map();
6195 /** @type {Map<String, Array>} */
6196 this._closers = new Map();
6197 /** @type {Set<String>} */
6198 this._ignoredPaths = new Set();
6199
6200 /** @type {Map<ThrottleType, Map>} */
6201 this._throttled = new Map();
6202
6203 /** @type {Map<Path, String|Boolean>} */
6204 this._symlinkPaths = new Map();
6205
6206 this._streams = new Set();
6207 this.closed = false;
6208
6209 // Set up default options.
6210 if (undef(opts, 'persistent')) opts.persistent = true;
6211 if (undef(opts, 'ignoreInitial')) opts.ignoreInitial = false;
6212 if (undef(opts, 'ignorePermissionErrors')) opts.ignorePermissionErrors = false;
6213 if (undef(opts, 'interval')) opts.interval = 100;
6214 if (undef(opts, 'binaryInterval')) opts.binaryInterval = 300;
6215 if (undef(opts, 'disableGlobbing')) opts.disableGlobbing = false;
6216 opts.enableBinaryInterval = opts.binaryInterval !== opts.interval;
6217
6218 // Enable fsevents on OS X when polling isn't explicitly enabled.
6219 if (undef(opts, 'useFsEvents')) opts.useFsEvents = !opts.usePolling;
6220
6221 // If we can't use fsevents, ensure the options reflect it's disabled.
6222 const canUseFsEvents = fseventsHandler.canUse();
6223 if (!canUseFsEvents) opts.useFsEvents = false;
6224
6225 // Use polling on Mac if not using fsevents.
6226 // Other platforms use non-polling fs_watch.
6227 if (undef(opts, 'usePolling') && !opts.useFsEvents) {
6228 opts.usePolling = isMacos;
6229 }
6230
6231 // Global override (useful for end-developers that need to force polling for all
6232 // instances of chokidar, regardless of usage/dependency depth)
6233 const envPoll = process.env.CHOKIDAR_USEPOLLING;
6234 if (envPoll !== undefined) {
6235 const envLower = envPoll.toLowerCase();
6236
6237 if (envLower === 'false' || envLower === '0') {
6238 opts.usePolling = false;
6239 } else if (envLower === 'true' || envLower === '1') {
6240 opts.usePolling = true;
6241 } else {
6242 opts.usePolling = !!envLower;
6243 }
6244 }
6245 const envInterval = process.env.CHOKIDAR_INTERVAL;
6246 if (envInterval) {
6247 opts.interval = Number.parseInt(envInterval, 10);
6248 }
6249
6250 // Editor atomic write normalization enabled by default with fs.watch
6251 if (undef(opts, 'atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents;
6252 if (opts.atomic) this._pendingUnlinks = new Map();
6253
6254 if (undef(opts, 'followSymlinks')) opts.followSymlinks = true;
6255
6256 if (undef(opts, 'awaitWriteFinish')) opts.awaitWriteFinish = false;
6257 if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {};
6258 const awf = opts.awaitWriteFinish;
6259 if (awf) {
6260 if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000;
6261 if (!awf.pollInterval) awf.pollInterval = 100;
6262 this._pendingWrites = new Map();
6263 }
6264 if (opts.ignored) opts.ignored = arrify(opts.ignored);
6265
6266 let readyCalls = 0;
6267 this._emitReady = () => {
6268 readyCalls++;
6269 if (readyCalls >= this._readyCount) {
6270 this._emitReady = EMPTY_FN$2;
6271 this._readyEmitted = true;
6272 // use process.nextTick to allow time for listener to be bound
6273 process.nextTick(() => this.emit(EV_READY));
6274 }
6275 };
6276 this._emitRaw = (...args) => this.emit(EV_RAW, ...args);
6277 this._readyEmitted = false;
6278 this.options = opts;
6279
6280 // Initialize with proper watcher.
6281 if (opts.useFsEvents) {
6282 this._fsEventsHandler = new fseventsHandler(this);
6283 } else {
6284 this._nodeFsHandler = new nodefsHandler(this);
6285 }
6286
6287 // You’re frozen when your heart’s not open.
6288 Object.freeze(opts);
6289}
6290
6291// Public methods
6292
6293/**
6294 * Adds paths to be watched on an existing FSWatcher instance
6295 * @param {Path|Array<Path>} paths_
6296 * @param {String=} _origAdd private; for handling non-existent paths to be watched
6297 * @param {Boolean=} _internal private; indicates a non-user add
6298 * @returns {FSWatcher} for chaining
6299 */
6300add(paths_, _origAdd, _internal) {
6301 const {cwd, disableGlobbing} = this.options;
6302 this.closed = false;
6303 let paths = unifyPaths(paths_);
6304 if (cwd) {
6305 paths = paths.map((path) => {
6306 const absPath = getAbsolutePath(path, cwd);
6307
6308 // Check `path` instead of `absPath` because the cwd portion can't be a glob
6309 if (disableGlobbing || !isGlob(path)) {
6310 return absPath;
6311 }
6312 return normalizePath(absPath);
6313 });
6314 }
6315
6316 // set aside negated glob strings
6317 paths = paths.filter((path) => {
6318 if (path.startsWith(BANG$1)) {
6319 this._ignoredPaths.add(path.slice(1));
6320 return false;
6321 }
6322
6323 // if a path is being added that was previously ignored, stop ignoring it
6324 this._ignoredPaths.delete(path);
6325 this._ignoredPaths.delete(path + SLASH_GLOBSTAR);
6326
6327 // reset the cached userIgnored anymatch fn
6328 // to make ignoredPaths changes effective
6329 this._userIgnored = undefined;
6330
6331 return true;
6332 });
6333
6334 if (this.options.useFsEvents && this._fsEventsHandler) {
6335 if (!this._readyCount) this._readyCount = paths.length;
6336 if (this.options.persistent) this._readyCount *= 2;
6337 paths.forEach((path) => this._fsEventsHandler._addToFsEvents(path));
6338 } else {
6339 if (!this._readyCount) this._readyCount = 0;
6340 this._readyCount += paths.length;
6341 Promise.all(
6342 paths.map(async path => {
6343 const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, 0, 0, _origAdd);
6344 if (res) this._emitReady();
6345 return res;
6346 })
6347 ).then(results => {
6348 if (this.closed) return;
6349 results.filter(item => item).forEach(item => {
6350 this.add(_events_commonjsExternal.sysPath.dirname(item), _events_commonjsExternal.sysPath.basename(_origAdd || item));
6351 });
6352 });
6353 }
6354
6355 return this;
6356}
6357
6358/**
6359 * Close watchers or start ignoring events from specified paths.
6360 * @param {Path|Array<Path>} paths_ - string or array of strings, file/directory paths and/or globs
6361 * @returns {FSWatcher} for chaining
6362*/
6363unwatch(paths_) {
6364 if (this.closed) return this;
6365 const paths = unifyPaths(paths_);
6366 const {cwd} = this.options;
6367
6368 paths.forEach((path) => {
6369 // convert to absolute path unless relative path already matches
6370 if (!_events_commonjsExternal.sysPath.isAbsolute(path) && !this._closers.has(path)) {
6371 if (cwd) path = _events_commonjsExternal.sysPath.join(cwd, path);
6372 path = _events_commonjsExternal.sysPath.resolve(path);
6373 }
6374
6375 this._closePath(path);
6376
6377 this._ignoredPaths.add(path);
6378 if (this._watched.has(path)) {
6379 this._ignoredPaths.add(path + SLASH_GLOBSTAR);
6380 }
6381
6382 // reset the cached userIgnored anymatch fn
6383 // to make ignoredPaths changes effective
6384 this._userIgnored = undefined;
6385 });
6386
6387 return this;
6388}
6389
6390/**
6391 * Close watchers and remove all listeners from watched paths.
6392 * @returns {Promise<void>}.
6393*/
6394close() {
6395 if (this.closed) return this;
6396 this.closed = true;
6397
6398 // Memory management.
6399 this.removeAllListeners();
6400 const closers = [];
6401 this._closers.forEach(closerList => closerList.forEach(closer => {
6402 const promise = closer();
6403 if (promise instanceof Promise) closers.push(promise);
6404 }));
6405 this._streams.forEach(stream => stream.destroy());
6406 this._userIgnored = undefined;
6407 this._readyCount = 0;
6408 this._readyEmitted = false;
6409 this._watched.forEach(dirent => dirent.dispose());
6410 ['closers', 'watched', 'streams', 'symlinkPaths', 'throttled'].forEach(key => {
6411 this[`_${key}`].clear();
6412 });
6413 return closers.length ? Promise.all(closers).then(() => undefined) : Promise.resolve();
6414}
6415
6416/**
6417 * Expose list of watched paths
6418 * @returns {Object} for chaining
6419*/
6420getWatched() {
6421 const watchList = {};
6422 this._watched.forEach((entry, dir) => {
6423 const key = this.options.cwd ? _events_commonjsExternal.sysPath.relative(this.options.cwd, dir) : dir;
6424 watchList[key || ONE_DOT] = entry.getChildren().sort();
6425 });
6426 return watchList;
6427}
6428
6429emitWithAll(event, args) {
6430 this.emit(...args);
6431 if (event !== EV_ERROR$2) this.emit(EV_ALL, ...args);
6432}
6433
6434// Common helpers
6435// --------------
6436
6437/**
6438 * Normalize and emit events.
6439 * Calling _emit DOES NOT MEAN emit() would be called!
6440 * @param {EventName} event Type of event
6441 * @param {Path} path File or directory path
6442 * @param {*=} val1 arguments to be passed with event
6443 * @param {*=} val2
6444 * @param {*=} val3
6445 * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
6446 */
6447async _emit(event, path, val1, val2, val3) {
6448 if (this.closed) return;
6449
6450 const opts = this.options;
6451 if (isWindows$1) path = _events_commonjsExternal.sysPath.normalize(path);
6452 if (opts.cwd) path = _events_commonjsExternal.sysPath.relative(opts.cwd, path);
6453 /** @type Array<any> */
6454 const args = [event, path];
6455 if (val3 !== undefined) args.push(val1, val2, val3);
6456 else if (val2 !== undefined) args.push(val1, val2);
6457 else if (val1 !== undefined) args.push(val1);
6458
6459 const awf = opts.awaitWriteFinish;
6460 let pw;
6461 if (awf && (pw = this._pendingWrites.get(path))) {
6462 pw.lastChange = new Date();
6463 return this;
6464 }
6465
6466 if (opts.atomic) {
6467 if (event === EV_UNLINK$1) {
6468 this._pendingUnlinks.set(path, args);
6469 setTimeout(() => {
6470 this._pendingUnlinks.forEach((entry, path) => {
6471 this.emit(...entry);
6472 this.emit(EV_ALL, ...entry);
6473 this._pendingUnlinks.delete(path);
6474 });
6475 }, typeof opts.atomic === 'number' ? opts.atomic : 100);
6476 return this;
6477 }
6478 if (event === EV_ADD$2 && this._pendingUnlinks.has(path)) {
6479 event = args[0] = EV_CHANGE$2;
6480 this._pendingUnlinks.delete(path);
6481 }
6482 }
6483
6484 if (awf && (event === EV_ADD$2 || event === EV_CHANGE$2) && this._readyEmitted) {
6485 const awfEmit = (err, stats) => {
6486 if (err) {
6487 event = args[0] = EV_ERROR$2;
6488 args[1] = err;
6489 this.emitWithAll(event, args);
6490 } else if (stats) {
6491 // if stats doesn't exist the file must have been deleted
6492 if (args.length > 2) {
6493 args[2] = stats;
6494 } else {
6495 args.push(stats);
6496 }
6497 this.emitWithAll(event, args);
6498 }
6499 };
6500
6501 this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit);
6502 return this;
6503 }
6504
6505 if (event === EV_CHANGE$2) {
6506 const isThrottled = !this._throttle(EV_CHANGE$2, path, 50);
6507 if (isThrottled) return this;
6508 }
6509
6510 if (opts.alwaysStat && val1 === undefined &&
6511 (event === EV_ADD$2 || event === EV_ADD_DIR$2 || event === EV_CHANGE$2)
6512 ) {
6513 const fullPath = opts.cwd ? _events_commonjsExternal.sysPath.join(opts.cwd, path) : path;
6514 try {
6515 const stats = await stat$3(fullPath);
6516 // Suppress event when fs_stat fails, to avoid sending undefined 'stat'
6517 if (!stats) return;
6518 args.push(stats);
6519 this.emitWithAll(event, args);
6520 } catch (err) {}
6521 } else {
6522 this.emitWithAll(event, args);
6523 }
6524
6525 return this;
6526}
6527
6528/**
6529 * Common handler for errors
6530 * @param {Error} error
6531 * @returns {Error|Boolean} The error if defined, otherwise the value of the FSWatcher instance's `closed` flag
6532 */
6533_handleError(error) {
6534 const code = error && error.code;
6535 if (error && code !== 'ENOENT' && code !== 'ENOTDIR' &&
6536 (!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES'))
6537 ) {
6538 this.emit(EV_ERROR$2, error);
6539 }
6540 return error || this.closed;
6541}
6542
6543/**
6544 * Helper utility for throttling
6545 * @param {ThrottleType} actionType type being throttled
6546 * @param {Path} path being acted upon
6547 * @param {Number} timeout duration of time to suppress duplicate actions
6548 * @returns {Object|false} tracking object or false if action should be suppressed
6549 */
6550_throttle(actionType, path, timeout) {
6551 if (!this._throttled.has(actionType)) {
6552 this._throttled.set(actionType, new Map());
6553 }
6554
6555 /** @type {Map<Path, Object>} */
6556 const action = this._throttled.get(actionType);
6557 /** @type {Object} */
6558 const actionPath = action.get(path);
6559
6560 if (actionPath) {
6561 actionPath.count++;
6562 return false;
6563 }
6564
6565 let timeoutObject;
6566 const clear = () => {
6567 const item = action.get(path);
6568 const count = item ? item.count : 0;
6569 action.delete(path);
6570 clearTimeout(timeoutObject);
6571 if (item) clearTimeout(item.timeoutObject);
6572 return count;
6573 };
6574 timeoutObject = setTimeout(clear, timeout);
6575 const thr = {timeoutObject, clear, count: 0};
6576 action.set(path, thr);
6577 return thr;
6578}
6579
6580_incrReadyCount() {
6581 return this._readyCount++;
6582}
6583
6584/**
6585 * Awaits write operation to finish.
6586 * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback.
6587 * @param {Path} path being acted upon
6588 * @param {Number} threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished
6589 * @param {EventName} event
6590 * @param {Function} awfEmit Callback to be called when ready for event to be emitted.
6591 */
6592_awaitWriteFinish(path, threshold, event, awfEmit) {
6593 let timeoutHandler;
6594
6595 let fullPath = path;
6596 if (this.options.cwd && !_events_commonjsExternal.sysPath.isAbsolute(path)) {
6597 fullPath = _events_commonjsExternal.sysPath.join(this.options.cwd, path);
6598 }
6599
6600 const now = new Date();
6601
6602 const awaitWriteFinish = (prevStat) => {
6603 fs.stat(fullPath, (err, curStat) => {
6604 if (err || !this._pendingWrites.has(path)) {
6605 if (err && err.code !== 'ENOENT') awfEmit(err);
6606 return;
6607 }
6608
6609 const now = Number(new Date());
6610
6611 if (prevStat && curStat.size !== prevStat.size) {
6612 this._pendingWrites.get(path).lastChange = now;
6613 }
6614 const pw = this._pendingWrites.get(path);
6615 const df = now - pw.lastChange;
6616
6617 if (df >= threshold) {
6618 this._pendingWrites.delete(path);
6619 awfEmit(undefined, curStat);
6620 } else {
6621 timeoutHandler = setTimeout(
6622 awaitWriteFinish,
6623 this.options.awaitWriteFinish.pollInterval,
6624 curStat
6625 );
6626 }
6627 });
6628 };
6629
6630 if (!this._pendingWrites.has(path)) {
6631 this._pendingWrites.set(path, {
6632 lastChange: now,
6633 cancelWait: () => {
6634 this._pendingWrites.delete(path);
6635 clearTimeout(timeoutHandler);
6636 return event;
6637 }
6638 });
6639 timeoutHandler = setTimeout(
6640 awaitWriteFinish,
6641 this.options.awaitWriteFinish.pollInterval
6642 );
6643 }
6644}
6645
6646_getGlobIgnored() {
6647 return [...this._ignoredPaths.values()];
6648}
6649
6650/**
6651 * Determines whether user has asked to ignore this path.
6652 * @param {Path} path filepath or dir
6653 * @param {fs.Stats=} stats result of fs.stat
6654 * @returns {Boolean}
6655 */
6656_isIgnored(path, stats) {
6657 if (this.options.atomic && DOT_RE.test(path)) return true;
6658 if (!this._userIgnored) {
6659 const {cwd} = this.options;
6660 const ign = this.options.ignored;
6661
6662 const ignored = ign && ign.map(normalizeIgnored(cwd));
6663 const paths = arrify(ignored)
6664 .filter((path) => typeof path === STRING_TYPE && !isGlob(path))
6665 .map((path) => path + SLASH_GLOBSTAR);
6666 const list = this._getGlobIgnored().map(normalizeIgnored(cwd)).concat(ignored, paths);
6667 this._userIgnored = anymatch(list, undefined, ANYMATCH_OPTS);
6668 }
6669
6670 return this._userIgnored([path, stats]);
6671}
6672
6673_isntIgnored(path, stat) {
6674 return !this._isIgnored(path, stat);
6675}
6676
6677/**
6678 * Provides a set of common helpers and properties relating to symlink and glob handling.
6679 * @param {Path} path file, directory, or glob pattern being watched
6680 * @param {Number=} depth at any depth > 0, this isn't a glob
6681 * @returns {WatchHelper} object containing helpers for this path
6682 */
6683_getWatchHelpers(path, depth) {
6684 const watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path);
6685 const follow = this.options.followSymlinks;
6686
6687 return new WatchHelper(path, watchPath, follow, this);
6688}
6689
6690// Directory helpers
6691// -----------------
6692
6693/**
6694 * Provides directory tracking objects
6695 * @param {String} directory path of the directory
6696 * @returns {DirEntry} the directory's tracking object
6697 */
6698_getWatchedDir(directory) {
6699 if (!this._boundRemove) this._boundRemove = this._remove.bind(this);
6700 const dir = _events_commonjsExternal.sysPath.resolve(directory);
6701 if (!this._watched.has(dir)) this._watched.set(dir, new DirEntry(dir, this._boundRemove));
6702 return this._watched.get(dir);
6703}
6704
6705// File helpers
6706// ------------
6707
6708/**
6709 * Check for read permissions.
6710 * Based on this answer on SO: https://stackoverflow.com/a/11781404/1358405
6711 * @param {fs.Stats} stats - object, result of fs_stat
6712 * @returns {Boolean} indicates whether the file can be read
6713*/
6714_hasReadPermissions(stats) {
6715 if (this.options.ignorePermissionErrors) return true;
6716
6717 // stats.mode may be bigint
6718 const md = stats && Number.parseInt(stats.mode, 10);
6719 const st = md & 0o777;
6720 const it = Number.parseInt(st.toString(8)[0], 10);
6721 return Boolean(4 & it);
6722}
6723
6724/**
6725 * Handles emitting unlink events for
6726 * files and directories, and via recursion, for
6727 * files and directories within directories that are unlinked
6728 * @param {String} directory within which the following item is located
6729 * @param {String} item base path of item/directory
6730 * @returns {void}
6731*/
6732_remove(directory, item) {
6733 // if what is being deleted is a directory, get that directory's paths
6734 // for recursive deleting and cleaning of watched object
6735 // if it is not a directory, nestedDirectoryChildren will be empty array
6736 const path = _events_commonjsExternal.sysPath.join(directory, item);
6737 const fullPath = _events_commonjsExternal.sysPath.resolve(path);
6738 const isDirectory = this._watched.has(path) || this._watched.has(fullPath);
6739
6740 // prevent duplicate handling in case of arriving here nearly simultaneously
6741 // via multiple paths (such as _handleFile and _handleDir)
6742 if (!this._throttle('remove', path, 100)) return;
6743
6744 // if the only watched file is removed, watch for its return
6745 if (!isDirectory && !this.options.useFsEvents && this._watched.size === 1) {
6746 this.add(directory, item, true);
6747 }
6748
6749 // This will create a new entry in the watched object in either case
6750 // so we got to do the directory check beforehand
6751 const wp = this._getWatchedDir(path);
6752 const nestedDirectoryChildren = wp.getChildren();
6753
6754 // Recursively remove children directories / files.
6755 nestedDirectoryChildren.forEach(nested => this._remove(path, nested));
6756
6757 // Check if item was on the watched list and remove it
6758 const parent = this._getWatchedDir(directory);
6759 const wasTracked = parent.has(item);
6760 parent.remove(item);
6761
6762 // If we wait for this file to be fully written, cancel the wait.
6763 let relPath = path;
6764 if (this.options.cwd) relPath = _events_commonjsExternal.sysPath.relative(this.options.cwd, path);
6765 if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
6766 const event = this._pendingWrites.get(relPath).cancelWait();
6767 if (event === EV_ADD$2) return;
6768 }
6769
6770 // The Entry will either be a directory that just got removed
6771 // or a bogus entry to a file, in either case we have to remove it
6772 this._watched.delete(path);
6773 this._watched.delete(fullPath);
6774 const eventName = isDirectory ? EV_UNLINK_DIR : EV_UNLINK$1;
6775 if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path);
6776
6777 // Avoid conflicts if we later create another file with the same name
6778 if (!this.options.useFsEvents) {
6779 this._closePath(path);
6780 }
6781}
6782
6783/**
6784 *
6785 * @param {Path} path
6786 */
6787_closePath(path) {
6788 const closers = this._closers.get(path);
6789 if (!closers) return;
6790 closers.forEach(closer => closer());
6791 this._closers.delete(path);
6792 const dir = _events_commonjsExternal.sysPath.dirname(path);
6793 this._getWatchedDir(dir).remove(_events_commonjsExternal.sysPath.basename(path));
6794}
6795
6796/**
6797 *
6798 * @param {Path} path
6799 * @param {Function} closer
6800 */
6801_addPathCloser(path, closer) {
6802 if (!closer) return;
6803 let list = this._closers.get(path);
6804 if (!list) {
6805 list = [];
6806 this._closers.set(path, list);
6807 }
6808 list.push(closer);
6809}
6810
6811_readdirp(root, opts) {
6812 if (this.closed) return;
6813 const options = {type: EV_ALL, alwaysStat: true, lstat: true, ...opts};
6814 let stream = readdirp_1(root, options);
6815 this._streams.add(stream);
6816 stream.once(STR_CLOSE, () => {
6817 stream = undefined;
6818 });
6819 stream.once(STR_END$2, () => {
6820 if (stream) {
6821 this._streams.delete(stream);
6822 stream = undefined;
6823 }
6824 });
6825 return stream;
6826}
6827
6828}
6829
6830// Export FSWatcher class
6831var FSWatcher_1 = FSWatcher;
6832
6833/**
6834 * Instantiates watcher with paths to be tracked.
6835 * @param {String|Array<String>} paths file/directory paths and/or globs
6836 * @param {Object=} options chokidar opts
6837 * @returns an instance of FSWatcher for chaining.
6838 */
6839const watch = (paths, options) => {
6840 const watcher = new FSWatcher(options);
6841 watcher.add(paths);
6842 return watcher;
6843};
6844
6845var watch_1 = watch;
6846
6847var chokidar = {
6848 FSWatcher: FSWatcher_1,
6849 watch: watch_1
6850};
6851
6852class FileWatcher {
6853 constructor(task, chokidarOptions) {
6854 this.transformWatchers = new Map();
6855 this.chokidarOptions = chokidarOptions;
6856 this.task = task;
6857 this.watcher = this.createWatcher(null);
6858 }
6859 close() {
6860 this.watcher.close();
6861 for (const watcher of this.transformWatchers.values()) {
6862 watcher.close();
6863 }
6864 }
6865 unwatch(id) {
6866 this.watcher.unwatch(id);
6867 const transformWatcher = this.transformWatchers.get(id);
6868 if (transformWatcher) {
6869 this.transformWatchers.delete(id);
6870 transformWatcher.close();
6871 }
6872 }
6873 watch(id, isTransformDependency) {
6874 if (isTransformDependency) {
6875 const watcher = this.transformWatchers.get(id) || this.createWatcher(id);
6876 watcher.add(id);
6877 this.transformWatchers.set(id, watcher);
6878 }
6879 else {
6880 this.watcher.add(id);
6881 }
6882 }
6883 createWatcher(transformWatcherId) {
6884 const task = this.task;
6885 const isLinux = os.platform() === 'linux';
6886 const isTransformDependency = transformWatcherId !== null;
6887 const handleChange = (id) => {
6888 const changedId = transformWatcherId || id;
6889 if (isLinux) {
6890 // unwatching and watching fixes an issue with chokidar where on certain systems,
6891 // a file that was unlinked and immediately recreated would create a change event
6892 // but then no longer any further events
6893 watcher.unwatch(changedId);
6894 watcher.add(changedId);
6895 }
6896 task.invalidate(changedId, isTransformDependency);
6897 };
6898 const watcher = chokidar
6899 .watch([], this.chokidarOptions)
6900 .on('change', handleChange)
6901 .on('unlink', handleChange);
6902 return watcher;
6903 }
6904}
6905
6906const DELAY = 200;
6907class Watcher {
6908 constructor(configs, emitter) {
6909 this.buildTimeout = null;
6910 this.invalidatedIds = new Set();
6911 this.rerun = false;
6912 this.emitter = emitter;
6913 emitter.close = this.close.bind(this);
6914 this.tasks = (Array.isArray(configs) ? configs : configs ? [configs] : []).map(config => new Task(this, config));
6915 this.running = true;
6916 process.nextTick(() => this.run());
6917 }
6918 close() {
6919 if (this.buildTimeout)
6920 clearTimeout(this.buildTimeout);
6921 for (const task of this.tasks) {
6922 task.close();
6923 }
6924 this.emitter.removeAllListeners();
6925 }
6926 emit(event, value) {
6927 this.emitter.emit(event, value);
6928 }
6929 invalidate(id) {
6930 if (id) {
6931 this.invalidatedIds.add(id);
6932 }
6933 if (this.running) {
6934 this.rerun = true;
6935 return;
6936 }
6937 if (this.buildTimeout)
6938 clearTimeout(this.buildTimeout);
6939 this.buildTimeout = setTimeout(() => {
6940 this.buildTimeout = null;
6941 for (const id of this.invalidatedIds) {
6942 this.emit('change', id);
6943 }
6944 this.invalidatedIds.clear();
6945 this.emit('restart');
6946 this.run();
6947 }, DELAY);
6948 }
6949 async run() {
6950 this.running = true;
6951 this.emit('event', {
6952 code: 'START'
6953 });
6954 try {
6955 for (const task of this.tasks) {
6956 await task.run();
6957 }
6958 this.running = false;
6959 this.emit('event', {
6960 code: 'END'
6961 });
6962 }
6963 catch (error) {
6964 this.running = false;
6965 this.emit('event', {
6966 code: 'ERROR',
6967 error
6968 });
6969 }
6970 if (this.rerun) {
6971 this.rerun = false;
6972 this.invalidate();
6973 }
6974 }
6975}
6976class Task {
6977 constructor(watcher, config) {
6978 this.cache = { modules: [] };
6979 this.watchFiles = [];
6980 this.invalidated = true;
6981 this.watcher = watcher;
6982 this.closed = false;
6983 this.watched = new Set();
6984 const { inputOptions, outputOptions } = _events_commonjsExternal.mergeOptions(config);
6985 this.inputOptions = inputOptions;
6986 this.outputs = outputOptions;
6987 this.outputFiles = this.outputs.map(output => {
6988 if (output.file || output.dir)
6989 return path.resolve(output.file || output.dir);
6990 return undefined;
6991 });
6992 const watchOptions = inputOptions.watch || {};
6993 this.filter = createFilter(watchOptions.include, watchOptions.exclude);
6994 this.fileWatcher = new FileWatcher(this, {
6995 ...watchOptions.chokidar,
6996 disableGlobbing: true,
6997 ignoreInitial: true
6998 });
6999 }
7000 close() {
7001 this.closed = true;
7002 this.fileWatcher.close();
7003 }
7004 invalidate(id, isTransformDependency) {
7005 this.invalidated = true;
7006 if (isTransformDependency) {
7007 for (const module of this.cache.modules) {
7008 if (module.transformDependencies.indexOf(id) === -1)
7009 continue;
7010 // effective invalidation
7011 module.originalCode = null;
7012 }
7013 }
7014 this.watcher.invalidate(id);
7015 }
7016 async run() {
7017 if (!this.invalidated)
7018 return;
7019 this.invalidated = false;
7020 const options = {
7021 ...this.inputOptions,
7022 cache: this.cache
7023 };
7024 const start = Date.now();
7025 this.watcher.emit('event', {
7026 code: 'BUNDLE_START',
7027 input: this.inputOptions.input,
7028 output: this.outputFiles
7029 });
7030 try {
7031 const result = await rollup_js.rollupInternal(options, this.watcher.emitter);
7032 if (this.closed) {
7033 return;
7034 }
7035 this.updateWatchedFiles(result);
7036 await Promise.all(this.outputs.map(output => result.write(output)));
7037 this.watcher.emit('event', {
7038 code: 'BUNDLE_END',
7039 duration: Date.now() - start,
7040 input: this.inputOptions.input,
7041 output: this.outputFiles,
7042 result
7043 });
7044 }
7045 catch (error) {
7046 if (this.closed) {
7047 return;
7048 }
7049 if (Array.isArray(error.watchFiles)) {
7050 for (const id of error.watchFiles) {
7051 this.watchFile(id);
7052 }
7053 }
7054 if (error.id) {
7055 this.cache.modules = this.cache.modules.filter(module => module.id !== error.id);
7056 }
7057 throw error;
7058 }
7059 }
7060 updateWatchedFiles(result) {
7061 const previouslyWatched = this.watched;
7062 this.watched = new Set();
7063 this.watchFiles = result.watchFiles;
7064 this.cache = result.cache;
7065 for (const id of this.watchFiles) {
7066 this.watchFile(id);
7067 }
7068 for (const module of this.cache.modules) {
7069 for (const depId of module.transformDependencies) {
7070 this.watchFile(depId, true);
7071 }
7072 }
7073 for (const id of previouslyWatched) {
7074 if (!this.watched.has(id)) {
7075 this.fileWatcher.unwatch(id);
7076 }
7077 }
7078 }
7079 watchFile(id, isTransformDependency = false) {
7080 if (!this.filter(id))
7081 return;
7082 this.watched.add(id);
7083 if (this.outputFiles.some(file => file === id)) {
7084 throw new Error('Cannot import the generated bundle');
7085 }
7086 // this is necessary to ensure that any 'renamed' files
7087 // continue to be watched following an error
7088 this.fileWatcher.watch(id, isTransformDependency);
7089 }
7090}
7091
7092exports.Task = Task;
7093exports.Watcher = Watcher;
7094//# sourceMappingURL=watch.js.map