'use strict'; var browserSyncModule = require('browser-sync'); var node_util = require('node:util'); var path$d = require('node:path'); var process$1 = require('node:process'); var fs$c = require('node:fs'); var require$$0 = require('stream'); var os$1 = require('os'); var path$c = require('path'); var require$$0$1 = require('util'); var require$$0$2 = require('events'); var fs$b = require('fs'); var node_url = require('node:url'); require('node:stream'); var require$$0$3 = require('constants'); var require$$5 = require('assert'); var gulp = require('gulp'); var flatten$1 = require('gulp-flatten'); var plumber = require('gulp-plumber'); var postcss = require('gulp-postcss'); var sourcemaps = require('gulp-sourcemaps'); var gulpIf = require('gulp-if'); var log = require('fancy-log'); var through = require('through2'); var crypto = require('crypto'); var glob$1 = require('glob'); var fs$d = require('fs-extra'); var glob$2 = require('glob-all'); var environments = require('gulp-environments'); var rollup = require('rollup'); var pluginBabel = require('@rollup/plugin-babel'); var commonjs = require('@rollup/plugin-commonjs'); var pluginNodeResolve = require('@rollup/plugin-node-resolve'); var terser = require('@rollup/plugin-terser'); var cleanup = require('rollup-plugin-cleanup'); var postcss$1 = require('rollup-plugin-postcss'); var svg$1 = require('rollup-plugin-svg'); var stylelint = require('stylelint'); var eslint = require('gulp-eslint'); var childProcess = require('child_process'); var SVGSprite = require('svg-sprite'); var File = require('vinyl'); const browserSyncInstance = browserSyncModule.create(); const browserSync = options => { return () => { browserSyncInstance.init({ ui: { port: parseInt(process.env.BROWSER_SYNC_UI_PORT, 10) || 3000 }, host: process.env.BROWSER_SYNC_HOST || 'localhost', port: parseInt(process.env.BROWSER_SYNC_PORT, 10) || 3002, proxy: process.env.BROWSER_SYNC_PROXY || 'http://localhost:3001/', open: false, ...options }); }; }; var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } /* * merge2 * https://github.com/teambition/merge2 * * Copyright (c) 2014-2020 Teambition * Licensed under the MIT license. */ const Stream$1 = require$$0; const PassThrough = Stream$1.PassThrough; const slice = Array.prototype.slice; var merge2_1 = merge2$1; function merge2$1() { const streamsQueue = []; const args = slice.call(arguments); let merging = false; let options = args[args.length - 1]; if (options && !Array.isArray(options) && options.pipe == null) { args.pop(); } else { options = {}; } const doEnd = options.end !== false; const doPipeError = options.pipeError === true; if (options.objectMode == null) { options.objectMode = true; } if (options.highWaterMark == null) { options.highWaterMark = 64 * 1024; } const mergedStream = PassThrough(options); function addStream() { for (let i = 0, len = arguments.length; i < len; i++) { streamsQueue.push(pauseStreams(arguments[i], options)); } mergeStream(); return this; } function mergeStream() { if (merging) { return; } merging = true; let streams = streamsQueue.shift(); if (!streams) { process.nextTick(endStream); return; } if (!Array.isArray(streams)) { streams = [streams]; } let pipesCount = streams.length + 1; function next() { if (--pipesCount > 0) { return; } merging = false; mergeStream(); } function pipe(stream) { function onend() { stream.removeListener('merge2UnpipeEnd', onend); stream.removeListener('end', onend); if (doPipeError) { stream.removeListener('error', onerror); } next(); } function onerror(err) { mergedStream.emit('error', err); } // skip ended stream if (stream._readableState.endEmitted) { return next(); } stream.on('merge2UnpipeEnd', onend); stream.on('end', onend); if (doPipeError) { stream.on('error', onerror); } stream.pipe(mergedStream, { end: false }); // compatible for old stream stream.resume(); } for (let i = 0; i < streams.length; i++) { pipe(streams[i]); } next(); } function endStream() { merging = false; // emit 'queueDrain' when all streams merged. mergedStream.emit('queueDrain'); if (doEnd) { mergedStream.end(); } } mergedStream.setMaxListeners(0); mergedStream.add = addStream; mergedStream.on('unpipe', function (stream) { stream.emit('merge2UnpipeEnd'); }); if (args.length) { addStream.apply(null, args); } return mergedStream; } // check and pause streams for pipe. function pauseStreams(streams, options) { if (!Array.isArray(streams)) { // Backwards-compat with old-style streams if (!streams._readableState && streams.pipe) { streams = streams.pipe(PassThrough(options)); } if (!streams._readableState || !streams.pause || !streams.pipe) { throw new Error('Only readable stream can be merged.'); } streams.pause(); } else { for (let i = 0, len = streams.length; i < len; i++) { streams[i] = pauseStreams(streams[i], options); } } return streams; } var tasks$1 = {}; var utils$k = {}; var array$1 = {}; Object.defineProperty(array$1, "__esModule", { value: true }); array$1.splitWhen = array$1.flatten = void 0; function flatten(items) { return items.reduce((collection, item) => [].concat(collection, item), []); } array$1.flatten = flatten; function splitWhen(items, predicate) { const result = [[]]; let groupIndex = 0; for (const item of items) { if (predicate(item)) { groupIndex++; result[groupIndex] = []; } else { result[groupIndex].push(item); } } return result; } array$1.splitWhen = splitWhen; var errno$1 = {}; Object.defineProperty(errno$1, "__esModule", { value: true }); errno$1.isEnoentCodeError = void 0; function isEnoentCodeError(error) { return error.code === 'ENOENT'; } errno$1.isEnoentCodeError = isEnoentCodeError; var fs$a = {}; Object.defineProperty(fs$a, "__esModule", { value: true }); fs$a.createDirentFromStats = void 0; let DirentFromStats$1 = class DirentFromStats { constructor(name, stats) { this.name = name; this.isBlockDevice = stats.isBlockDevice.bind(stats); this.isCharacterDevice = stats.isCharacterDevice.bind(stats); this.isDirectory = stats.isDirectory.bind(stats); this.isFIFO = stats.isFIFO.bind(stats); this.isFile = stats.isFile.bind(stats); this.isSocket = stats.isSocket.bind(stats); this.isSymbolicLink = stats.isSymbolicLink.bind(stats); } }; function createDirentFromStats$1(name, stats) { return new DirentFromStats$1(name, stats); } fs$a.createDirentFromStats = createDirentFromStats$1; var path$b = {}; Object.defineProperty(path$b, "__esModule", { value: true }); path$b.convertPosixPathToPattern = path$b.convertWindowsPathToPattern = path$b.convertPathToPattern = path$b.escapePosixPath = path$b.escapeWindowsPath = path$b.escape = path$b.removeLeadingDotSegment = path$b.makeAbsolute = path$b.unixify = void 0; const os = os$1; const path$a = path$c; const IS_WINDOWS_PLATFORM = os.platform() === 'win32'; const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\ /** * All non-escaped special characters. * Posix: ()*?[]{|}, !+@ before (, ! at the beginning, \\ before non-special characters. * Windows: (){}[], !+@ before (, ! at the beginning. */ const POSIX_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\()|\\(?![!()*+?@[\]{|}]))/g; const WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()[\]{}]|^!|[!+@](?=\())/g; /** * The device path (\\.\ or \\?\). * https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#dos-device-paths */ const DOS_DEVICE_PATH_RE = /^\\\\([.?])/; /** * All backslashes except those escaping special characters. * Windows: !()+@{} * https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions */ const WINDOWS_BACKSLASHES_RE = /\\(?![!()+@[\]{}])/g; /** * Designed to work only with simple paths: `dir\\file`. */ function unixify(filepath) { return filepath.replace(/\\/g, '/'); } path$b.unixify = unixify; function makeAbsolute(cwd, filepath) { return path$a.resolve(cwd, filepath); } path$b.makeAbsolute = makeAbsolute; function removeLeadingDotSegment(entry) { // We do not use `startsWith` because this is 10x slower than current implementation for some cases. // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with if (entry.charAt(0) === '.') { const secondCharactery = entry.charAt(1); if (secondCharactery === '/' || secondCharactery === '\\') { return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT); } } return entry; } path$b.removeLeadingDotSegment = removeLeadingDotSegment; path$b.escape = IS_WINDOWS_PLATFORM ? escapeWindowsPath : escapePosixPath; function escapeWindowsPath(pattern) { return pattern.replace(WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE, '\\$2'); } path$b.escapeWindowsPath = escapeWindowsPath; function escapePosixPath(pattern) { return pattern.replace(POSIX_UNESCAPED_GLOB_SYMBOLS_RE, '\\$2'); } path$b.escapePosixPath = escapePosixPath; path$b.convertPathToPattern = IS_WINDOWS_PLATFORM ? convertWindowsPathToPattern : convertPosixPathToPattern; function convertWindowsPathToPattern(filepath) { return escapeWindowsPath(filepath).replace(DOS_DEVICE_PATH_RE, '//$1').replace(WINDOWS_BACKSLASHES_RE, '/'); } path$b.convertWindowsPathToPattern = convertWindowsPathToPattern; function convertPosixPathToPattern(filepath) { return escapePosixPath(filepath); } path$b.convertPosixPathToPattern = convertPosixPathToPattern; var pattern$1 = {}; /*! * is-extglob * * Copyright (c) 2014-2016, Jon Schlinkert. * Licensed under the MIT License. */ var isExtglob$1 = function isExtglob(str) { if (typeof str !== 'string' || str === '') { return false; } var match; while (match = /(\\).|([@?!+*]\(.*\))/g.exec(str)) { if (match[2]) return true; str = str.slice(match.index + match[0].length); } return false; }; /*! * is-glob * * Copyright (c) 2014-2017, Jon Schlinkert. * Released under the MIT License. */ var isExtglob = isExtglob$1; var chars = { '{': '}', '(': ')', '[': ']' }; var strictCheck = function (str) { if (str[0] === '!') { return true; } var index = 0; var pipeIndex = -2; var closeSquareIndex = -2; var closeCurlyIndex = -2; var closeParenIndex = -2; var backSlashIndex = -2; while (index < str.length) { if (str[index] === '*') { return true; } if (str[index + 1] === '?' && /[\].+)]/.test(str[index])) { return true; } if (closeSquareIndex !== -1 && str[index] === '[' && str[index + 1] !== ']') { if (closeSquareIndex < index) { closeSquareIndex = str.indexOf(']', index); } if (closeSquareIndex > index) { if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) { return true; } backSlashIndex = str.indexOf('\\', index); if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) { return true; } } } if (closeCurlyIndex !== -1 && str[index] === '{' && str[index + 1] !== '}') { closeCurlyIndex = str.indexOf('}', index); if (closeCurlyIndex > index) { backSlashIndex = str.indexOf('\\', index); if (backSlashIndex === -1 || backSlashIndex > closeCurlyIndex) { return true; } } } if (closeParenIndex !== -1 && str[index] === '(' && str[index + 1] === '?' && /[:!=]/.test(str[index + 2]) && str[index + 3] !== ')') { closeParenIndex = str.indexOf(')', index); if (closeParenIndex > index) { backSlashIndex = str.indexOf('\\', index); if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) { return true; } } } if (pipeIndex !== -1 && str[index] === '(' && str[index + 1] !== '|') { if (pipeIndex < index) { pipeIndex = str.indexOf('|', index); } if (pipeIndex !== -1 && str[pipeIndex + 1] !== ')') { closeParenIndex = str.indexOf(')', pipeIndex); if (closeParenIndex > pipeIndex) { backSlashIndex = str.indexOf('\\', pipeIndex); if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) { return true; } } } } if (str[index] === '\\') { var open = str[index + 1]; index += 2; var close = chars[open]; if (close) { var n = str.indexOf(close, index); if (n !== -1) { index = n + 1; } } if (str[index] === '!') { return true; } } else { index++; } } return false; }; var relaxedCheck = function (str) { if (str[0] === '!') { return true; } var index = 0; while (index < str.length) { if (/[*?{}()[\]]/.test(str[index])) { return true; } if (str[index] === '\\') { var open = str[index + 1]; index += 2; var close = chars[open]; if (close) { var n = str.indexOf(close, index); if (n !== -1) { index = n + 1; } } if (str[index] === '!') { return true; } } else { index++; } } return false; }; var isGlob$1 = function isGlob(str, options) { if (typeof str !== 'string' || str === '') { return false; } if (isExtglob(str)) { return true; } var check = strictCheck; // optionally relax check if (options && options.strict === false) { check = relaxedCheck; } return check(str); }; var isGlob$2 = /*@__PURE__*/getDefaultExportFromCjs(isGlob$1); var isGlob = isGlob$1; var pathPosixDirname = path$c.posix.dirname; var isWin32 = os$1.platform() === 'win32'; var slash$1 = '/'; var backslash = /\\/g; var enclosure = /[\{\[].*[\}\]]$/; var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g; /** * @param {string} str * @param {Object} opts * @param {boolean} [opts.flipBackslashes=true] * @returns {string} */ var globParent$1 = function globParent(str, opts) { var options = Object.assign({ flipBackslashes: true }, opts); // flip windows path separators if (options.flipBackslashes && isWin32 && str.indexOf(slash$1) < 0) { str = str.replace(backslash, slash$1); } // special case for strings ending in enclosure containing path separator if (enclosure.test(str)) { str += slash$1; } // preserves full path in case of trailing path separator str += 'a'; // remove path parts that are globby do { str = pathPosixDirname(str); } while (isGlob(str) || globby.test(str)); // remove escape chars and return result return str.replace(escaped, '$1'); }; var utils$j = {}; (function (exports) { exports.isInteger = num => { if (typeof num === 'number') { return Number.isInteger(num); } if (typeof num === 'string' && num.trim() !== '') { return Number.isInteger(Number(num)); } return false; }; /** * Find a node of the given type */ exports.find = (node, type) => node.nodes.find(node => node.type === type); /** * Find a node of the given type */ exports.exceedsLimit = (min, max, step = 1, limit) => { if (limit === false) return false; if (!exports.isInteger(min) || !exports.isInteger(max)) return false; return (Number(max) - Number(min)) / Number(step) >= limit; }; /** * Escape the given node with '\\' before node.value */ exports.escapeNode = (block, n = 0, type) => { const node = block.nodes[n]; if (!node) return; if (type && node.type === type || node.type === 'open' || node.type === 'close') { if (node.escaped !== true) { node.value = '\\' + node.value; node.escaped = true; } } }; /** * Returns true if the given brace node should be enclosed in literal braces */ exports.encloseBrace = node => { if (node.type !== 'brace') return false; if (node.commas >> 0 + node.ranges >> 0 === 0) { node.invalid = true; return true; } return false; }; /** * Returns true if a brace node is invalid. */ exports.isInvalidBrace = block => { if (block.type !== 'brace') return false; if (block.invalid === true || block.dollar) return true; if (block.commas >> 0 + block.ranges >> 0 === 0) { block.invalid = true; return true; } if (block.open !== true || block.close !== true) { block.invalid = true; return true; } return false; }; /** * Returns true if a node is an open or close node */ exports.isOpenOrClose = node => { if (node.type === 'open' || node.type === 'close') { return true; } return node.open === true || node.close === true; }; /** * Reduce an array of text nodes. */ exports.reduce = nodes => nodes.reduce((acc, node) => { if (node.type === 'text') acc.push(node.value); if (node.type === 'range') node.type = 'text'; return acc; }, []); /** * Flatten an array */ exports.flatten = (...args) => { const result = []; const flat = arr => { for (let i = 0; i < arr.length; i++) { const ele = arr[i]; if (Array.isArray(ele)) { flat(ele); continue; } if (ele !== undefined) { result.push(ele); } } return result; }; flat(args); return result; }; })(utils$j); const utils$i = utils$j; var stringify$4 = (ast, options = {}) => { const stringify = (node, parent = {}) => { const invalidBlock = options.escapeInvalid && utils$i.isInvalidBrace(parent); const invalidNode = node.invalid === true && options.escapeInvalid === true; let output = ''; if (node.value) { if ((invalidBlock || invalidNode) && utils$i.isOpenOrClose(node)) { return '\\' + node.value; } return node.value; } if (node.value) { return node.value; } if (node.nodes) { for (const child of node.nodes) { output += stringify(child); } } return output; }; return stringify(ast); }; /*! * is-number * * Copyright (c) 2014-present, Jon Schlinkert. * Released under the MIT License. */ var isNumber$2 = function (num) { if (typeof num === 'number') { return num - num === 0; } if (typeof num === 'string' && num.trim() !== '') { return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); } return false; }; /*! * to-regex-range * * Copyright (c) 2015-present, Jon Schlinkert. * Released under the MIT License. */ const isNumber$1 = isNumber$2; const toRegexRange$1 = (min, max, options) => { if (isNumber$1(min) === false) { throw new TypeError('toRegexRange: expected the first argument to be a number'); } if (max === void 0 || min === max) { return String(min); } if (isNumber$1(max) === false) { throw new TypeError('toRegexRange: expected the second argument to be a number.'); } let opts = { relaxZeros: true, ...options }; if (typeof opts.strictZeros === 'boolean') { opts.relaxZeros = opts.strictZeros === false; } let relax = String(opts.relaxZeros); let shorthand = String(opts.shorthand); let capture = String(opts.capture); let wrap = String(opts.wrap); let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; if (toRegexRange$1.cache.hasOwnProperty(cacheKey)) { return toRegexRange$1.cache[cacheKey].result; } let a = Math.min(min, max); let b = Math.max(min, max); if (Math.abs(a - b) === 1) { let result = min + '|' + max; if (opts.capture) { return `(${result})`; } if (opts.wrap === false) { return result; } return `(?:${result})`; } let isPadded = hasPadding(min) || hasPadding(max); let state = { min, max, a, b }; let positives = []; let negatives = []; if (isPadded) { state.isPadded = isPadded; state.maxLen = String(state.max).length; } if (a < 0) { let newMin = b < 0 ? Math.abs(b) : 1; negatives = splitToPatterns(newMin, Math.abs(a), state, opts); a = state.a = 0; } if (b >= 0) { positives = splitToPatterns(a, b, state, opts); } state.negatives = negatives; state.positives = positives; state.result = collatePatterns(negatives, positives); if (opts.capture === true) { state.result = `(${state.result})`; } else if (opts.wrap !== false && positives.length + negatives.length > 1) { state.result = `(?:${state.result})`; } toRegexRange$1.cache[cacheKey] = state; return state.result; }; function collatePatterns(neg, pos, options) { let onlyNegative = filterPatterns(neg, pos, '-', false) || []; let onlyPositive = filterPatterns(pos, neg, '', false) || []; let intersected = filterPatterns(neg, pos, '-?', true) || []; let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); return subpatterns.join('|'); } function splitToRanges(min, max) { let nines = 1; let zeros = 1; let stop = countNines(min, nines); let stops = new Set([max]); while (min <= stop && stop <= max) { stops.add(stop); nines += 1; stop = countNines(min, nines); } stop = countZeros(max + 1, zeros) - 1; while (min < stop && stop <= max) { stops.add(stop); zeros += 1; stop = countZeros(max + 1, zeros) - 1; } stops = [...stops]; stops.sort(compare); return stops; } /** * Convert a range to a regex pattern * @param {Number} `start` * @param {Number} `stop` * @return {String} */ function rangeToPattern(start, stop, options) { if (start === stop) { return { pattern: start, count: [], digits: 0 }; } let zipped = zip(start, stop); let digits = zipped.length; let pattern = ''; let count = 0; for (let i = 0; i < digits; i++) { let [startDigit, stopDigit] = zipped[i]; if (startDigit === stopDigit) { pattern += startDigit; } else if (startDigit !== '0' || stopDigit !== '9') { pattern += toCharacterClass(startDigit, stopDigit); } else { count++; } } if (count) { pattern += options.shorthand === true ? '\\d' : '[0-9]'; } return { pattern, count: [count], digits }; } function splitToPatterns(min, max, tok, options) { let ranges = splitToRanges(min, max); let tokens = []; let start = min; let prev; for (let i = 0; i < ranges.length; i++) { let max = ranges[i]; let obj = rangeToPattern(String(start), String(max), options); let zeros = ''; if (!tok.isPadded && prev && prev.pattern === obj.pattern) { if (prev.count.length > 1) { prev.count.pop(); } prev.count.push(obj.count[0]); prev.string = prev.pattern + toQuantifier(prev.count); start = max + 1; continue; } if (tok.isPadded) { zeros = padZeros(max, tok, options); } obj.string = zeros + obj.pattern + toQuantifier(obj.count); tokens.push(obj); start = max + 1; prev = obj; } return tokens; } function filterPatterns(arr, comparison, prefix, intersection, options) { let result = []; for (let ele of arr) { let { string } = ele; // only push if _both_ are negative... if (!intersection && !contains(comparison, 'string', string)) { result.push(prefix + string); } // or _both_ are positive if (intersection && contains(comparison, 'string', string)) { result.push(prefix + string); } } return result; } /** * Zip strings */ function zip(a, b) { let arr = []; for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); return arr; } function compare(a, b) { return a > b ? 1 : b > a ? -1 : 0; } function contains(arr, key, val) { return arr.some(ele => ele[key] === val); } function countNines(min, len) { return Number(String(min).slice(0, -len) + '9'.repeat(len)); } function countZeros(integer, zeros) { return integer - integer % Math.pow(10, zeros); } function toQuantifier(digits) { let [start = 0, stop = ''] = digits; if (stop || start > 1) { return `{${start + (stop ? ',' + stop : '')}}`; } return ''; } function toCharacterClass(a, b, options) { return `[${a}${b - a === 1 ? '' : '-'}${b}]`; } function hasPadding(str) { return /^-?(0+)\d/.test(str); } function padZeros(value, tok, options) { if (!tok.isPadded) { return value; } let diff = Math.abs(tok.maxLen - String(value).length); let relax = options.relaxZeros !== false; switch (diff) { case 0: return ''; case 1: return relax ? '0?' : '0'; case 2: return relax ? '0{0,2}' : '00'; default: { return relax ? `0{0,${diff}}` : `0{${diff}}`; } } } /** * Cache */ toRegexRange$1.cache = {}; toRegexRange$1.clearCache = () => toRegexRange$1.cache = {}; /** * Expose `toRegexRange` */ var toRegexRange_1 = toRegexRange$1; /*! * fill-range * * Copyright (c) 2014-present, Jon Schlinkert. * Licensed under the MIT License. */ const util$2 = require$$0$1; const toRegexRange = toRegexRange_1; const isObject$1 = val => val !== null && typeof val === 'object' && !Array.isArray(val); const transform = toNumber => { return value => toNumber === true ? Number(value) : String(value); }; const isValidValue = value => { return typeof value === 'number' || typeof value === 'string' && value !== ''; }; const isNumber = num => Number.isInteger(+num); const zeros = input => { let value = `${input}`; let index = -1; if (value[0] === '-') value = value.slice(1); if (value === '0') return false; while (value[++index] === '0'); return index > 0; }; const stringify$3 = (start, end, options) => { if (typeof start === 'string' || typeof end === 'string') { return true; } return options.stringify === true; }; const pad = (input, maxLength, toNumber) => { if (maxLength > 0) { let dash = input[0] === '-' ? '-' : ''; if (dash) input = input.slice(1); input = dash + input.padStart(dash ? maxLength - 1 : maxLength, '0'); } if (toNumber === false) { return String(input); } return input; }; const toMaxLen = (input, maxLength) => { let negative = input[0] === '-' ? '-' : ''; if (negative) { input = input.slice(1); maxLength--; } while (input.length < maxLength) input = '0' + input; return negative ? '-' + input : input; }; const toSequence = (parts, options, maxLen) => { parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); let prefix = options.capture ? '' : '?:'; let positives = ''; let negatives = ''; let result; if (parts.positives.length) { positives = parts.positives.map(v => toMaxLen(String(v), maxLen)).join('|'); } if (parts.negatives.length) { negatives = `-(${prefix}${parts.negatives.map(v => toMaxLen(String(v), maxLen)).join('|')})`; } if (positives && negatives) { result = `${positives}|${negatives}`; } else { result = positives || negatives; } if (options.wrap) { return `(${prefix}${result})`; } return result; }; const toRange = (a, b, isNumbers, options) => { if (isNumbers) { return toRegexRange(a, b, { wrap: false, ...options }); } let start = String.fromCharCode(a); if (a === b) return start; let stop = String.fromCharCode(b); return `[${start}-${stop}]`; }; const toRegex = (start, end, options) => { if (Array.isArray(start)) { let wrap = options.wrap === true; let prefix = options.capture ? '' : '?:'; return wrap ? `(${prefix}${start.join('|')})` : start.join('|'); } return toRegexRange(start, end, options); }; const rangeError = (...args) => { return new RangeError('Invalid range arguments: ' + util$2.inspect(...args)); }; const invalidRange = (start, end, options) => { if (options.strictRanges === true) throw rangeError([start, end]); return []; }; const invalidStep = (step, options) => { if (options.strictRanges === true) { throw new TypeError(`Expected step "${step}" to be a number`); } return []; }; const fillNumbers = (start, end, step = 1, options = {}) => { let a = Number(start); let b = Number(end); if (!Number.isInteger(a) || !Number.isInteger(b)) { if (options.strictRanges === true) throw rangeError([start, end]); return []; } // fix negative zero if (a === 0) a = 0; if (b === 0) b = 0; let descending = a > b; let startString = String(start); let endString = String(end); let stepString = String(step); step = Math.max(Math.abs(step), 1); let padded = zeros(startString) || zeros(endString) || zeros(stepString); let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0; let toNumber = padded === false && stringify$3(start, end, options) === false; let format = options.transform || transform(toNumber); if (options.toRegex && step === 1) { return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); } let parts = { negatives: [], positives: [] }; let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); let range = []; let index = 0; while (descending ? a >= b : a <= b) { if (options.toRegex === true && step > 1) { push(a); } else { range.push(pad(format(a, index), maxLen, toNumber)); } a = descending ? a - step : a + step; index++; } if (options.toRegex === true) { return step > 1 ? toSequence(parts, options, maxLen) : toRegex(range, null, { wrap: false, ...options }); } return range; }; const fillLetters = (start, end, step = 1, options = {}) => { if (!isNumber(start) && start.length > 1 || !isNumber(end) && end.length > 1) { return invalidRange(start, end, options); } let format = options.transform || (val => String.fromCharCode(val)); let a = `${start}`.charCodeAt(0); let b = `${end}`.charCodeAt(0); let descending = a > b; let min = Math.min(a, b); let max = Math.max(a, b); if (options.toRegex && step === 1) { return toRange(min, max, false, options); } let range = []; let index = 0; while (descending ? a >= b : a <= b) { range.push(format(a, index)); a = descending ? a - step : a + step; index++; } if (options.toRegex === true) { return toRegex(range, null, { wrap: false, options }); } return range; }; const fill$2 = (start, end, step, options = {}) => { if (end == null && isValidValue(start)) { return [start]; } if (!isValidValue(start) || !isValidValue(end)) { return invalidRange(start, end, options); } if (typeof step === 'function') { return fill$2(start, end, 1, { transform: step }); } if (isObject$1(step)) { return fill$2(start, end, 0, step); } let opts = { ...options }; if (opts.capture === true) opts.wrap = true; step = step || opts.step || 1; if (!isNumber(step)) { if (step != null && !isObject$1(step)) return invalidStep(step, opts); return fill$2(start, end, 1, step); } if (isNumber(start) && isNumber(end)) { return fillNumbers(start, end, step, opts); } return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); }; var fillRange = fill$2; const fill$1 = fillRange; const utils$h = utils$j; const compile$1 = (ast, options = {}) => { const walk = (node, parent = {}) => { const invalidBlock = utils$h.isInvalidBrace(parent); const invalidNode = node.invalid === true && options.escapeInvalid === true; const invalid = invalidBlock === true || invalidNode === true; const prefix = options.escapeInvalid === true ? '\\' : ''; let output = ''; if (node.isOpen === true) { return prefix + node.value; } if (node.isClose === true) { console.log('node.isClose', prefix, node.value); return prefix + node.value; } if (node.type === 'open') { return invalid ? prefix + node.value : '('; } if (node.type === 'close') { return invalid ? prefix + node.value : ')'; } if (node.type === 'comma') { return node.prev.type === 'comma' ? '' : invalid ? node.value : '|'; } if (node.value) { return node.value; } if (node.nodes && node.ranges > 0) { const args = utils$h.reduce(node.nodes); const range = fill$1(...args, { ...options, wrap: false, toRegex: true, strictZeros: true }); if (range.length !== 0) { return args.length > 1 && range.length > 1 ? `(${range})` : range; } } if (node.nodes) { for (const child of node.nodes) { output += walk(child, node); } } return output; }; return walk(ast); }; var compile_1 = compile$1; const fill = fillRange; const stringify$2 = stringify$4; const utils$g = utils$j; const append = (queue = '', stash = '', enclose = false) => { const result = []; queue = [].concat(queue); stash = [].concat(stash); if (!stash.length) return queue; if (!queue.length) { return enclose ? utils$g.flatten(stash).map(ele => `{${ele}}`) : stash; } for (const item of queue) { if (Array.isArray(item)) { for (const value of item) { result.push(append(value, stash, enclose)); } } else { for (let ele of stash) { if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; result.push(Array.isArray(ele) ? append(item, ele, enclose) : item + ele); } } } return utils$g.flatten(result); }; const expand$1 = (ast, options = {}) => { const rangeLimit = options.rangeLimit === undefined ? 1000 : options.rangeLimit; const walk = (node, parent = {}) => { node.queue = []; let p = parent; let q = parent.queue; while (p.type !== 'brace' && p.type !== 'root' && p.parent) { p = p.parent; q = p.queue; } if (node.invalid || node.dollar) { q.push(append(q.pop(), stringify$2(node, options))); return; } if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { q.push(append(q.pop(), ['{}'])); return; } if (node.nodes && node.ranges > 0) { const args = utils$g.reduce(node.nodes); if (utils$g.exceedsLimit(...args, options.step, rangeLimit)) { throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); } let range = fill(...args, options); if (range.length === 0) { range = stringify$2(node, options); } q.push(append(q.pop(), range)); node.nodes = []; return; } const enclose = utils$g.encloseBrace(node); let queue = node.queue; let block = node; while (block.type !== 'brace' && block.type !== 'root' && block.parent) { block = block.parent; queue = block.queue; } for (let i = 0; i < node.nodes.length; i++) { const child = node.nodes[i]; if (child.type === 'comma' && node.type === 'brace') { if (i === 1) queue.push(''); queue.push(''); continue; } if (child.type === 'close') { q.push(append(q.pop(), queue, enclose)); continue; } if (child.value && child.type !== 'open') { queue.push(append(queue.pop(), child.value)); continue; } if (child.nodes) { walk(child, node); } } return queue; }; return utils$g.flatten(walk(ast)); }; var expand_1 = expand$1; var constants$5 = { MAX_LENGTH: 10000, // Digits CHAR_0: '0', /* 0 */ CHAR_9: '9', /* 9 */ // Alphabet chars. CHAR_UPPERCASE_A: 'A', /* A */ CHAR_LOWERCASE_A: 'a', /* a */ CHAR_UPPERCASE_Z: 'Z', /* Z */ CHAR_LOWERCASE_Z: 'z', /* z */ CHAR_LEFT_PARENTHESES: '(', /* ( */ CHAR_RIGHT_PARENTHESES: ')', /* ) */ CHAR_ASTERISK: '*', /* * */ // Non-alphabetic chars. CHAR_AMPERSAND: '&', /* & */ CHAR_AT: '@', /* @ */ CHAR_BACKSLASH: '\\', /* \ */ CHAR_BACKTICK: '`', /* ` */ CHAR_CARRIAGE_RETURN: '\r', /* \r */ CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ CHAR_COLON: ':', /* : */ CHAR_COMMA: ',', /* , */ CHAR_DOLLAR: '$', /* . */ CHAR_DOT: '.', /* . */ CHAR_DOUBLE_QUOTE: '"', /* " */ CHAR_EQUAL: '=', /* = */ CHAR_EXCLAMATION_MARK: '!', /* ! */ CHAR_FORM_FEED: '\f', /* \f */ CHAR_FORWARD_SLASH: '/', /* / */ CHAR_HASH: '#', /* # */ CHAR_HYPHEN_MINUS: '-', /* - */ CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ CHAR_LEFT_CURLY_BRACE: '{', /* { */ CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ CHAR_LINE_FEED: '\n', /* \n */ CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ CHAR_PERCENT: '%', /* % */ CHAR_PLUS: '+', /* + */ CHAR_QUESTION_MARK: '?', /* ? */ CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ CHAR_RIGHT_CURLY_BRACE: '}', /* } */ CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ CHAR_SEMICOLON: ';', /* ; */ CHAR_SINGLE_QUOTE: '\'', /* ' */ CHAR_SPACE: ' ', /* */ CHAR_TAB: '\t', /* \t */ CHAR_UNDERSCORE: '_', /* _ */ CHAR_VERTICAL_LINE: '|', /* | */ CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ }; const stringify$1 = stringify$4; /** * Constants */ const { MAX_LENGTH: MAX_LENGTH$1, CHAR_BACKSLASH, /* \ */ CHAR_BACKTICK, /* ` */ CHAR_COMMA: CHAR_COMMA$1, /* , */ CHAR_DOT: CHAR_DOT$1, /* . */ CHAR_LEFT_PARENTHESES: CHAR_LEFT_PARENTHESES$1, /* ( */ CHAR_RIGHT_PARENTHESES: CHAR_RIGHT_PARENTHESES$1, /* ) */ CHAR_LEFT_CURLY_BRACE: CHAR_LEFT_CURLY_BRACE$1, /* { */ CHAR_RIGHT_CURLY_BRACE: CHAR_RIGHT_CURLY_BRACE$1, /* } */ CHAR_LEFT_SQUARE_BRACKET: CHAR_LEFT_SQUARE_BRACKET$1, /* [ */ CHAR_RIGHT_SQUARE_BRACKET: CHAR_RIGHT_SQUARE_BRACKET$1, /* ] */ CHAR_DOUBLE_QUOTE, /* " */ CHAR_SINGLE_QUOTE, /* ' */ CHAR_NO_BREAK_SPACE, CHAR_ZERO_WIDTH_NOBREAK_SPACE } = constants$5; /** * parse */ const parse$3 = (input, options = {}) => { if (typeof input !== 'string') { throw new TypeError('Expected a string'); } const opts = options || {}; const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$1, opts.maxLength) : MAX_LENGTH$1; if (input.length > max) { throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); } const ast = { type: 'root', input, nodes: [] }; const stack = [ast]; let block = ast; let prev = ast; let brackets = 0; const length = input.length; let index = 0; let depth = 0; let value; /** * Helpers */ const advance = () => input[index++]; const push = node => { if (node.type === 'text' && prev.type === 'dot') { prev.type = 'text'; } if (prev && prev.type === 'text' && node.type === 'text') { prev.value += node.value; return; } block.nodes.push(node); node.parent = block; node.prev = prev; prev = node; return node; }; push({ type: 'bos' }); while (index < length) { block = stack[stack.length - 1]; value = advance(); /** * Invalid chars */ if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { continue; } /** * Escaped chars */ if (value === CHAR_BACKSLASH) { push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); continue; } /** * Right square bracket (literal): ']' */ if (value === CHAR_RIGHT_SQUARE_BRACKET$1) { push({ type: 'text', value: '\\' + value }); continue; } /** * Left square bracket: '[' */ if (value === CHAR_LEFT_SQUARE_BRACKET$1) { brackets++; let next; while (index < length && (next = advance())) { value += next; if (next === CHAR_LEFT_SQUARE_BRACKET$1) { brackets++; continue; } if (next === CHAR_BACKSLASH) { value += advance(); continue; } if (next === CHAR_RIGHT_SQUARE_BRACKET$1) { brackets--; if (brackets === 0) { break; } } } push({ type: 'text', value }); continue; } /** * Parentheses */ if (value === CHAR_LEFT_PARENTHESES$1) { block = push({ type: 'paren', nodes: [] }); stack.push(block); push({ type: 'text', value }); continue; } if (value === CHAR_RIGHT_PARENTHESES$1) { if (block.type !== 'paren') { push({ type: 'text', value }); continue; } block = stack.pop(); push({ type: 'text', value }); block = stack[stack.length - 1]; continue; } /** * Quotes: '|"|` */ if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { const open = value; let next; if (options.keepQuotes !== true) { value = ''; } while (index < length && (next = advance())) { if (next === CHAR_BACKSLASH) { value += next + advance(); continue; } if (next === open) { if (options.keepQuotes === true) value += next; break; } value += next; } push({ type: 'text', value }); continue; } /** * Left curly brace: '{' */ if (value === CHAR_LEFT_CURLY_BRACE$1) { depth++; const dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; const brace = { type: 'brace', open: true, close: false, dollar, depth, commas: 0, ranges: 0, nodes: [] }; block = push(brace); stack.push(block); push({ type: 'open', value }); continue; } /** * Right curly brace: '}' */ if (value === CHAR_RIGHT_CURLY_BRACE$1) { if (block.type !== 'brace') { push({ type: 'text', value }); continue; } const type = 'close'; block = stack.pop(); block.close = true; push({ type, value }); depth--; block = stack[stack.length - 1]; continue; } /** * Comma: ',' */ if (value === CHAR_COMMA$1 && depth > 0) { if (block.ranges > 0) { block.ranges = 0; const open = block.nodes.shift(); block.nodes = [open, { type: 'text', value: stringify$1(block) }]; } push({ type: 'comma', value }); block.commas++; continue; } /** * Dot: '.' */ if (value === CHAR_DOT$1 && depth > 0 && block.commas === 0) { const siblings = block.nodes; if (depth === 0 || siblings.length === 0) { push({ type: 'text', value }); continue; } if (prev.type === 'dot') { block.range = []; prev.value += value; prev.type = 'range'; if (block.nodes.length !== 3 && block.nodes.length !== 5) { block.invalid = true; block.ranges = 0; prev.type = 'text'; continue; } block.ranges++; block.args = []; continue; } if (prev.type === 'range') { siblings.pop(); const before = siblings[siblings.length - 1]; before.value += prev.value + value; prev = before; block.ranges--; continue; } push({ type: 'dot', value }); continue; } /** * Text */ push({ type: 'text', value }); } // Mark imbalanced braces and brackets as invalid do { block = stack.pop(); if (block.type !== 'root') { block.nodes.forEach(node => { if (!node.nodes) { if (node.type === 'open') node.isOpen = true; if (node.type === 'close') node.isClose = true; if (!node.nodes) node.type = 'text'; node.invalid = true; } }); // get the location of the block on parent.nodes (block's siblings) const parent = stack[stack.length - 1]; const index = parent.nodes.indexOf(block); // replace the (invalid) block with it's nodes parent.nodes.splice(index, 1, ...block.nodes); } } while (stack.length > 0); push({ type: 'eos' }); return ast; }; var parse_1$1 = parse$3; const stringify = stringify$4; const compile = compile_1; const expand = expand_1; const parse$2 = parse_1$1; /** * Expand the given pattern or create a regex-compatible string. * * ```js * const braces = require('braces'); * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] * ``` * @param {String} `str` * @param {Object} `options` * @return {String} * @api public */ const braces$1 = (input, options = {}) => { let output = []; if (Array.isArray(input)) { for (const pattern of input) { const result = braces$1.create(pattern, options); if (Array.isArray(result)) { output.push(...result); } else { output.push(result); } } } else { output = [].concat(braces$1.create(input, options)); } if (options && options.expand === true && options.nodupes === true) { output = [...new Set(output)]; } return output; }; /** * Parse the given `str` with the given `options`. * * ```js * // braces.parse(pattern, [, options]); * const ast = braces.parse('a/{b,c}/d'); * console.log(ast); * ``` * @param {String} pattern Brace pattern to parse * @param {Object} options * @return {Object} Returns an AST * @api public */ braces$1.parse = (input, options = {}) => parse$2(input, options); /** * Creates a braces string from an AST, or an AST node. * * ```js * const braces = require('braces'); * let ast = braces.parse('foo/{a,b}/bar'); * console.log(stringify(ast.nodes[2])); //=> '{a,b}' * ``` * @param {String} `input` Brace pattern or AST. * @param {Object} `options` * @return {Array} Returns an array of expanded values. * @api public */ braces$1.stringify = (input, options = {}) => { if (typeof input === 'string') { return stringify(braces$1.parse(input, options), options); } return stringify(input, options); }; /** * Compiles a brace pattern into a regex-compatible, optimized string. * This method is called by the main [braces](#braces) function by default. * * ```js * const braces = require('braces'); * console.log(braces.compile('a/{b,c}/d')); * //=> ['a/(b|c)/d'] * ``` * @param {String} `input` Brace pattern or AST. * @param {Object} `options` * @return {Array} Returns an array of expanded values. * @api public */ braces$1.compile = (input, options = {}) => { if (typeof input === 'string') { input = braces$1.parse(input, options); } return compile(input, options); }; /** * Expands a brace pattern into an array. This method is called by the * main [braces](#braces) function when `options.expand` is true. Before * using this method it's recommended that you read the [performance notes](#performance)) * and advantages of using [.compile](#compile) instead. * * ```js * const braces = require('braces'); * console.log(braces.expand('a/{b,c}/d')); * //=> ['a/b/d', 'a/c/d']; * ``` * @param {String} `pattern` Brace pattern * @param {Object} `options` * @return {Array} Returns an array of expanded values. * @api public */ braces$1.expand = (input, options = {}) => { if (typeof input === 'string') { input = braces$1.parse(input, options); } let result = expand(input, options); // filter out empty strings if specified if (options.noempty === true) { result = result.filter(Boolean); } // filter out duplicates if specified if (options.nodupes === true) { result = [...new Set(result)]; } return result; }; /** * Processes a brace pattern and returns either an expanded array * (if `options.expand` is true), a highly optimized regex-compatible string. * This method is called by the main [braces](#braces) function. * * ```js * const braces = require('braces'); * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' * ``` * @param {String} `pattern` Brace pattern * @param {Object} `options` * @return {Array} Returns an array of expanded values. * @api public */ braces$1.create = (input, options = {}) => { if (input === '' || input.length < 3) { return [input]; } return options.expand !== true ? braces$1.compile(input, options) : braces$1.expand(input, options); }; /** * Expose "braces" */ var braces_1 = braces$1; var utils$f = {}; const path$9 = path$c; const WIN_SLASH = '\\\\/'; const WIN_NO_SLASH = `[^${WIN_SLASH}]`; /** * Posix glob regex */ const DOT_LITERAL = '\\.'; const PLUS_LITERAL = '\\+'; const QMARK_LITERAL = '\\?'; const SLASH_LITERAL = '\\/'; const ONE_CHAR = '(?=.)'; const QMARK = '[^/]'; const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; const NO_DOT = `(?!${DOT_LITERAL})`; const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; const STAR = `${QMARK}*?`; const POSIX_CHARS = { DOT_LITERAL, PLUS_LITERAL, QMARK_LITERAL, SLASH_LITERAL, ONE_CHAR, QMARK, END_ANCHOR, DOTS_SLASH, NO_DOT, NO_DOTS, NO_DOT_SLASH, NO_DOTS_SLASH, QMARK_NO_DOT, STAR, START_ANCHOR }; /** * Windows glob regex */ const WINDOWS_CHARS = { ...POSIX_CHARS, SLASH_LITERAL: `[${WIN_SLASH}]`, QMARK: WIN_NO_SLASH, STAR: `${WIN_NO_SLASH}*?`, DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, NO_DOT: `(?!${DOT_LITERAL})`, NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, QMARK_NO_DOT: `[^.${WIN_SLASH}]`, START_ANCHOR: `(?:^|[${WIN_SLASH}])`, END_ANCHOR: `(?:[${WIN_SLASH}]|$)` }; /** * POSIX Bracket Regex */ const POSIX_REGEX_SOURCE$1 = { alnum: 'a-zA-Z0-9', alpha: 'a-zA-Z', ascii: '\\x00-\\x7F', blank: ' \\t', cntrl: '\\x00-\\x1F\\x7F', digit: '0-9', graph: '\\x21-\\x7E', lower: 'a-z', print: '\\x20-\\x7E ', punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', space: ' \\t\\r\\n\\v\\f', upper: 'A-Z', word: 'A-Za-z0-9_', xdigit: 'A-Fa-f0-9' }; var constants$4 = { MAX_LENGTH: 1024 * 64, POSIX_REGEX_SOURCE: POSIX_REGEX_SOURCE$1, // regular expressions REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, // Replace globs with equivalent patterns to reduce parsing time. REPLACEMENTS: { '***': '*', '**/**': '**', '**/**/**': '**' }, // Digits CHAR_0: 48, /* 0 */ CHAR_9: 57, /* 9 */ // Alphabet chars. CHAR_UPPERCASE_A: 65, /* A */ CHAR_LOWERCASE_A: 97, /* a */ CHAR_UPPERCASE_Z: 90, /* Z */ CHAR_LOWERCASE_Z: 122, /* z */ CHAR_LEFT_PARENTHESES: 40, /* ( */ CHAR_RIGHT_PARENTHESES: 41, /* ) */ CHAR_ASTERISK: 42, /* * */ // Non-alphabetic chars. CHAR_AMPERSAND: 38, /* & */ CHAR_AT: 64, /* @ */ CHAR_BACKWARD_SLASH: 92, /* \ */ CHAR_CARRIAGE_RETURN: 13, /* \r */ CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ CHAR_COLON: 58, /* : */ CHAR_COMMA: 44, /* , */ CHAR_DOT: 46, /* . */ CHAR_DOUBLE_QUOTE: 34, /* " */ CHAR_EQUAL: 61, /* = */ CHAR_EXCLAMATION_MARK: 33, /* ! */ CHAR_FORM_FEED: 12, /* \f */ CHAR_FORWARD_SLASH: 47, /* / */ CHAR_GRAVE_ACCENT: 96, /* ` */ CHAR_HASH: 35, /* # */ CHAR_HYPHEN_MINUS: 45, /* - */ CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ CHAR_LEFT_CURLY_BRACE: 123, /* { */ CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ CHAR_LINE_FEED: 10, /* \n */ CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ CHAR_PERCENT: 37, /* % */ CHAR_PLUS: 43, /* + */ CHAR_QUESTION_MARK: 63, /* ? */ CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ CHAR_RIGHT_CURLY_BRACE: 125, /* } */ CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ CHAR_SEMICOLON: 59, /* ; */ CHAR_SINGLE_QUOTE: 39, /* ' */ CHAR_SPACE: 32, /* */ CHAR_TAB: 9, /* \t */ CHAR_UNDERSCORE: 95, /* _ */ CHAR_VERTICAL_LINE: 124, /* | */ CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ SEP: path$9.sep, /** * Create EXTGLOB_CHARS */ extglobChars(chars) { return { '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, '?': { type: 'qmark', open: '(?:', close: ')?' }, '+': { type: 'plus', open: '(?:', close: ')+' }, '*': { type: 'star', open: '(?:', close: ')*' }, '@': { type: 'at', open: '(?:', close: ')' } }; }, /** * Create GLOB_CHARS */ globChars(win32) { return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; } }; (function (exports) { const path = path$c; const win32 = process.platform === 'win32'; const { REGEX_BACKSLASH, REGEX_REMOVE_BACKSLASH, REGEX_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_GLOBAL } = constants$4; exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); exports.removeBackslashes = str => { return str.replace(REGEX_REMOVE_BACKSLASH, match => { return match === '\\' ? '' : match; }); }; exports.supportsLookbehinds = () => { const segs = process.version.slice(1).split('.').map(Number); if (segs.length === 3 && segs[0] >= 9 || segs[0] === 8 && segs[1] >= 10) { return true; } return false; }; exports.isWindows = options => { if (options && typeof options.windows === 'boolean') { return options.windows; } return win32 === true || path.sep === '\\'; }; exports.escapeLast = (input, char, lastIdx) => { const idx = input.lastIndexOf(char, lastIdx); if (idx === -1) return input; if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); return `${input.slice(0, idx)}\\${input.slice(idx)}`; }; exports.removePrefix = (input, state = {}) => { let output = input; if (output.startsWith('./')) { output = output.slice(2); state.prefix = './'; } return output; }; exports.wrapOutput = (input, state = {}, options = {}) => { const prepend = options.contains ? '' : '^'; const append = options.contains ? '' : '$'; let output = `${prepend}(?:${input})${append}`; if (state.negated === true) { output = `(?:^(?!${output}).*$)`; } return output; }; })(utils$f); const utils$e = utils$f; const { CHAR_ASTERISK, /* * */ CHAR_AT, /* @ */ CHAR_BACKWARD_SLASH, /* \ */ CHAR_COMMA, /* , */ CHAR_DOT, /* . */ CHAR_EXCLAMATION_MARK, /* ! */ CHAR_FORWARD_SLASH, /* / */ CHAR_LEFT_CURLY_BRACE, /* { */ CHAR_LEFT_PARENTHESES, /* ( */ CHAR_LEFT_SQUARE_BRACKET, /* [ */ CHAR_PLUS, /* + */ CHAR_QUESTION_MARK, /* ? */ CHAR_RIGHT_CURLY_BRACE, /* } */ CHAR_RIGHT_PARENTHESES, /* ) */ CHAR_RIGHT_SQUARE_BRACKET /* ] */ } = constants$4; const isPathSeparator = code => { return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; }; const depth = token => { if (token.isPrefix !== true) { token.depth = token.isGlobstar ? Infinity : 1; } }; /** * Quickly scans a glob pattern and returns an object with a handful of * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). * * ```js * const pm = require('picomatch'); * console.log(pm.scan('foo/bar/*.js')); * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } * ``` * @param {String} `str` * @param {Object} `options` * @return {Object} Returns an object with tokens and regex source string. * @api public */ const scan$1 = (input, options) => { const opts = options || {}; const length = input.length - 1; const scanToEnd = opts.parts === true || opts.scanToEnd === true; const slashes = []; const tokens = []; const parts = []; let str = input; let index = -1; let start = 0; let lastIndex = 0; let isBrace = false; let isBracket = false; let isGlob = false; let isExtglob = false; let isGlobstar = false; let braceEscaped = false; let backslashes = false; let negated = false; let negatedExtglob = false; let finished = false; let braces = 0; let prev; let code; let token = { value: '', depth: 0, isGlob: false }; const eos = () => index >= length; const peek = () => str.charCodeAt(index + 1); const advance = () => { prev = code; return str.charCodeAt(++index); }; while (index < length) { code = advance(); let next; if (code === CHAR_BACKWARD_SLASH) { backslashes = token.backslashes = true; code = advance(); if (code === CHAR_LEFT_CURLY_BRACE) { braceEscaped = true; } continue; } if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { braces++; while (eos() !== true && (code = advance())) { if (code === CHAR_BACKWARD_SLASH) { backslashes = token.backslashes = true; advance(); continue; } if (code === CHAR_LEFT_CURLY_BRACE) { braces++; continue; } if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { isBrace = token.isBrace = true; isGlob = token.isGlob = true; finished = true; if (scanToEnd === true) { continue; } break; } if (braceEscaped !== true && code === CHAR_COMMA) { isBrace = token.isBrace = true; isGlob = token.isGlob = true; finished = true; if (scanToEnd === true) { continue; } break; } if (code === CHAR_RIGHT_CURLY_BRACE) { braces--; if (braces === 0) { braceEscaped = false; isBrace = token.isBrace = true; finished = true; break; } } } if (scanToEnd === true) { continue; } break; } if (code === CHAR_FORWARD_SLASH) { slashes.push(index); tokens.push(token); token = { value: '', depth: 0, isGlob: false }; if (finished === true) continue; if (prev === CHAR_DOT && index === start + 1) { start += 2; continue; } lastIndex = index + 1; continue; } if (opts.noext !== true) { const isExtglobChar = code === CHAR_PLUS || code === CHAR_AT || code === CHAR_ASTERISK || code === CHAR_QUESTION_MARK || code === CHAR_EXCLAMATION_MARK; if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { isGlob = token.isGlob = true; isExtglob = token.isExtglob = true; finished = true; if (code === CHAR_EXCLAMATION_MARK && index === start) { negatedExtglob = true; } if (scanToEnd === true) { while (eos() !== true && (code = advance())) { if (code === CHAR_BACKWARD_SLASH) { backslashes = token.backslashes = true; code = advance(); continue; } if (code === CHAR_RIGHT_PARENTHESES) { isGlob = token.isGlob = true; finished = true; break; } } continue; } break; } } if (code === CHAR_ASTERISK) { if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; isGlob = token.isGlob = true; finished = true; if (scanToEnd === true) { continue; } break; } if (code === CHAR_QUESTION_MARK) { isGlob = token.isGlob = true; finished = true; if (scanToEnd === true) { continue; } break; } if (code === CHAR_LEFT_SQUARE_BRACKET) { while (eos() !== true && (next = advance())) { if (next === CHAR_BACKWARD_SLASH) { backslashes = token.backslashes = true; advance(); continue; } if (next === CHAR_RIGHT_SQUARE_BRACKET) { isBracket = token.isBracket = true; isGlob = token.isGlob = true; finished = true; break; } } if (scanToEnd === true) { continue; } break; } if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { negated = token.negated = true; start++; continue; } if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { isGlob = token.isGlob = true; if (scanToEnd === true) { while (eos() !== true && (code = advance())) { if (code === CHAR_LEFT_PARENTHESES) { backslashes = token.backslashes = true; code = advance(); continue; } if (code === CHAR_RIGHT_PARENTHESES) { finished = true; break; } } continue; } break; } if (isGlob === true) { finished = true; if (scanToEnd === true) { continue; } break; } } if (opts.noext === true) { isExtglob = false; isGlob = false; } let base = str; let prefix = ''; let glob = ''; if (start > 0) { prefix = str.slice(0, start); str = str.slice(start); lastIndex -= start; } if (base && isGlob === true && lastIndex > 0) { base = str.slice(0, lastIndex); glob = str.slice(lastIndex); } else if (isGlob === true) { base = ''; glob = str; } else { base = str; } if (base && base !== '' && base !== '/' && base !== str) { if (isPathSeparator(base.charCodeAt(base.length - 1))) { base = base.slice(0, -1); } } if (opts.unescape === true) { if (glob) glob = utils$e.removeBackslashes(glob); if (base && backslashes === true) { base = utils$e.removeBackslashes(base); } } const state = { prefix, input, start, base, glob, isBrace, isBracket, isGlob, isExtglob, isGlobstar, negated, negatedExtglob }; if (opts.tokens === true) { state.maxDepth = 0; if (!isPathSeparator(code)) { tokens.push(token); } state.tokens = tokens; } if (opts.parts === true || opts.tokens === true) { let prevIndex; for (let idx = 0; idx < slashes.length; idx++) { const n = prevIndex ? prevIndex + 1 : start; const i = slashes[idx]; const value = input.slice(n, i); if (opts.tokens) { if (idx === 0 && start !== 0) { tokens[idx].isPrefix = true; tokens[idx].value = prefix; } else { tokens[idx].value = value; } depth(tokens[idx]); state.maxDepth += tokens[idx].depth; } if (idx !== 0 || value !== '') { parts.push(value); } prevIndex = i; } if (prevIndex && prevIndex + 1 < input.length) { const value = input.slice(prevIndex + 1); parts.push(value); if (opts.tokens) { tokens[tokens.length - 1].value = value; depth(tokens[tokens.length - 1]); state.maxDepth += tokens[tokens.length - 1].depth; } } state.slashes = slashes; state.parts = parts; } return state; }; var scan_1 = scan$1; const constants$3 = constants$4; const utils$d = utils$f; /** * Constants */ const { MAX_LENGTH, POSIX_REGEX_SOURCE, REGEX_NON_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_BACKREF, REPLACEMENTS } = constants$3; /** * Helpers */ const expandRange = (args, options) => { if (typeof options.expandRange === 'function') { return options.expandRange(...args, options); } args.sort(); const value = `[${args.join('-')}]`; try { /* eslint-disable-next-line no-new */ new RegExp(value); } catch (ex) { return args.map(v => utils$d.escapeRegex(v)).join('..'); } return value; }; /** * Create the message for a syntax error */ const syntaxError = (type, char) => { return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; }; /** * Parse the given input string. * @param {String} input * @param {Object} options * @return {Object} */ const parse$1 = (input, options) => { if (typeof input !== 'string') { throw new TypeError('Expected a string'); } input = REPLACEMENTS[input] || input; const opts = { ...options }; const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; let len = input.length; if (len > max) { throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); } const bos = { type: 'bos', value: '', output: opts.prepend || '' }; const tokens = [bos]; const capture = opts.capture ? '' : '?:'; const win32 = utils$d.isWindows(options); // create constants based on platform, for windows or posix const PLATFORM_CHARS = constants$3.globChars(win32); const EXTGLOB_CHARS = constants$3.extglobChars(PLATFORM_CHARS); const { DOT_LITERAL, PLUS_LITERAL, SLASH_LITERAL, ONE_CHAR, DOTS_SLASH, NO_DOT, NO_DOT_SLASH, NO_DOTS_SLASH, QMARK, QMARK_NO_DOT, STAR, START_ANCHOR } = PLATFORM_CHARS; const globstar = opts => { return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; }; const nodot = opts.dot ? '' : NO_DOT; const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; let star = opts.bash === true ? globstar(opts) : STAR; if (opts.capture) { star = `(${star})`; } // minimatch options support if (typeof opts.noext === 'boolean') { opts.noextglob = opts.noext; } const state = { input, index: -1, start: 0, dot: opts.dot === true, consumed: '', output: '', prefix: '', backtrack: false, negated: false, brackets: 0, braces: 0, parens: 0, quotes: 0, globstar: false, tokens }; input = utils$d.removePrefix(input, state); len = input.length; const extglobs = []; const braces = []; const stack = []; let prev = bos; let value; /** * Tokenizing helpers */ const eos = () => state.index === len - 1; const peek = state.peek = (n = 1) => input[state.index + n]; const advance = state.advance = () => input[++state.index] || ''; const remaining = () => input.slice(state.index + 1); const consume = (value = '', num = 0) => { state.consumed += value; state.index += num; }; const append = token => { state.output += token.output != null ? token.output : token.value; consume(token.value); }; const negate = () => { let count = 1; while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { advance(); state.start++; count++; } if (count % 2 === 0) { return false; } state.negated = true; state.start++; return true; }; const increment = type => { state[type]++; stack.push(type); }; const decrement = type => { state[type]--; stack.pop(); }; /** * Push tokens onto the tokens array. This helper speeds up * tokenizing by 1) helping us avoid backtracking as much as possible, * and 2) helping us avoid creating extra tokens when consecutive * characters are plain text. This improves performance and simplifies * lookbehinds. */ const push = tok => { if (prev.type === 'globstar') { const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); const isExtglob = tok.extglob === true || extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'); if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { state.output = state.output.slice(0, -prev.output.length); prev.type = 'star'; prev.value = '*'; prev.output = star; state.output += prev.output; } } if (extglobs.length && tok.type !== 'paren') { extglobs[extglobs.length - 1].inner += tok.value; } if (tok.value || tok.output) append(tok); if (prev && prev.type === 'text' && tok.type === 'text') { prev.value += tok.value; prev.output = (prev.output || '') + tok.value; return; } tok.prev = prev; tokens.push(tok); prev = tok; }; const extglobOpen = (type, value) => { const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; token.prev = prev; token.parens = state.parens; token.output = state.output; const output = (opts.capture ? '(' : '') + token.open; increment('parens'); push({ type, value, output: state.output ? '' : ONE_CHAR }); push({ type: 'paren', extglob: true, value: advance(), output }); extglobs.push(token); }; const extglobClose = token => { let output = token.close + (opts.capture ? ')' : ''); let rest; if (token.type === 'negate') { let extglobStar = star; if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { extglobStar = globstar(opts); } if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { output = token.close = `)$))${extglobStar}`; } if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis. // In this case, we need to parse the string and use it in the output of the original pattern. // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`. // // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`. const expression = parse$1(rest, { ...options, fastpaths: false }).output; output = token.close = `)${expression})${extglobStar})`; } if (token.prev.type === 'bos') { state.negatedExtglob = true; } } push({ type: 'paren', extglob: true, value, output }); decrement('parens'); }; /** * Fast paths */ if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { let backslashes = false; let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { if (first === '\\') { backslashes = true; return m; } if (first === '?') { if (esc) { return esc + first + (rest ? QMARK.repeat(rest.length) : ''); } if (index === 0) { return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); } return QMARK.repeat(chars.length); } if (first === '.') { return DOT_LITERAL.repeat(chars.length); } if (first === '*') { if (esc) { return esc + first + (rest ? star : ''); } return star; } return esc ? m : `\\${m}`; }); if (backslashes === true) { if (opts.unescape === true) { output = output.replace(/\\/g, ''); } else { output = output.replace(/\\+/g, m => { return m.length % 2 === 0 ? '\\\\' : m ? '\\' : ''; }); } } if (output === input && opts.contains === true) { state.output = input; return state; } state.output = utils$d.wrapOutput(output, state, options); return state; } /** * Tokenize input until we reach end-of-string */ while (!eos()) { value = advance(); if (value === '\u0000') { continue; } /** * Escaped characters */ if (value === '\\') { const next = peek(); if (next === '/' && opts.bash !== true) { continue; } if (next === '.' || next === ';') { continue; } if (!next) { value += '\\'; push({ type: 'text', value }); continue; } // collapse slashes to reduce potential for exploits const match = /^\\+/.exec(remaining()); let slashes = 0; if (match && match[0].length > 2) { slashes = match[0].length; state.index += slashes; if (slashes % 2 !== 0) { value += '\\'; } } if (opts.unescape === true) { value = advance(); } else { value += advance(); } if (state.brackets === 0) { push({ type: 'text', value }); continue; } } /** * If we're inside a regex character class, continue * until we reach the closing bracket. */ if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { if (opts.posix !== false && value === ':') { const inner = prev.value.slice(1); if (inner.includes('[')) { prev.posix = true; if (inner.includes(':')) { const idx = prev.value.lastIndexOf('['); const pre = prev.value.slice(0, idx); const rest = prev.value.slice(idx + 2); const posix = POSIX_REGEX_SOURCE[rest]; if (posix) { prev.value = pre + posix; state.backtrack = true; advance(); if (!bos.output && tokens.indexOf(prev) === 1) { bos.output = ONE_CHAR; } continue; } } } } if (value === '[' && peek() !== ':' || value === '-' && peek() === ']') { value = `\\${value}`; } if (value === ']' && (prev.value === '[' || prev.value === '[^')) { value = `\\${value}`; } if (opts.posix === true && value === '!' && prev.value === '[') { value = '^'; } prev.value += value; append({ value }); continue; } /** * If we're inside a quoted string, continue * until we reach the closing double quote. */ if (state.quotes === 1 && value !== '"') { value = utils$d.escapeRegex(value); prev.value += value; append({ value }); continue; } /** * Double quotes */ if (value === '"') { state.quotes = state.quotes === 1 ? 0 : 1; if (opts.keepQuotes === true) { push({ type: 'text', value }); } continue; } /** * Parentheses */ if (value === '(') { increment('parens'); push({ type: 'paren', value }); continue; } if (value === ')') { if (state.parens === 0 && opts.strictBrackets === true) { throw new SyntaxError(syntaxError('opening', '(')); } const extglob = extglobs[extglobs.length - 1]; if (extglob && state.parens === extglob.parens + 1) { extglobClose(extglobs.pop()); continue; } push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); decrement('parens'); continue; } /** * Square brackets */ if (value === '[') { if (opts.nobracket === true || !remaining().includes(']')) { if (opts.nobracket !== true && opts.strictBrackets === true) { throw new SyntaxError(syntaxError('closing', ']')); } value = `\\${value}`; } else { increment('brackets'); } push({ type: 'bracket', value }); continue; } if (value === ']') { if (opts.nobracket === true || prev && prev.type === 'bracket' && prev.value.length === 1) { push({ type: 'text', value, output: `\\${value}` }); continue; } if (state.brackets === 0) { if (opts.strictBrackets === true) { throw new SyntaxError(syntaxError('opening', '[')); } push({ type: 'text', value, output: `\\${value}` }); continue; } decrement('brackets'); const prevValue = prev.value.slice(1); if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { value = `/${value}`; } prev.value += value; append({ value }); // when literal brackets are explicitly disabled // assume we should match with a regex character class if (opts.literalBrackets === false || utils$d.hasRegexChars(prevValue)) { continue; } const escaped = utils$d.escapeRegex(prev.value); state.output = state.output.slice(0, -prev.value.length); // when literal brackets are explicitly enabled // assume we should escape the brackets to match literal characters if (opts.literalBrackets === true) { state.output += escaped; prev.value = escaped; continue; } // when the user specifies nothing, try to match both prev.value = `(${capture}${escaped}|${prev.value})`; state.output += prev.value; continue; } /** * Braces */ if (value === '{' && opts.nobrace !== true) { increment('braces'); const open = { type: 'brace', value, output: '(', outputIndex: state.output.length, tokensIndex: state.tokens.length }; braces.push(open); push(open); continue; } if (value === '}') { const brace = braces[braces.length - 1]; if (opts.nobrace === true || !brace) { push({ type: 'text', value, output: value }); continue; } let output = ')'; if (brace.dots === true) { const arr = tokens.slice(); const range = []; for (let i = arr.length - 1; i >= 0; i--) { tokens.pop(); if (arr[i].type === 'brace') { break; } if (arr[i].type !== 'dots') { range.unshift(arr[i].value); } } output = expandRange(range, opts); state.backtrack = true; } if (brace.comma !== true && brace.dots !== true) { const out = state.output.slice(0, brace.outputIndex); const toks = state.tokens.slice(brace.tokensIndex); brace.value = brace.output = '\\{'; value = output = '\\}'; state.output = out; for (const t of toks) { state.output += t.output || t.value; } } push({ type: 'brace', value, output }); decrement('braces'); braces.pop(); continue; } /** * Pipes */ if (value === '|') { if (extglobs.length > 0) { extglobs[extglobs.length - 1].conditions++; } push({ type: 'text', value }); continue; } /** * Commas */ if (value === ',') { let output = value; const brace = braces[braces.length - 1]; if (brace && stack[stack.length - 1] === 'braces') { brace.comma = true; output = '|'; } push({ type: 'comma', value, output }); continue; } /** * Slashes */ if (value === '/') { // if the beginning of the glob is "./", advance the start // to the current index, and don't add the "./" characters // to the state. This greatly simplifies lookbehinds when // checking for BOS characters like "!" and "." (not "./") if (prev.type === 'dot' && state.index === state.start + 1) { state.start = state.index + 1; state.consumed = ''; state.output = ''; tokens.pop(); prev = bos; // reset "prev" to the first token continue; } push({ type: 'slash', value, output: SLASH_LITERAL }); continue; } /** * Dots */ if (value === '.') { if (state.braces > 0 && prev.type === 'dot') { if (prev.value === '.') prev.output = DOT_LITERAL; const brace = braces[braces.length - 1]; prev.type = 'dots'; prev.output += value; prev.value += value; brace.dots = true; continue; } if (state.braces + state.parens === 0 && prev.type !== 'bos' && prev.type !== 'slash') { push({ type: 'text', value, output: DOT_LITERAL }); continue; } push({ type: 'dot', value, output: DOT_LITERAL }); continue; } /** * Question marks */ if (value === '?') { const isGroup = prev && prev.value === '('; if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { extglobOpen('qmark', value); continue; } if (prev && prev.type === 'paren') { const next = peek(); let output = value; if (next === '<' && !utils$d.supportsLookbehinds()) { throw new Error('Node.js v10 or higher is required for regex lookbehinds'); } if (prev.value === '(' && !/[!=<:]/.test(next) || next === '<' && !/<([!=]|\w+>)/.test(remaining())) { output = `\\${value}`; } push({ type: 'text', value, output }); continue; } if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { push({ type: 'qmark', value, output: QMARK_NO_DOT }); continue; } push({ type: 'qmark', value, output: QMARK }); continue; } /** * Exclamation */ if (value === '!') { if (opts.noextglob !== true && peek() === '(') { if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { extglobOpen('negate', value); continue; } } if (opts.nonegate !== true && state.index === 0) { negate(); continue; } } /** * Plus */ if (value === '+') { if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { extglobOpen('plus', value); continue; } if (prev && prev.value === '(' || opts.regex === false) { push({ type: 'plus', value, output: PLUS_LITERAL }); continue; } if (prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace') || state.parens > 0) { push({ type: 'plus', value }); continue; } push({ type: 'plus', value: PLUS_LITERAL }); continue; } /** * Plain text */ if (value === '@') { if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { push({ type: 'at', extglob: true, value, output: '' }); continue; } push({ type: 'text', value }); continue; } /** * Plain text */ if (value !== '*') { if (value === '$' || value === '^') { value = `\\${value}`; } const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); if (match) { value += match[0]; state.index += match[0].length; } push({ type: 'text', value }); continue; } /** * Stars */ if (prev && (prev.type === 'globstar' || prev.star === true)) { prev.type = 'star'; prev.star = true; prev.value += value; prev.output = star; state.backtrack = true; state.globstar = true; consume(value); continue; } let rest = remaining(); if (opts.noextglob !== true && /^\([^?]/.test(rest)) { extglobOpen('star', value); continue; } if (prev.type === 'star') { if (opts.noglobstar === true) { consume(value); continue; } const prior = prev.prev; const before = prior.prev; const isStart = prior.type === 'slash' || prior.type === 'bos'; const afterStar = before && (before.type === 'star' || before.type === 'globstar'); if (opts.bash === true && (!isStart || rest[0] && rest[0] !== '/')) { push({ type: 'star', value, output: '' }); continue; } const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { push({ type: 'star', value, output: '' }); continue; } // strip consecutive `/**/` while (rest.slice(0, 3) === '/**') { const after = input[state.index + 4]; if (after && after !== '/') { break; } rest = rest.slice(3); consume('/**', 3); } if (prior.type === 'bos' && eos()) { prev.type = 'globstar'; prev.value += value; prev.output = globstar(opts); state.output = prev.output; state.globstar = true; consume(value); continue; } if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { state.output = state.output.slice(0, -(prior.output + prev.output).length); prior.output = `(?:${prior.output}`; prev.type = 'globstar'; prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); prev.value += value; state.globstar = true; state.output += prior.output + prev.output; consume(value); continue; } if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { const end = rest[1] !== void 0 ? '|$' : ''; state.output = state.output.slice(0, -(prior.output + prev.output).length); prior.output = `(?:${prior.output}`; prev.type = 'globstar'; prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; prev.value += value; state.output += prior.output + prev.output; state.globstar = true; consume(value + advance()); push({ type: 'slash', value: '/', output: '' }); continue; } if (prior.type === 'bos' && rest[0] === '/') { prev.type = 'globstar'; prev.value += value; prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; state.output = prev.output; state.globstar = true; consume(value + advance()); push({ type: 'slash', value: '/', output: '' }); continue; } // remove single star from output state.output = state.output.slice(0, -prev.output.length); // reset previous token to globstar prev.type = 'globstar'; prev.output = globstar(opts); prev.value += value; // reset output with globstar state.output += prev.output; state.globstar = true; consume(value); continue; } const token = { type: 'star', value, output: star }; if (opts.bash === true) { token.output = '.*?'; if (prev.type === 'bos' || prev.type === 'slash') { token.output = nodot + token.output; } push(token); continue; } if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { token.output = value; push(token); continue; } if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { if (prev.type === 'dot') { state.output += NO_DOT_SLASH; prev.output += NO_DOT_SLASH; } else if (opts.dot === true) { state.output += NO_DOTS_SLASH; prev.output += NO_DOTS_SLASH; } else { state.output += nodot; prev.output += nodot; } if (peek() !== '*') { state.output += ONE_CHAR; prev.output += ONE_CHAR; } } push(token); } while (state.brackets > 0) { if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); state.output = utils$d.escapeLast(state.output, '['); decrement('brackets'); } while (state.parens > 0) { if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); state.output = utils$d.escapeLast(state.output, '('); decrement('parens'); } while (state.braces > 0) { if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); state.output = utils$d.escapeLast(state.output, '{'); decrement('braces'); } if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); } // rebuild the output if we had to backtrack at any point if (state.backtrack === true) { state.output = ''; for (const token of state.tokens) { state.output += token.output != null ? token.output : token.value; if (token.suffix) { state.output += token.suffix; } } } return state; }; /** * Fast paths for creating regular expressions for common glob patterns. * This can significantly speed up processing and has very little downside * impact when none of the fast paths match. */ parse$1.fastpaths = (input, options) => { const opts = { ...options }; const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; const len = input.length; if (len > max) { throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); } input = REPLACEMENTS[input] || input; const win32 = utils$d.isWindows(options); // create constants based on platform, for windows or posix const { DOT_LITERAL, SLASH_LITERAL, ONE_CHAR, DOTS_SLASH, NO_DOT, NO_DOTS, NO_DOTS_SLASH, STAR, START_ANCHOR } = constants$3.globChars(win32); const nodot = opts.dot ? NO_DOTS : NO_DOT; const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; const capture = opts.capture ? '' : '?:'; const state = { negated: false, prefix: '' }; let star = opts.bash === true ? '.*?' : STAR; if (opts.capture) { star = `(${star})`; } const globstar = opts => { if (opts.noglobstar === true) return star; return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; }; const create = str => { switch (str) { case '*': return `${nodot}${ONE_CHAR}${star}`; case '.*': return `${DOT_LITERAL}${ONE_CHAR}${star}`; case '*.*': return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; case '*/*': return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; case '**': return nodot + globstar(opts); case '**/*': return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; case '**/*.*': return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; case '**/.*': return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; default: { const match = /^(.*?)\.(\w+)$/.exec(str); if (!match) return; const source = create(match[1]); if (!source) return; return source + DOT_LITERAL + match[2]; } } }; const output = utils$d.removePrefix(input, state); let source = create(output); if (source && opts.strictSlashes !== true) { source += `${SLASH_LITERAL}?`; } return source; }; var parse_1 = parse$1; const path$8 = path$c; const scan = scan_1; const parse = parse_1; const utils$c = utils$f; const constants$2 = constants$4; const isObject = val => val && typeof val === 'object' && !Array.isArray(val); /** * Creates a matcher function from one or more glob patterns. The * returned function takes a string to match as its first argument, * and returns true if the string is a match. The returned matcher * function also takes a boolean as the second argument that, when true, * returns an object with additional information. * * ```js * const picomatch = require('picomatch'); * // picomatch(glob[, options]); * * const isMatch = picomatch('*.!(*a)'); * console.log(isMatch('a.a')); //=> false * console.log(isMatch('a.b')); //=> true * ``` * @name picomatch * @param {String|Array} `globs` One or more glob patterns. * @param {Object=} `options` * @return {Function=} Returns a matcher function. * @api public */ const picomatch$2 = (glob, options, returnState = false) => { if (Array.isArray(glob)) { const fns = glob.map(input => picomatch$2(input, options, returnState)); const arrayMatcher = str => { for (const isMatch of fns) { const state = isMatch(str); if (state) return state; } return false; }; return arrayMatcher; } const isState = isObject(glob) && glob.tokens && glob.input; if (glob === '' || typeof glob !== 'string' && !isState) { throw new TypeError('Expected pattern to be a non-empty string'); } const opts = options || {}; const posix = utils$c.isWindows(options); const regex = isState ? picomatch$2.compileRe(glob, options) : picomatch$2.makeRe(glob, options, false, true); const state = regex.state; delete regex.state; let isIgnored = () => false; if (opts.ignore) { const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; isIgnored = picomatch$2(opts.ignore, ignoreOpts, returnState); } const matcher = (input, returnObject = false) => { const { isMatch, match, output } = picomatch$2.test(input, regex, options, { glob, posix }); const result = { glob, state, regex, posix, input, output, match, isMatch }; if (typeof opts.onResult === 'function') { opts.onResult(result); } if (isMatch === false) { result.isMatch = false; return returnObject ? result : false; } if (isIgnored(input)) { if (typeof opts.onIgnore === 'function') { opts.onIgnore(result); } result.isMatch = false; return returnObject ? result : false; } if (typeof opts.onMatch === 'function') { opts.onMatch(result); } return returnObject ? result : true; }; if (returnState) { matcher.state = state; } return matcher; }; /** * Test `input` with the given `regex`. This is used by the main * `picomatch()` function to test the input string. * * ```js * const picomatch = require('picomatch'); * // picomatch.test(input, regex[, options]); * * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } * ``` * @param {String} `input` String to test. * @param {RegExp} `regex` * @return {Object} Returns an object with matching info. * @api public */ picomatch$2.test = (input, regex, options, { glob, posix } = {}) => { if (typeof input !== 'string') { throw new TypeError('Expected input to be a string'); } if (input === '') { return { isMatch: false, output: '' }; } const opts = options || {}; const format = opts.format || (posix ? utils$c.toPosixSlashes : null); let match = input === glob; let output = match && format ? format(input) : input; if (match === false) { output = format ? format(input) : input; match = output === glob; } if (match === false || opts.capture === true) { if (opts.matchBase === true || opts.basename === true) { match = picomatch$2.matchBase(input, regex, options, posix); } else { match = regex.exec(output); } } return { isMatch: Boolean(match), match, output }; }; /** * Match the basename of a filepath. * * ```js * const picomatch = require('picomatch'); * // picomatch.matchBase(input, glob[, options]); * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true * ``` * @param {String} `input` String to test. * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). * @return {Boolean} * @api public */ picomatch$2.matchBase = (input, glob, options, posix = utils$c.isWindows(options)) => { const regex = glob instanceof RegExp ? glob : picomatch$2.makeRe(glob, options); return regex.test(path$8.basename(input)); }; /** * Returns true if **any** of the given glob `patterns` match the specified `string`. * * ```js * const picomatch = require('picomatch'); * // picomatch.isMatch(string, patterns[, options]); * * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false * ``` * @param {String|Array} str The string to test. * @param {String|Array} patterns One or more glob patterns to use for matching. * @param {Object} [options] See available [options](#options). * @return {Boolean} Returns true if any patterns match `str` * @api public */ picomatch$2.isMatch = (str, patterns, options) => picomatch$2(patterns, options)(str); /** * Parse a glob pattern to create the source string for a regular * expression. * * ```js * const picomatch = require('picomatch'); * const result = picomatch.parse(pattern[, options]); * ``` * @param {String} `pattern` * @param {Object} `options` * @return {Object} Returns an object with useful properties and output to be used as a regex source string. * @api public */ picomatch$2.parse = (pattern, options) => { if (Array.isArray(pattern)) return pattern.map(p => picomatch$2.parse(p, options)); return parse(pattern, { ...options, fastpaths: false }); }; /** * Scan a glob pattern to separate the pattern into segments. * * ```js * const picomatch = require('picomatch'); * // picomatch.scan(input[, options]); * * const result = picomatch.scan('!./foo/*.js'); * console.log(result); * { prefix: '!./', * input: '!./foo/*.js', * start: 3, * base: 'foo', * glob: '*.js', * isBrace: false, * isBracket: false, * isGlob: true, * isExtglob: false, * isGlobstar: false, * negated: true } * ``` * @param {String} `input` Glob pattern to scan. * @param {Object} `options` * @return {Object} Returns an object with * @api public */ picomatch$2.scan = (input, options) => scan(input, options); /** * Compile a regular expression from the `state` object returned by the * [parse()](#parse) method. * * @param {Object} `state` * @param {Object} `options` * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. * @return {RegExp} * @api public */ picomatch$2.compileRe = (state, options, returnOutput = false, returnState = false) => { if (returnOutput === true) { return state.output; } const opts = options || {}; const prepend = opts.contains ? '' : '^'; const append = opts.contains ? '' : '$'; let source = `${prepend}(?:${state.output})${append}`; if (state && state.negated === true) { source = `^(?!${source}).*$`; } const regex = picomatch$2.toRegex(source, options); if (returnState === true) { regex.state = state; } return regex; }; /** * Create a regular expression from a parsed glob pattern. * * ```js * const picomatch = require('picomatch'); * const state = picomatch.parse('*.js'); * // picomatch.compileRe(state[, options]); * * console.log(picomatch.compileRe(state)); * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ * ``` * @param {String} `state` The object returned from the `.parse` method. * @param {Object} `options` * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. * @return {RegExp} Returns a regex created from the given pattern. * @api public */ picomatch$2.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { if (!input || typeof input !== 'string') { throw new TypeError('Expected a non-empty string'); } let parsed = { negated: false, fastpaths: true }; if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { parsed.output = parse.fastpaths(input, options); } if (!parsed.output) { parsed = parse(input, options); } return picomatch$2.compileRe(parsed, options, returnOutput, returnState); }; /** * Create a regular expression from the given regex source string. * * ```js * const picomatch = require('picomatch'); * // picomatch.toRegex(source[, options]); * * const { output } = picomatch.parse('*.js'); * console.log(picomatch.toRegex(output)); * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ * ``` * @param {String} `source` Regular expression source string. * @param {Object} `options` * @return {RegExp} * @api public */ picomatch$2.toRegex = (source, options) => { try { const opts = options || {}; return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); } catch (err) { if (options && options.debug === true) throw err; return /$^/; } }; /** * Picomatch constants. * @return {Object} */ picomatch$2.constants = constants$2; /** * Expose "picomatch" */ var picomatch_1 = picomatch$2; var picomatch$1 = picomatch_1; const util$1 = require$$0$1; const braces = braces_1; const picomatch = picomatch$1; const utils$b = utils$f; const isEmptyString = val => val === '' || val === './'; /** * Returns an array of strings that match one or more glob patterns. * * ```js * const mm = require('micromatch'); * // mm(list, patterns[, options]); * * console.log(mm(['a.js', 'a.txt'], ['*.js'])); * //=> [ 'a.js' ] * ``` * @param {String|Array} `list` List of strings to match. * @param {String|Array} `patterns` One or more glob patterns to use for matching. * @param {Object} `options` See available [options](#options) * @return {Array} Returns an array of matches * @summary false * @api public */ const micromatch$1 = (list, patterns, options) => { patterns = [].concat(patterns); list = [].concat(list); let omit = new Set(); let keep = new Set(); let items = new Set(); let negatives = 0; let onResult = state => { items.add(state.output); if (options && options.onResult) { options.onResult(state); } }; for (let i = 0; i < patterns.length; i++) { let isMatch = picomatch(String(patterns[i]), { ...options, onResult }, true); let negated = isMatch.state.negated || isMatch.state.negatedExtglob; if (negated) negatives++; for (let item of list) { let matched = isMatch(item, true); let match = negated ? !matched.isMatch : matched.isMatch; if (!match) continue; if (negated) { omit.add(matched.output); } else { omit.delete(matched.output); keep.add(matched.output); } } } let result = negatives === patterns.length ? [...items] : [...keep]; let matches = result.filter(item => !omit.has(item)); if (options && matches.length === 0) { if (options.failglob === true) { throw new Error(`No matches found for "${patterns.join(', ')}"`); } if (options.nonull === true || options.nullglob === true) { return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns; } } return matches; }; /** * Backwards compatibility */ micromatch$1.match = micromatch$1; /** * Returns a matcher function from the given glob `pattern` and `options`. * The returned function takes a string to match as its only argument and returns * true if the string is a match. * * ```js * const mm = require('micromatch'); * // mm.matcher(pattern[, options]); * * const isMatch = mm.matcher('*.!(*a)'); * console.log(isMatch('a.a')); //=> false * console.log(isMatch('a.b')); //=> true * ``` * @param {String} `pattern` Glob pattern * @param {Object} `options` * @return {Function} Returns a matcher function. * @api public */ micromatch$1.matcher = (pattern, options) => picomatch(pattern, options); /** * Returns true if **any** of the given glob `patterns` match the specified `string`. * * ```js * const mm = require('micromatch'); * // mm.isMatch(string, patterns[, options]); * * console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true * console.log(mm.isMatch('a.a', 'b.*')); //=> false * ``` * @param {String} `str` The string to test. * @param {String|Array} `patterns` One or more glob patterns to use for matching. * @param {Object} `[options]` See available [options](#options). * @return {Boolean} Returns true if any patterns match `str` * @api public */ micromatch$1.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); /** * Backwards compatibility */ micromatch$1.any = micromatch$1.isMatch; /** * Returns a list of strings that _**do not match any**_ of the given `patterns`. * * ```js * const mm = require('micromatch'); * // mm.not(list, patterns[, options]); * * console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a')); * //=> ['b.b', 'c.c'] * ``` * @param {Array} `list` Array of strings to match. * @param {String|Array} `patterns` One or more glob pattern to use for matching. * @param {Object} `options` See available [options](#options) for changing how matches are performed * @return {Array} Returns an array of strings that **do not match** the given patterns. * @api public */ micromatch$1.not = (list, patterns, options = {}) => { patterns = [].concat(patterns).map(String); let result = new Set(); let items = []; let onResult = state => { if (options.onResult) options.onResult(state); items.push(state.output); }; let matches = new Set(micromatch$1(list, patterns, { ...options, onResult })); for (let item of items) { if (!matches.has(item)) { result.add(item); } } return [...result]; }; /** * Returns true if the given `string` contains the given pattern. Similar * to [.isMatch](#isMatch) but the pattern can match any part of the string. * * ```js * var mm = require('micromatch'); * // mm.contains(string, pattern[, options]); * * console.log(mm.contains('aa/bb/cc', '*b')); * //=> true * console.log(mm.contains('aa/bb/cc', '*d')); * //=> false * ``` * @param {String} `str` The string to match. * @param {String|Array} `patterns` Glob pattern to use for matching. * @param {Object} `options` See available [options](#options) for changing how matches are performed * @return {Boolean} Returns true if any of the patterns matches any part of `str`. * @api public */ micromatch$1.contains = (str, pattern, options) => { if (typeof str !== 'string') { throw new TypeError(`Expected a string: "${util$1.inspect(str)}"`); } if (Array.isArray(pattern)) { return pattern.some(p => micromatch$1.contains(str, p, options)); } if (typeof pattern === 'string') { if (isEmptyString(str) || isEmptyString(pattern)) { return false; } if (str.includes(pattern) || str.startsWith('./') && str.slice(2).includes(pattern)) { return true; } } return micromatch$1.isMatch(str, pattern, { ...options, contains: true }); }; /** * Filter the keys of the given object with the given `glob` pattern * and `options`. Does not attempt to match nested keys. If you need this feature, * use [glob-object][] instead. * * ```js * const mm = require('micromatch'); * // mm.matchKeys(object, patterns[, options]); * * const obj = { aa: 'a', ab: 'b', ac: 'c' }; * console.log(mm.matchKeys(obj, '*b')); * //=> { ab: 'b' } * ``` * @param {Object} `object` The object with keys to filter. * @param {String|Array} `patterns` One or more glob patterns to use for matching. * @param {Object} `options` See available [options](#options) for changing how matches are performed * @return {Object} Returns an object with only keys that match the given patterns. * @api public */ micromatch$1.matchKeys = (obj, patterns, options) => { if (!utils$b.isObject(obj)) { throw new TypeError('Expected the first argument to be an object'); } let keys = micromatch$1(Object.keys(obj), patterns, options); let res = {}; for (let key of keys) res[key] = obj[key]; return res; }; /** * Returns true if some of the strings in the given `list` match any of the given glob `patterns`. * * ```js * const mm = require('micromatch'); * // mm.some(list, patterns[, options]); * * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); * // true * console.log(mm.some(['foo.js'], ['*.js', '!foo.js'])); * // false * ``` * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found. * @param {String|Array} `patterns` One or more glob patterns to use for matching. * @param {Object} `options` See available [options](#options) for changing how matches are performed * @return {Boolean} Returns true if any `patterns` matches any of the strings in `list` * @api public */ micromatch$1.some = (list, patterns, options) => { let items = [].concat(list); for (let pattern of [].concat(patterns)) { let isMatch = picomatch(String(pattern), options); if (items.some(item => isMatch(item))) { return true; } } return false; }; /** * Returns true if every string in the given `list` matches * any of the given glob `patterns`. * * ```js * const mm = require('micromatch'); * // mm.every(list, patterns[, options]); * * console.log(mm.every('foo.js', ['foo.js'])); * // true * console.log(mm.every(['foo.js', 'bar.js'], ['*.js'])); * // true * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); * // false * console.log(mm.every(['foo.js'], ['*.js', '!foo.js'])); * // false * ``` * @param {String|Array} `list` The string or array of strings to test. * @param {String|Array} `patterns` One or more glob patterns to use for matching. * @param {Object} `options` See available [options](#options) for changing how matches are performed * @return {Boolean} Returns true if all `patterns` matches all of the strings in `list` * @api public */ micromatch$1.every = (list, patterns, options) => { let items = [].concat(list); for (let pattern of [].concat(patterns)) { let isMatch = picomatch(String(pattern), options); if (!items.every(item => isMatch(item))) { return false; } } return true; }; /** * Returns true if **all** of the given `patterns` match * the specified string. * * ```js * const mm = require('micromatch'); * // mm.all(string, patterns[, options]); * * console.log(mm.all('foo.js', ['foo.js'])); * // true * * console.log(mm.all('foo.js', ['*.js', '!foo.js'])); * // false * * console.log(mm.all('foo.js', ['*.js', 'foo.js'])); * // true * * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js'])); * // true * ``` * @param {String|Array} `str` The string to test. * @param {String|Array} `patterns` One or more glob patterns to use for matching. * @param {Object} `options` See available [options](#options) for changing how matches are performed * @return {Boolean} Returns true if any patterns match `str` * @api public */ micromatch$1.all = (str, patterns, options) => { if (typeof str !== 'string') { throw new TypeError(`Expected a string: "${util$1.inspect(str)}"`); } return [].concat(patterns).every(p => picomatch(p, options)(str)); }; /** * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match. * * ```js * const mm = require('micromatch'); * // mm.capture(pattern, string[, options]); * * console.log(mm.capture('test/*.js', 'test/foo.js')); * //=> ['foo'] * console.log(mm.capture('test/*.js', 'foo/bar.css')); * //=> null * ``` * @param {String} `glob` Glob pattern to use for matching. * @param {String} `input` String to match * @param {Object} `options` See available [options](#options) for changing how matches are performed * @return {Array|null} Returns an array of captures if the input matches the glob pattern, otherwise `null`. * @api public */ micromatch$1.capture = (glob, input, options) => { let posix = utils$b.isWindows(options); let regex = picomatch.makeRe(String(glob), { ...options, capture: true }); let match = regex.exec(posix ? utils$b.toPosixSlashes(input) : input); if (match) { return match.slice(1).map(v => v === void 0 ? '' : v); } }; /** * Create a regular expression from the given glob `pattern`. * * ```js * const mm = require('micromatch'); * // mm.makeRe(pattern[, options]); * * console.log(mm.makeRe('*.js')); * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/ * ``` * @param {String} `pattern` A glob pattern to convert to regex. * @param {Object} `options` * @return {RegExp} Returns a regex created from the given pattern. * @api public */ micromatch$1.makeRe = (...args) => picomatch.makeRe(...args); /** * Scan a glob pattern to separate the pattern into segments. Used * by the [split](#split) method. * * ```js * const mm = require('micromatch'); * const state = mm.scan(pattern[, options]); * ``` * @param {String} `pattern` * @param {Object} `options` * @return {Object} Returns an object with * @api public */ micromatch$1.scan = (...args) => picomatch.scan(...args); /** * Parse a glob pattern to create the source string for a regular * expression. * * ```js * const mm = require('micromatch'); * const state = mm.parse(pattern[, options]); * ``` * @param {String} `glob` * @param {Object} `options` * @return {Object} Returns an object with useful properties and output to be used as regex source string. * @api public */ micromatch$1.parse = (patterns, options) => { let res = []; for (let pattern of [].concat(patterns || [])) { for (let str of braces(String(pattern), options)) { res.push(picomatch.parse(str, options)); } } return res; }; /** * Process the given brace `pattern`. * * ```js * const { braces } = require('micromatch'); * console.log(braces('foo/{a,b,c}/bar')); * //=> [ 'foo/(a|b|c)/bar' ] * * console.log(braces('foo/{a,b,c}/bar', { expand: true })); * //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ] * ``` * @param {String} `pattern` String with brace pattern to process. * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options. * @return {Array} * @api public */ micromatch$1.braces = (pattern, options) => { if (typeof pattern !== 'string') throw new TypeError('Expected a string'); if (options && options.nobrace === true || !/\{.*\}/.test(pattern)) { return [pattern]; } return braces(pattern, options); }; /** * Expand braces */ micromatch$1.braceExpand = (pattern, options) => { if (typeof pattern !== 'string') throw new TypeError('Expected a string'); return micromatch$1.braces(pattern, { ...options, expand: true }); }; /** * Expose micromatch */ var micromatch_1 = micromatch$1; Object.defineProperty(pattern$1, "__esModule", { value: true }); pattern$1.removeDuplicateSlashes = pattern$1.matchAny = pattern$1.convertPatternsToRe = pattern$1.makeRe = pattern$1.getPatternParts = pattern$1.expandBraceExpansion = pattern$1.expandPatternsWithBraceExpansion = pattern$1.isAffectDepthOfReadingPattern = pattern$1.endsWithSlashGlobStar = pattern$1.hasGlobStar = pattern$1.getBaseDirectory = pattern$1.isPatternRelatedToParentDirectory = pattern$1.getPatternsOutsideCurrentDirectory = pattern$1.getPatternsInsideCurrentDirectory = pattern$1.getPositivePatterns = pattern$1.getNegativePatterns = pattern$1.isPositivePattern = pattern$1.isNegativePattern = pattern$1.convertToNegativePattern = pattern$1.convertToPositivePattern = pattern$1.isDynamicPattern = pattern$1.isStaticPattern = void 0; const path$7 = path$c; const globParent = globParent$1; const micromatch = micromatch_1; const GLOBSTAR = '**'; const ESCAPE_SYMBOL = '\\'; const COMMON_GLOB_SYMBOLS_RE = /[*?]|^!/; const REGEX_CHARACTER_CLASS_SYMBOLS_RE = /\[[^[]*]/; const REGEX_GROUP_SYMBOLS_RE = /(?:^|[^!*+?@])\([^(]*\|[^|]*\)/; const GLOB_EXTENSION_SYMBOLS_RE = /[!*+?@]\([^(]*\)/; const BRACE_EXPANSION_SEPARATORS_RE = /,|\.\./; /** * Matches a sequence of two or more consecutive slashes, excluding the first two slashes at the beginning of the string. * The latter is due to the presence of the device path at the beginning of the UNC path. */ const DOUBLE_SLASH_RE = /(?!^)\/{2,}/g; function isStaticPattern(pattern, options = {}) { return !isDynamicPattern(pattern, options); } pattern$1.isStaticPattern = isStaticPattern; function isDynamicPattern(pattern, options = {}) { /** * A special case with an empty string is necessary for matching patterns that start with a forward slash. * An empty string cannot be a dynamic pattern. * For example, the pattern `/lib/*` will be spread into parts: '', 'lib', '*'. */ if (pattern === '') { return false; } /** * When the `caseSensitiveMatch` option is disabled, all patterns must be marked as dynamic, because we cannot check * filepath directly (without read directory). */ if (options.caseSensitiveMatch === false || pattern.includes(ESCAPE_SYMBOL)) { return true; } if (COMMON_GLOB_SYMBOLS_RE.test(pattern) || REGEX_CHARACTER_CLASS_SYMBOLS_RE.test(pattern) || REGEX_GROUP_SYMBOLS_RE.test(pattern)) { return true; } if (options.extglob !== false && GLOB_EXTENSION_SYMBOLS_RE.test(pattern)) { return true; } if (options.braceExpansion !== false && hasBraceExpansion(pattern)) { return true; } return false; } pattern$1.isDynamicPattern = isDynamicPattern; function hasBraceExpansion(pattern) { const openingBraceIndex = pattern.indexOf('{'); if (openingBraceIndex === -1) { return false; } const closingBraceIndex = pattern.indexOf('}', openingBraceIndex + 1); if (closingBraceIndex === -1) { return false; } const braceContent = pattern.slice(openingBraceIndex, closingBraceIndex); return BRACE_EXPANSION_SEPARATORS_RE.test(braceContent); } function convertToPositivePattern(pattern) { return isNegativePattern$1(pattern) ? pattern.slice(1) : pattern; } pattern$1.convertToPositivePattern = convertToPositivePattern; function convertToNegativePattern(pattern) { return '!' + pattern; } pattern$1.convertToNegativePattern = convertToNegativePattern; function isNegativePattern$1(pattern) { return pattern.startsWith('!') && pattern[1] !== '('; } pattern$1.isNegativePattern = isNegativePattern$1; function isPositivePattern(pattern) { return !isNegativePattern$1(pattern); } pattern$1.isPositivePattern = isPositivePattern; function getNegativePatterns(patterns) { return patterns.filter(isNegativePattern$1); } pattern$1.getNegativePatterns = getNegativePatterns; function getPositivePatterns$1(patterns) { return patterns.filter(isPositivePattern); } pattern$1.getPositivePatterns = getPositivePatterns$1; /** * Returns patterns that can be applied inside the current directory. * * @example * // ['./*', '*', 'a/*'] * getPatternsInsideCurrentDirectory(['./*', '*', 'a/*', '../*', './../*']) */ function getPatternsInsideCurrentDirectory(patterns) { return patterns.filter(pattern => !isPatternRelatedToParentDirectory(pattern)); } pattern$1.getPatternsInsideCurrentDirectory = getPatternsInsideCurrentDirectory; /** * Returns patterns to be expanded relative to (outside) the current directory. * * @example * // ['../*', './../*'] * getPatternsInsideCurrentDirectory(['./*', '*', 'a/*', '../*', './../*']) */ function getPatternsOutsideCurrentDirectory(patterns) { return patterns.filter(isPatternRelatedToParentDirectory); } pattern$1.getPatternsOutsideCurrentDirectory = getPatternsOutsideCurrentDirectory; function isPatternRelatedToParentDirectory(pattern) { return pattern.startsWith('..') || pattern.startsWith('./..'); } pattern$1.isPatternRelatedToParentDirectory = isPatternRelatedToParentDirectory; function getBaseDirectory(pattern) { return globParent(pattern, { flipBackslashes: false }); } pattern$1.getBaseDirectory = getBaseDirectory; function hasGlobStar(pattern) { return pattern.includes(GLOBSTAR); } pattern$1.hasGlobStar = hasGlobStar; function endsWithSlashGlobStar(pattern) { return pattern.endsWith('/' + GLOBSTAR); } pattern$1.endsWithSlashGlobStar = endsWithSlashGlobStar; function isAffectDepthOfReadingPattern(pattern) { const basename = path$7.basename(pattern); return endsWithSlashGlobStar(pattern) || isStaticPattern(basename); } pattern$1.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern; function expandPatternsWithBraceExpansion(patterns) { return patterns.reduce((collection, pattern) => { return collection.concat(expandBraceExpansion(pattern)); }, []); } pattern$1.expandPatternsWithBraceExpansion = expandPatternsWithBraceExpansion; function expandBraceExpansion(pattern) { const patterns = micromatch.braces(pattern, { expand: true, nodupes: true, keepEscaping: true }); /** * Sort the patterns by length so that the same depth patterns are processed side by side. * `a/{b,}/{c,}/*` – `['a///*', 'a/b//*', 'a//c/*', 'a/b/c/*']` */ patterns.sort((a, b) => a.length - b.length); /** * Micromatch can return an empty string in the case of patterns like `{a,}`. */ return patterns.filter(pattern => pattern !== ''); } pattern$1.expandBraceExpansion = expandBraceExpansion; function getPatternParts(pattern, options) { let { parts } = micromatch.scan(pattern, Object.assign(Object.assign({}, options), { parts: true })); /** * The scan method returns an empty array in some cases. * See micromatch/picomatch#58 for more details. */ if (parts.length === 0) { parts = [pattern]; } /** * The scan method does not return an empty part for the pattern with a forward slash. * This is another part of micromatch/picomatch#58. */ if (parts[0].startsWith('/')) { parts[0] = parts[0].slice(1); parts.unshift(''); } return parts; } pattern$1.getPatternParts = getPatternParts; function makeRe(pattern, options) { return micromatch.makeRe(pattern, options); } pattern$1.makeRe = makeRe; function convertPatternsToRe(patterns, options) { return patterns.map(pattern => makeRe(pattern, options)); } pattern$1.convertPatternsToRe = convertPatternsToRe; function matchAny(entry, patternsRe) { return patternsRe.some(patternRe => patternRe.test(entry)); } pattern$1.matchAny = matchAny; /** * This package only works with forward slashes as a path separator. * Because of this, we cannot use the standard `path.normalize` method, because on Windows platform it will use of backslashes. */ function removeDuplicateSlashes(pattern) { return pattern.replace(DOUBLE_SLASH_RE, '/'); } pattern$1.removeDuplicateSlashes = removeDuplicateSlashes; var stream$4 = {}; Object.defineProperty(stream$4, "__esModule", { value: true }); stream$4.merge = void 0; const merge2 = merge2_1; function merge(streams) { const mergedStream = merge2(streams); streams.forEach(stream => { stream.once('error', error => mergedStream.emit('error', error)); }); mergedStream.once('close', () => propagateCloseEventToSources(streams)); mergedStream.once('end', () => propagateCloseEventToSources(streams)); return mergedStream; } stream$4.merge = merge; function propagateCloseEventToSources(streams) { streams.forEach(stream => stream.emit('close')); } var string$1 = {}; Object.defineProperty(string$1, "__esModule", { value: true }); string$1.isEmpty = string$1.isString = void 0; function isString$1(input) { return typeof input === 'string'; } string$1.isString = isString$1; function isEmpty(input) { return input === ''; } string$1.isEmpty = isEmpty; Object.defineProperty(utils$k, "__esModule", { value: true }); utils$k.string = utils$k.stream = utils$k.pattern = utils$k.path = utils$k.fs = utils$k.errno = utils$k.array = void 0; const array = array$1; utils$k.array = array; const errno = errno$1; utils$k.errno = errno; const fs$9 = fs$a; utils$k.fs = fs$9; const path$6 = path$b; utils$k.path = path$6; const pattern = pattern$1; utils$k.pattern = pattern; const stream$3 = stream$4; utils$k.stream = stream$3; const string = string$1; utils$k.string = string; Object.defineProperty(tasks$1, "__esModule", { value: true }); tasks$1.convertPatternGroupToTask = tasks$1.convertPatternGroupsToTasks = tasks$1.groupPatternsByBaseDirectory = tasks$1.getNegativePatternsAsPositive = tasks$1.getPositivePatterns = tasks$1.convertPatternsToTasks = tasks$1.generate = void 0; const utils$a = utils$k; function generate(input, settings) { const patterns = processPatterns(input, settings); const ignore = processPatterns(settings.ignore, settings); const positivePatterns = getPositivePatterns(patterns); const negativePatterns = getNegativePatternsAsPositive(patterns, ignore); const staticPatterns = positivePatterns.filter(pattern => utils$a.pattern.isStaticPattern(pattern, settings)); const dynamicPatterns = positivePatterns.filter(pattern => utils$a.pattern.isDynamicPattern(pattern, settings)); const staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */false); const dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */true); return staticTasks.concat(dynamicTasks); } tasks$1.generate = generate; function processPatterns(input, settings) { let patterns = input; /** * The original pattern like `{,*,**,a/*}` can lead to problems checking the depth when matching entry * and some problems with the micromatch package (see fast-glob issues: #365, #394). * * To solve this problem, we expand all patterns containing brace expansion. This can lead to a slight slowdown * in matching in the case of a large set of patterns after expansion. */ if (settings.braceExpansion) { patterns = utils$a.pattern.expandPatternsWithBraceExpansion(patterns); } /** * If the `baseNameMatch` option is enabled, we must add globstar to patterns, so that they can be used * at any nesting level. * * We do this here, because otherwise we have to complicate the filtering logic. For example, we need to change * the pattern in the filter before creating a regular expression. There is no need to change the patterns * in the application. Only on the input. */ if (settings.baseNameMatch) { patterns = patterns.map(pattern => pattern.includes('/') ? pattern : `**/${pattern}`); } /** * This method also removes duplicate slashes that may have been in the pattern or formed as a result of expansion. */ return patterns.map(pattern => utils$a.pattern.removeDuplicateSlashes(pattern)); } /** * Returns tasks grouped by basic pattern directories. * * Patterns that can be found inside (`./`) and outside (`../`) the current directory are handled separately. * This is necessary because directory traversal starts at the base directory and goes deeper. */ function convertPatternsToTasks(positive, negative, dynamic) { const tasks = []; const patternsOutsideCurrentDirectory = utils$a.pattern.getPatternsOutsideCurrentDirectory(positive); const patternsInsideCurrentDirectory = utils$a.pattern.getPatternsInsideCurrentDirectory(positive); const outsideCurrentDirectoryGroup = groupPatternsByBaseDirectory(patternsOutsideCurrentDirectory); const insideCurrentDirectoryGroup = groupPatternsByBaseDirectory(patternsInsideCurrentDirectory); tasks.push(...convertPatternGroupsToTasks(outsideCurrentDirectoryGroup, negative, dynamic)); /* * For the sake of reducing future accesses to the file system, we merge all tasks within the current directory * into a global task, if at least one pattern refers to the root (`.`). In this case, the global task covers the rest. */ if ('.' in insideCurrentDirectoryGroup) { tasks.push(convertPatternGroupToTask('.', patternsInsideCurrentDirectory, negative, dynamic)); } else { tasks.push(...convertPatternGroupsToTasks(insideCurrentDirectoryGroup, negative, dynamic)); } return tasks; } tasks$1.convertPatternsToTasks = convertPatternsToTasks; function getPositivePatterns(patterns) { return utils$a.pattern.getPositivePatterns(patterns); } tasks$1.getPositivePatterns = getPositivePatterns; function getNegativePatternsAsPositive(patterns, ignore) { const negative = utils$a.pattern.getNegativePatterns(patterns).concat(ignore); const positive = negative.map(utils$a.pattern.convertToPositivePattern); return positive; } tasks$1.getNegativePatternsAsPositive = getNegativePatternsAsPositive; function groupPatternsByBaseDirectory(patterns) { const group = {}; return patterns.reduce((collection, pattern) => { const base = utils$a.pattern.getBaseDirectory(pattern); if (base in collection) { collection[base].push(pattern); } else { collection[base] = [pattern]; } return collection; }, group); } tasks$1.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory; function convertPatternGroupsToTasks(positive, negative, dynamic) { return Object.keys(positive).map(base => { return convertPatternGroupToTask(base, positive[base], negative, dynamic); }); } tasks$1.convertPatternGroupsToTasks = convertPatternGroupsToTasks; function convertPatternGroupToTask(base, positive, negative, dynamic) { return { dynamic, positive, negative, base, patterns: [].concat(positive, negative.map(utils$a.pattern.convertToNegativePattern)) }; } tasks$1.convertPatternGroupToTask = convertPatternGroupToTask; var async$7 = {}; var async$6 = {}; var out$3 = {}; var async$5 = {}; var async$4 = {}; var out$2 = {}; var async$3 = {}; var out$1 = {}; var async$2 = {}; Object.defineProperty(async$2, "__esModule", { value: true }); async$2.read = void 0; function read$3(path, settings, callback) { settings.fs.lstat(path, (lstatError, lstat) => { if (lstatError !== null) { callFailureCallback$2(callback, lstatError); return; } if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { callSuccessCallback$2(callback, lstat); return; } settings.fs.stat(path, (statError, stat) => { if (statError !== null) { if (settings.throwErrorOnBrokenSymbolicLink) { callFailureCallback$2(callback, statError); return; } callSuccessCallback$2(callback, lstat); return; } if (settings.markSymbolicLink) { stat.isSymbolicLink = () => true; } callSuccessCallback$2(callback, stat); }); }); } async$2.read = read$3; function callFailureCallback$2(callback, error) { callback(error); } function callSuccessCallback$2(callback, result) { callback(null, result); } var sync$7 = {}; Object.defineProperty(sync$7, "__esModule", { value: true }); sync$7.read = void 0; function read$2(path, settings) { const lstat = settings.fs.lstatSync(path); if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { return lstat; } try { const stat = settings.fs.statSync(path); if (settings.markSymbolicLink) { stat.isSymbolicLink = () => true; } return stat; } catch (error) { if (!settings.throwErrorOnBrokenSymbolicLink) { return lstat; } throw error; } } sync$7.read = read$2; var settings$3 = {}; var fs$8 = {}; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0; const fs = fs$b; exports.FILE_SYSTEM_ADAPTER = { lstat: fs.lstat, stat: fs.stat, lstatSync: fs.lstatSync, statSync: fs.statSync }; function createFileSystemAdapter(fsMethods) { if (fsMethods === undefined) { return exports.FILE_SYSTEM_ADAPTER; } return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); } exports.createFileSystemAdapter = createFileSystemAdapter; })(fs$8); Object.defineProperty(settings$3, "__esModule", { value: true }); const fs$7 = fs$8; let Settings$2 = class Settings { constructor(_options = {}) { this._options = _options; this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true); this.fs = fs$7.createFileSystemAdapter(this._options.fs); this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false); this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); } _getValue(option, value) { return option !== null && option !== void 0 ? option : value; } }; settings$3.default = Settings$2; Object.defineProperty(out$1, "__esModule", { value: true }); out$1.statSync = out$1.stat = out$1.Settings = void 0; const async$1 = async$2; const sync$6 = sync$7; const settings_1$3 = settings$3; out$1.Settings = settings_1$3.default; function stat(path, optionsOrSettingsOrCallback, callback) { if (typeof optionsOrSettingsOrCallback === 'function') { async$1.read(path, getSettings$2(), optionsOrSettingsOrCallback); return; } async$1.read(path, getSettings$2(optionsOrSettingsOrCallback), callback); } out$1.stat = stat; function statSync(path, optionsOrSettings) { const settings = getSettings$2(optionsOrSettings); return sync$6.read(path, settings); } out$1.statSync = statSync; function getSettings$2(settingsOrOptions = {}) { if (settingsOrOptions instanceof settings_1$3.default) { return settingsOrOptions; } return new settings_1$3.default(settingsOrOptions); } /*! queue-microtask. MIT License. Feross Aboukhadijeh */ let promise; var queueMicrotask_1 = typeof queueMicrotask === 'function' ? queueMicrotask.bind(typeof window !== 'undefined' ? window : commonjsGlobal) // reuse resolved promise, and allocate it lazily : cb => (promise || (promise = Promise.resolve())).then(cb).catch(err => setTimeout(() => { throw err; }, 0)); /*! run-parallel. MIT License. Feross Aboukhadijeh */ var runParallel_1 = runParallel; const queueMicrotask$1 = queueMicrotask_1; function runParallel(tasks, cb) { let results, pending, keys; let isSync = true; if (Array.isArray(tasks)) { results = []; pending = tasks.length; } else { keys = Object.keys(tasks); results = {}; pending = keys.length; } function done(err) { function end() { if (cb) cb(err, results); cb = null; } if (isSync) queueMicrotask$1(end);else end(); } function each(i, err, result) { results[i] = result; if (--pending === 0 || err) { done(err); } } if (!pending) { // empty done(null); } else if (keys) { // object keys.forEach(function (key) { tasks[key](function (err, result) { each(key, err, result); }); }); } else { // array tasks.forEach(function (task, i) { task(function (err, result) { each(i, err, result); }); }); } isSync = false; } var constants$1 = {}; Object.defineProperty(constants$1, "__esModule", { value: true }); constants$1.IS_SUPPORT_READDIR_WITH_FILE_TYPES = void 0; const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.'); if (NODE_PROCESS_VERSION_PARTS[0] === undefined || NODE_PROCESS_VERSION_PARTS[1] === undefined) { throw new Error(`Unexpected behavior. The 'process.versions.node' variable has invalid value: ${process.versions.node}`); } const MAJOR_VERSION = Number.parseInt(NODE_PROCESS_VERSION_PARTS[0], 10); const MINOR_VERSION = Number.parseInt(NODE_PROCESS_VERSION_PARTS[1], 10); const SUPPORTED_MAJOR_VERSION = 10; const SUPPORTED_MINOR_VERSION = 10; const IS_MATCHED_BY_MAJOR = MAJOR_VERSION > SUPPORTED_MAJOR_VERSION; const IS_MATCHED_BY_MAJOR_AND_MINOR = MAJOR_VERSION === SUPPORTED_MAJOR_VERSION && MINOR_VERSION >= SUPPORTED_MINOR_VERSION; /** * IS `true` for Node.js 10.10 and greater. */ constants$1.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_BY_MAJOR_AND_MINOR; var utils$9 = {}; var fs$6 = {}; Object.defineProperty(fs$6, "__esModule", { value: true }); fs$6.createDirentFromStats = void 0; class DirentFromStats { constructor(name, stats) { this.name = name; this.isBlockDevice = stats.isBlockDevice.bind(stats); this.isCharacterDevice = stats.isCharacterDevice.bind(stats); this.isDirectory = stats.isDirectory.bind(stats); this.isFIFO = stats.isFIFO.bind(stats); this.isFile = stats.isFile.bind(stats); this.isSocket = stats.isSocket.bind(stats); this.isSymbolicLink = stats.isSymbolicLink.bind(stats); } } function createDirentFromStats(name, stats) { return new DirentFromStats(name, stats); } fs$6.createDirentFromStats = createDirentFromStats; Object.defineProperty(utils$9, "__esModule", { value: true }); utils$9.fs = void 0; const fs$5 = fs$6; utils$9.fs = fs$5; var common$6 = {}; Object.defineProperty(common$6, "__esModule", { value: true }); common$6.joinPathSegments = void 0; function joinPathSegments$1(a, b, separator) { /** * The correct handling of cases when the first segment is a root (`/`, `C:/`) or UNC path (`//?/C:/`). */ if (a.endsWith(separator)) { return a + b; } return a + separator + b; } common$6.joinPathSegments = joinPathSegments$1; Object.defineProperty(async$3, "__esModule", { value: true }); async$3.readdir = async$3.readdirWithFileTypes = async$3.read = void 0; const fsStat$5 = out$1; const rpl = runParallel_1; const constants_1$1 = constants$1; const utils$8 = utils$9; const common$5 = common$6; function read$1(directory, settings, callback) { if (!settings.stats && constants_1$1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { readdirWithFileTypes$1(directory, settings, callback); return; } readdir$1(directory, settings, callback); } async$3.read = read$1; function readdirWithFileTypes$1(directory, settings, callback) { settings.fs.readdir(directory, { withFileTypes: true }, (readdirError, dirents) => { if (readdirError !== null) { callFailureCallback$1(callback, readdirError); return; } const entries = dirents.map(dirent => ({ dirent, name: dirent.name, path: common$5.joinPathSegments(directory, dirent.name, settings.pathSegmentSeparator) })); if (!settings.followSymbolicLinks) { callSuccessCallback$1(callback, entries); return; } const tasks = entries.map(entry => makeRplTaskEntry(entry, settings)); rpl(tasks, (rplError, rplEntries) => { if (rplError !== null) { callFailureCallback$1(callback, rplError); return; } callSuccessCallback$1(callback, rplEntries); }); }); } async$3.readdirWithFileTypes = readdirWithFileTypes$1; function makeRplTaskEntry(entry, settings) { return done => { if (!entry.dirent.isSymbolicLink()) { done(null, entry); return; } settings.fs.stat(entry.path, (statError, stats) => { if (statError !== null) { if (settings.throwErrorOnBrokenSymbolicLink) { done(statError); return; } done(null, entry); return; } entry.dirent = utils$8.fs.createDirentFromStats(entry.name, stats); done(null, entry); }); }; } function readdir$1(directory, settings, callback) { settings.fs.readdir(directory, (readdirError, names) => { if (readdirError !== null) { callFailureCallback$1(callback, readdirError); return; } const tasks = names.map(name => { const path = common$5.joinPathSegments(directory, name, settings.pathSegmentSeparator); return done => { fsStat$5.stat(path, settings.fsStatSettings, (error, stats) => { if (error !== null) { done(error); return; } const entry = { name, path, dirent: utils$8.fs.createDirentFromStats(name, stats) }; if (settings.stats) { entry.stats = stats; } done(null, entry); }); }; }); rpl(tasks, (rplError, entries) => { if (rplError !== null) { callFailureCallback$1(callback, rplError); return; } callSuccessCallback$1(callback, entries); }); }); } async$3.readdir = readdir$1; function callFailureCallback$1(callback, error) { callback(error); } function callSuccessCallback$1(callback, result) { callback(null, result); } var sync$5 = {}; Object.defineProperty(sync$5, "__esModule", { value: true }); sync$5.readdir = sync$5.readdirWithFileTypes = sync$5.read = void 0; const fsStat$4 = out$1; const constants_1 = constants$1; const utils$7 = utils$9; const common$4 = common$6; function read(directory, settings) { if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { return readdirWithFileTypes(directory, settings); } return readdir(directory, settings); } sync$5.read = read; function readdirWithFileTypes(directory, settings) { const dirents = settings.fs.readdirSync(directory, { withFileTypes: true }); return dirents.map(dirent => { const entry = { dirent, name: dirent.name, path: common$4.joinPathSegments(directory, dirent.name, settings.pathSegmentSeparator) }; if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) { try { const stats = settings.fs.statSync(entry.path); entry.dirent = utils$7.fs.createDirentFromStats(entry.name, stats); } catch (error) { if (settings.throwErrorOnBrokenSymbolicLink) { throw error; } } } return entry; }); } sync$5.readdirWithFileTypes = readdirWithFileTypes; function readdir(directory, settings) { const names = settings.fs.readdirSync(directory); return names.map(name => { const entryPath = common$4.joinPathSegments(directory, name, settings.pathSegmentSeparator); const stats = fsStat$4.statSync(entryPath, settings.fsStatSettings); const entry = { name, path: entryPath, dirent: utils$7.fs.createDirentFromStats(name, stats) }; if (settings.stats) { entry.stats = stats; } return entry; }); } sync$5.readdir = readdir; var settings$2 = {}; var fs$4 = {}; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0; const fs = fs$b; exports.FILE_SYSTEM_ADAPTER = { lstat: fs.lstat, stat: fs.stat, lstatSync: fs.lstatSync, statSync: fs.statSync, readdir: fs.readdir, readdirSync: fs.readdirSync }; function createFileSystemAdapter(fsMethods) { if (fsMethods === undefined) { return exports.FILE_SYSTEM_ADAPTER; } return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); } exports.createFileSystemAdapter = createFileSystemAdapter; })(fs$4); Object.defineProperty(settings$2, "__esModule", { value: true }); const path$5 = path$c; const fsStat$3 = out$1; const fs$3 = fs$4; let Settings$1 = class Settings { constructor(_options = {}) { this._options = _options; this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false); this.fs = fs$3.createFileSystemAdapter(this._options.fs); this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path$5.sep); this.stats = this._getValue(this._options.stats, false); this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); this.fsStatSettings = new fsStat$3.Settings({ followSymbolicLink: this.followSymbolicLinks, fs: this.fs, throwErrorOnBrokenSymbolicLink: this.throwErrorOnBrokenSymbolicLink }); } _getValue(option, value) { return option !== null && option !== void 0 ? option : value; } }; settings$2.default = Settings$1; Object.defineProperty(out$2, "__esModule", { value: true }); out$2.Settings = out$2.scandirSync = out$2.scandir = void 0; const async = async$3; const sync$4 = sync$5; const settings_1$2 = settings$2; out$2.Settings = settings_1$2.default; function scandir(path, optionsOrSettingsOrCallback, callback) { if (typeof optionsOrSettingsOrCallback === 'function') { async.read(path, getSettings$1(), optionsOrSettingsOrCallback); return; } async.read(path, getSettings$1(optionsOrSettingsOrCallback), callback); } out$2.scandir = scandir; function scandirSync(path, optionsOrSettings) { const settings = getSettings$1(optionsOrSettings); return sync$4.read(path, settings); } out$2.scandirSync = scandirSync; function getSettings$1(settingsOrOptions = {}) { if (settingsOrOptions instanceof settings_1$2.default) { return settingsOrOptions; } return new settings_1$2.default(settingsOrOptions); } var queue$1 = {exports: {}}; function reusify$1(Constructor) { var head = new Constructor(); var tail = head; function get() { var current = head; if (current.next) { head = current.next; } else { head = new Constructor(); tail = head; } current.next = null; return current; } function release(obj) { tail.next = obj; tail = obj; } return { get: get, release: release }; } var reusify_1 = reusify$1; /* eslint-disable no-var */ var reusify = reusify_1; function fastqueue(context, worker, _concurrency) { if (typeof context === 'function') { _concurrency = worker; worker = context; context = null; } if (!(_concurrency >= 1)) { throw new Error('fastqueue concurrency must be equal to or greater than 1'); } var cache = reusify(Task); var queueHead = null; var queueTail = null; var _running = 0; var errorHandler = null; var self = { push: push, drain: noop$1, saturated: noop$1, pause: pause, paused: false, get concurrency() { return _concurrency; }, set concurrency(value) { if (!(value >= 1)) { throw new Error('fastqueue concurrency must be equal to or greater than 1'); } _concurrency = value; if (self.paused) return; for (; queueHead && _running < _concurrency;) { _running++; release(); } }, running: running, resume: resume, idle: idle, length: length, getQueue: getQueue, unshift: unshift, empty: noop$1, kill: kill, killAndDrain: killAndDrain, error: error }; return self; function running() { return _running; } function pause() { self.paused = true; } function length() { var current = queueHead; var counter = 0; while (current) { current = current.next; counter++; } return counter; } function getQueue() { var current = queueHead; var tasks = []; while (current) { tasks.push(current.value); current = current.next; } return tasks; } function resume() { if (!self.paused) return; self.paused = false; if (queueHead === null) { _running++; release(); return; } for (; queueHead && _running < _concurrency;) { _running++; release(); } } function idle() { return _running === 0 && self.length() === 0; } function push(value, done) { var current = cache.get(); current.context = context; current.release = release; current.value = value; current.callback = done || noop$1; current.errorHandler = errorHandler; if (_running >= _concurrency || self.paused) { if (queueTail) { queueTail.next = current; queueTail = current; } else { queueHead = current; queueTail = current; self.saturated(); } } else { _running++; worker.call(context, current.value, current.worked); } } function unshift(value, done) { var current = cache.get(); current.context = context; current.release = release; current.value = value; current.callback = done || noop$1; current.errorHandler = errorHandler; if (_running >= _concurrency || self.paused) { if (queueHead) { current.next = queueHead; queueHead = current; } else { queueHead = current; queueTail = current; self.saturated(); } } else { _running++; worker.call(context, current.value, current.worked); } } function release(holder) { if (holder) { cache.release(holder); } var next = queueHead; if (next && _running <= _concurrency) { if (!self.paused) { if (queueTail === queueHead) { queueTail = null; } queueHead = next.next; next.next = null; worker.call(context, next.value, next.worked); if (queueTail === null) { self.empty(); } } else { _running--; } } else if (--_running === 0) { self.drain(); } } function kill() { queueHead = null; queueTail = null; self.drain = noop$1; } function killAndDrain() { queueHead = null; queueTail = null; self.drain(); self.drain = noop$1; } function error(handler) { errorHandler = handler; } } function noop$1() {} function Task() { this.value = null; this.callback = noop$1; this.next = null; this.release = noop$1; this.context = null; this.errorHandler = null; var self = this; this.worked = function worked(err, result) { var callback = self.callback; var errorHandler = self.errorHandler; var val = self.value; self.value = null; self.callback = noop$1; if (self.errorHandler) { errorHandler(err, val); } callback.call(self.context, err, result); self.release(self); }; } function queueAsPromised(context, worker, _concurrency) { if (typeof context === 'function') { _concurrency = worker; worker = context; context = null; } function asyncWrapper(arg, cb) { worker.call(this, arg).then(function (res) { cb(null, res); }, cb); } var queue = fastqueue(context, asyncWrapper, _concurrency); var pushCb = queue.push; var unshiftCb = queue.unshift; queue.push = push; queue.unshift = unshift; queue.drained = drained; return queue; function push(value) { var p = new Promise(function (resolve, reject) { pushCb(value, function (err, result) { if (err) { reject(err); return; } resolve(result); }); }); // Let's fork the promise chain to // make the error bubble up to the user but // not lead to a unhandledRejection p.catch(noop$1); return p; } function unshift(value) { var p = new Promise(function (resolve, reject) { unshiftCb(value, function (err, result) { if (err) { reject(err); return; } resolve(result); }); }); // Let's fork the promise chain to // make the error bubble up to the user but // not lead to a unhandledRejection p.catch(noop$1); return p; } function drained() { if (queue.idle()) { return new Promise(function (resolve) { resolve(); }); } var previousDrain = queue.drain; var p = new Promise(function (resolve) { queue.drain = function () { previousDrain(); resolve(); }; }); return p; } } queue$1.exports = fastqueue; queue$1.exports.promise = queueAsPromised; var queueExports = queue$1.exports; var common$3 = {}; Object.defineProperty(common$3, "__esModule", { value: true }); common$3.joinPathSegments = common$3.replacePathSegmentSeparator = common$3.isAppliedFilter = common$3.isFatalError = void 0; function isFatalError(settings, error) { if (settings.errorFilter === null) { return true; } return !settings.errorFilter(error); } common$3.isFatalError = isFatalError; function isAppliedFilter(filter, value) { return filter === null || filter(value); } common$3.isAppliedFilter = isAppliedFilter; function replacePathSegmentSeparator(filepath, separator) { return filepath.split(/[/\\]/).join(separator); } common$3.replacePathSegmentSeparator = replacePathSegmentSeparator; function joinPathSegments(a, b, separator) { if (a === '') { return b; } /** * The correct handling of cases when the first segment is a root (`/`, `C:/`) or UNC path (`//?/C:/`). */ if (a.endsWith(separator)) { return a + b; } return a + separator + b; } common$3.joinPathSegments = joinPathSegments; var reader$1 = {}; Object.defineProperty(reader$1, "__esModule", { value: true }); const common$2 = common$3; let Reader$1 = class Reader { constructor(_root, _settings) { this._root = _root; this._settings = _settings; this._root = common$2.replacePathSegmentSeparator(_root, _settings.pathSegmentSeparator); } }; reader$1.default = Reader$1; Object.defineProperty(async$4, "__esModule", { value: true }); const events_1 = require$$0$2; const fsScandir$2 = out$2; const fastq = queueExports; const common$1 = common$3; const reader_1$4 = reader$1; class AsyncReader extends reader_1$4.default { constructor(_root, _settings) { super(_root, _settings); this._settings = _settings; this._scandir = fsScandir$2.scandir; this._emitter = new events_1.EventEmitter(); this._queue = fastq(this._worker.bind(this), this._settings.concurrency); this._isFatalError = false; this._isDestroyed = false; this._queue.drain = () => { if (!this._isFatalError) { this._emitter.emit('end'); } }; } read() { this._isFatalError = false; this._isDestroyed = false; setImmediate(() => { this._pushToQueue(this._root, this._settings.basePath); }); return this._emitter; } get isDestroyed() { return this._isDestroyed; } destroy() { if (this._isDestroyed) { throw new Error('The reader is already destroyed'); } this._isDestroyed = true; this._queue.killAndDrain(); } onEntry(callback) { this._emitter.on('entry', callback); } onError(callback) { this._emitter.once('error', callback); } onEnd(callback) { this._emitter.once('end', callback); } _pushToQueue(directory, base) { const queueItem = { directory, base }; this._queue.push(queueItem, error => { if (error !== null) { this._handleError(error); } }); } _worker(item, done) { this._scandir(item.directory, this._settings.fsScandirSettings, (error, entries) => { if (error !== null) { done(error, undefined); return; } for (const entry of entries) { this._handleEntry(entry, item.base); } done(null, undefined); }); } _handleError(error) { if (this._isDestroyed || !common$1.isFatalError(this._settings, error)) { return; } this._isFatalError = true; this._isDestroyed = true; this._emitter.emit('error', error); } _handleEntry(entry, base) { if (this._isDestroyed || this._isFatalError) { return; } const fullpath = entry.path; if (base !== undefined) { entry.path = common$1.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); } if (common$1.isAppliedFilter(this._settings.entryFilter, entry)) { this._emitEntry(entry); } if (entry.dirent.isDirectory() && common$1.isAppliedFilter(this._settings.deepFilter, entry)) { this._pushToQueue(fullpath, base === undefined ? undefined : entry.path); } } _emitEntry(entry) { this._emitter.emit('entry', entry); } } async$4.default = AsyncReader; Object.defineProperty(async$5, "__esModule", { value: true }); const async_1$4 = async$4; class AsyncProvider { constructor(_root, _settings) { this._root = _root; this._settings = _settings; this._reader = new async_1$4.default(this._root, this._settings); this._storage = []; } read(callback) { this._reader.onError(error => { callFailureCallback(callback, error); }); this._reader.onEntry(entry => { this._storage.push(entry); }); this._reader.onEnd(() => { callSuccessCallback(callback, this._storage); }); this._reader.read(); } } async$5.default = AsyncProvider; function callFailureCallback(callback, error) { callback(error); } function callSuccessCallback(callback, entries) { callback(null, entries); } var stream$2 = {}; Object.defineProperty(stream$2, "__esModule", { value: true }); const stream_1$5 = require$$0; const async_1$3 = async$4; class StreamProvider { constructor(_root, _settings) { this._root = _root; this._settings = _settings; this._reader = new async_1$3.default(this._root, this._settings); this._stream = new stream_1$5.Readable({ objectMode: true, read: () => {}, destroy: () => { if (!this._reader.isDestroyed) { this._reader.destroy(); } } }); } read() { this._reader.onError(error => { this._stream.emit('error', error); }); this._reader.onEntry(entry => { this._stream.push(entry); }); this._reader.onEnd(() => { this._stream.push(null); }); this._reader.read(); return this._stream; } } stream$2.default = StreamProvider; var sync$3 = {}; var sync$2 = {}; Object.defineProperty(sync$2, "__esModule", { value: true }); const fsScandir$1 = out$2; const common = common$3; const reader_1$3 = reader$1; class SyncReader extends reader_1$3.default { constructor() { super(...arguments); this._scandir = fsScandir$1.scandirSync; this._storage = []; this._queue = new Set(); } read() { this._pushToQueue(this._root, this._settings.basePath); this._handleQueue(); return this._storage; } _pushToQueue(directory, base) { this._queue.add({ directory, base }); } _handleQueue() { for (const item of this._queue.values()) { this._handleDirectory(item.directory, item.base); } } _handleDirectory(directory, base) { try { const entries = this._scandir(directory, this._settings.fsScandirSettings); for (const entry of entries) { this._handleEntry(entry, base); } } catch (error) { this._handleError(error); } } _handleError(error) { if (!common.isFatalError(this._settings, error)) { return; } throw error; } _handleEntry(entry, base) { const fullpath = entry.path; if (base !== undefined) { entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); } if (common.isAppliedFilter(this._settings.entryFilter, entry)) { this._pushToStorage(entry); } if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { this._pushToQueue(fullpath, base === undefined ? undefined : entry.path); } } _pushToStorage(entry) { this._storage.push(entry); } } sync$2.default = SyncReader; Object.defineProperty(sync$3, "__esModule", { value: true }); const sync_1$3 = sync$2; class SyncProvider { constructor(_root, _settings) { this._root = _root; this._settings = _settings; this._reader = new sync_1$3.default(this._root, this._settings); } read() { return this._reader.read(); } } sync$3.default = SyncProvider; var settings$1 = {}; Object.defineProperty(settings$1, "__esModule", { value: true }); const path$4 = path$c; const fsScandir = out$2; class Settings { constructor(_options = {}) { this._options = _options; this.basePath = this._getValue(this._options.basePath, undefined); this.concurrency = this._getValue(this._options.concurrency, Number.POSITIVE_INFINITY); this.deepFilter = this._getValue(this._options.deepFilter, null); this.entryFilter = this._getValue(this._options.entryFilter, null); this.errorFilter = this._getValue(this._options.errorFilter, null); this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path$4.sep); this.fsScandirSettings = new fsScandir.Settings({ followSymbolicLinks: this._options.followSymbolicLinks, fs: this._options.fs, pathSegmentSeparator: this._options.pathSegmentSeparator, stats: this._options.stats, throwErrorOnBrokenSymbolicLink: this._options.throwErrorOnBrokenSymbolicLink }); } _getValue(option, value) { return option !== null && option !== void 0 ? option : value; } } settings$1.default = Settings; Object.defineProperty(out$3, "__esModule", { value: true }); out$3.Settings = out$3.walkStream = out$3.walkSync = out$3.walk = void 0; const async_1$2 = async$5; const stream_1$4 = stream$2; const sync_1$2 = sync$3; const settings_1$1 = settings$1; out$3.Settings = settings_1$1.default; function walk(directory, optionsOrSettingsOrCallback, callback) { if (typeof optionsOrSettingsOrCallback === 'function') { new async_1$2.default(directory, getSettings()).read(optionsOrSettingsOrCallback); return; } new async_1$2.default(directory, getSettings(optionsOrSettingsOrCallback)).read(callback); } out$3.walk = walk; function walkSync(directory, optionsOrSettings) { const settings = getSettings(optionsOrSettings); const provider = new sync_1$2.default(directory, settings); return provider.read(); } out$3.walkSync = walkSync; function walkStream(directory, optionsOrSettings) { const settings = getSettings(optionsOrSettings); const provider = new stream_1$4.default(directory, settings); return provider.read(); } out$3.walkStream = walkStream; function getSettings(settingsOrOptions = {}) { if (settingsOrOptions instanceof settings_1$1.default) { return settingsOrOptions; } return new settings_1$1.default(settingsOrOptions); } var reader = {}; Object.defineProperty(reader, "__esModule", { value: true }); const path$3 = path$c; const fsStat$2 = out$1; const utils$6 = utils$k; class Reader { constructor(_settings) { this._settings = _settings; this._fsStatSettings = new fsStat$2.Settings({ followSymbolicLink: this._settings.followSymbolicLinks, fs: this._settings.fs, throwErrorOnBrokenSymbolicLink: this._settings.followSymbolicLinks }); } _getFullEntryPath(filepath) { return path$3.resolve(this._settings.cwd, filepath); } _makeEntry(stats, pattern) { const entry = { name: pattern, path: pattern, dirent: utils$6.fs.createDirentFromStats(pattern, stats) }; if (this._settings.stats) { entry.stats = stats; } return entry; } _isFatalError(error) { return !utils$6.errno.isEnoentCodeError(error) && !this._settings.suppressErrors; } } reader.default = Reader; var stream$1 = {}; Object.defineProperty(stream$1, "__esModule", { value: true }); const stream_1$3 = require$$0; const fsStat$1 = out$1; const fsWalk$2 = out$3; const reader_1$2 = reader; class ReaderStream extends reader_1$2.default { constructor() { super(...arguments); this._walkStream = fsWalk$2.walkStream; this._stat = fsStat$1.stat; } dynamic(root, options) { return this._walkStream(root, options); } static(patterns, options) { const filepaths = patterns.map(this._getFullEntryPath, this); const stream = new stream_1$3.PassThrough({ objectMode: true }); stream._write = (index, _enc, done) => { return this._getEntry(filepaths[index], patterns[index], options).then(entry => { if (entry !== null && options.entryFilter(entry)) { stream.push(entry); } if (index === filepaths.length - 1) { stream.end(); } done(); }).catch(done); }; for (let i = 0; i < filepaths.length; i++) { stream.write(i); } return stream; } _getEntry(filepath, pattern, options) { return this._getStat(filepath).then(stats => this._makeEntry(stats, pattern)).catch(error => { if (options.errorFilter(error)) { return null; } throw error; }); } _getStat(filepath) { return new Promise((resolve, reject) => { this._stat(filepath, this._fsStatSettings, (error, stats) => { return error === null ? resolve(stats) : reject(error); }); }); } } stream$1.default = ReaderStream; Object.defineProperty(async$6, "__esModule", { value: true }); const fsWalk$1 = out$3; const reader_1$1 = reader; const stream_1$2 = stream$1; class ReaderAsync extends reader_1$1.default { constructor() { super(...arguments); this._walkAsync = fsWalk$1.walk; this._readerStream = new stream_1$2.default(this._settings); } dynamic(root, options) { return new Promise((resolve, reject) => { this._walkAsync(root, options, (error, entries) => { if (error === null) { resolve(entries); } else { reject(error); } }); }); } async static(patterns, options) { const entries = []; const stream = this._readerStream.static(patterns, options); // After #235, replace it with an asynchronous iterator. return new Promise((resolve, reject) => { stream.once('error', reject); stream.on('data', entry => entries.push(entry)); stream.once('end', () => resolve(entries)); }); } } async$6.default = ReaderAsync; var provider = {}; var deep = {}; var partial = {}; var matcher = {}; Object.defineProperty(matcher, "__esModule", { value: true }); const utils$5 = utils$k; class Matcher { constructor(_patterns, _settings, _micromatchOptions) { this._patterns = _patterns; this._settings = _settings; this._micromatchOptions = _micromatchOptions; this._storage = []; this._fillStorage(); } _fillStorage() { for (const pattern of this._patterns) { const segments = this._getPatternSegments(pattern); const sections = this._splitSegmentsIntoSections(segments); this._storage.push({ complete: sections.length <= 1, pattern, segments, sections }); } } _getPatternSegments(pattern) { const parts = utils$5.pattern.getPatternParts(pattern, this._micromatchOptions); return parts.map(part => { const dynamic = utils$5.pattern.isDynamicPattern(part, this._settings); if (!dynamic) { return { dynamic: false, pattern: part }; } return { dynamic: true, pattern: part, patternRe: utils$5.pattern.makeRe(part, this._micromatchOptions) }; }); } _splitSegmentsIntoSections(segments) { return utils$5.array.splitWhen(segments, segment => segment.dynamic && utils$5.pattern.hasGlobStar(segment.pattern)); } } matcher.default = Matcher; Object.defineProperty(partial, "__esModule", { value: true }); const matcher_1 = matcher; class PartialMatcher extends matcher_1.default { match(filepath) { const parts = filepath.split('/'); const levels = parts.length; const patterns = this._storage.filter(info => !info.complete || info.segments.length > levels); for (const pattern of patterns) { const section = pattern.sections[0]; /** * In this case, the pattern has a globstar and we must read all directories unconditionally, * but only if the level has reached the end of the first group. * * fixtures/{a,b}/** * ^ true/false ^ always true */ if (!pattern.complete && levels > section.length) { return true; } const match = parts.every((part, index) => { const segment = pattern.segments[index]; if (segment.dynamic && segment.patternRe.test(part)) { return true; } if (!segment.dynamic && segment.pattern === part) { return true; } return false; }); if (match) { return true; } } return false; } } partial.default = PartialMatcher; Object.defineProperty(deep, "__esModule", { value: true }); const utils$4 = utils$k; const partial_1 = partial; class DeepFilter { constructor(_settings, _micromatchOptions) { this._settings = _settings; this._micromatchOptions = _micromatchOptions; } getFilter(basePath, positive, negative) { const matcher = this._getMatcher(positive); const negativeRe = this._getNegativePatternsRe(negative); return entry => this._filter(basePath, entry, matcher, negativeRe); } _getMatcher(patterns) { return new partial_1.default(patterns, this._settings, this._micromatchOptions); } _getNegativePatternsRe(patterns) { const affectDepthOfReadingPatterns = patterns.filter(utils$4.pattern.isAffectDepthOfReadingPattern); return utils$4.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this._micromatchOptions); } _filter(basePath, entry, matcher, negativeRe) { if (this._isSkippedByDeep(basePath, entry.path)) { return false; } if (this._isSkippedSymbolicLink(entry)) { return false; } const filepath = utils$4.path.removeLeadingDotSegment(entry.path); if (this._isSkippedByPositivePatterns(filepath, matcher)) { return false; } return this._isSkippedByNegativePatterns(filepath, negativeRe); } _isSkippedByDeep(basePath, entryPath) { /** * Avoid unnecessary depth calculations when it doesn't matter. */ if (this._settings.deep === Infinity) { return false; } return this._getEntryLevel(basePath, entryPath) >= this._settings.deep; } _getEntryLevel(basePath, entryPath) { const entryPathDepth = entryPath.split('/').length; if (basePath === '') { return entryPathDepth; } const basePathDepth = basePath.split('/').length; return entryPathDepth - basePathDepth; } _isSkippedSymbolicLink(entry) { return !this._settings.followSymbolicLinks && entry.dirent.isSymbolicLink(); } _isSkippedByPositivePatterns(entryPath, matcher) { return !this._settings.baseNameMatch && !matcher.match(entryPath); } _isSkippedByNegativePatterns(entryPath, patternsRe) { return !utils$4.pattern.matchAny(entryPath, patternsRe); } } deep.default = DeepFilter; var entry$1 = {}; Object.defineProperty(entry$1, "__esModule", { value: true }); const utils$3 = utils$k; class EntryFilter { constructor(_settings, _micromatchOptions) { this._settings = _settings; this._micromatchOptions = _micromatchOptions; this.index = new Map(); } getFilter(positive, negative) { const positiveRe = utils$3.pattern.convertPatternsToRe(positive, this._micromatchOptions); const negativeRe = utils$3.pattern.convertPatternsToRe(negative, Object.assign(Object.assign({}, this._micromatchOptions), { dot: true })); return entry => this._filter(entry, positiveRe, negativeRe); } _filter(entry, positiveRe, negativeRe) { const filepath = utils$3.path.removeLeadingDotSegment(entry.path); if (this._settings.unique && this._isDuplicateEntry(filepath)) { return false; } if (this._onlyFileFilter(entry) || this._onlyDirectoryFilter(entry)) { return false; } if (this._isSkippedByAbsoluteNegativePatterns(filepath, negativeRe)) { return false; } const isDirectory = entry.dirent.isDirectory(); const isMatched = this._isMatchToPatterns(filepath, positiveRe, isDirectory) && !this._isMatchToPatterns(filepath, negativeRe, isDirectory); if (this._settings.unique && isMatched) { this._createIndexRecord(filepath); } return isMatched; } _isDuplicateEntry(filepath) { return this.index.has(filepath); } _createIndexRecord(filepath) { this.index.set(filepath, undefined); } _onlyFileFilter(entry) { return this._settings.onlyFiles && !entry.dirent.isFile(); } _onlyDirectoryFilter(entry) { return this._settings.onlyDirectories && !entry.dirent.isDirectory(); } _isSkippedByAbsoluteNegativePatterns(entryPath, patternsRe) { if (!this._settings.absolute) { return false; } const fullpath = utils$3.path.makeAbsolute(this._settings.cwd, entryPath); return utils$3.pattern.matchAny(fullpath, patternsRe); } _isMatchToPatterns(filepath, patternsRe, isDirectory) { // Trying to match files and directories by patterns. const isMatched = utils$3.pattern.matchAny(filepath, patternsRe); // A pattern with a trailling slash can be used for directory matching. // To apply such pattern, we need to add a tralling slash to the path. if (!isMatched && isDirectory) { return utils$3.pattern.matchAny(filepath + '/', patternsRe); } return isMatched; } } entry$1.default = EntryFilter; var error = {}; Object.defineProperty(error, "__esModule", { value: true }); const utils$2 = utils$k; class ErrorFilter { constructor(_settings) { this._settings = _settings; } getFilter() { return error => this._isNonFatalError(error); } _isNonFatalError(error) { return utils$2.errno.isEnoentCodeError(error) || this._settings.suppressErrors; } } error.default = ErrorFilter; var entry = {}; Object.defineProperty(entry, "__esModule", { value: true }); const utils$1 = utils$k; class EntryTransformer { constructor(_settings) { this._settings = _settings; } getTransformer() { return entry => this._transform(entry); } _transform(entry) { let filepath = entry.path; if (this._settings.absolute) { filepath = utils$1.path.makeAbsolute(this._settings.cwd, filepath); filepath = utils$1.path.unixify(filepath); } if (this._settings.markDirectories && entry.dirent.isDirectory()) { filepath += '/'; } if (!this._settings.objectMode) { return filepath; } return Object.assign(Object.assign({}, entry), { path: filepath }); } } entry.default = EntryTransformer; Object.defineProperty(provider, "__esModule", { value: true }); const path$2 = path$c; const deep_1 = deep; const entry_1 = entry$1; const error_1 = error; const entry_2 = entry; class Provider { constructor(_settings) { this._settings = _settings; this.errorFilter = new error_1.default(this._settings); this.entryFilter = new entry_1.default(this._settings, this._getMicromatchOptions()); this.deepFilter = new deep_1.default(this._settings, this._getMicromatchOptions()); this.entryTransformer = new entry_2.default(this._settings); } _getRootDirectory(task) { return path$2.resolve(this._settings.cwd, task.base); } _getReaderOptions(task) { const basePath = task.base === '.' ? '' : task.base; return { basePath, pathSegmentSeparator: '/', concurrency: this._settings.concurrency, deepFilter: this.deepFilter.getFilter(basePath, task.positive, task.negative), entryFilter: this.entryFilter.getFilter(task.positive, task.negative), errorFilter: this.errorFilter.getFilter(), followSymbolicLinks: this._settings.followSymbolicLinks, fs: this._settings.fs, stats: this._settings.stats, throwErrorOnBrokenSymbolicLink: this._settings.throwErrorOnBrokenSymbolicLink, transform: this.entryTransformer.getTransformer() }; } _getMicromatchOptions() { return { dot: this._settings.dot, matchBase: this._settings.baseNameMatch, nobrace: !this._settings.braceExpansion, nocase: !this._settings.caseSensitiveMatch, noext: !this._settings.extglob, noglobstar: !this._settings.globstar, posix: true, strictSlashes: false }; } } provider.default = Provider; Object.defineProperty(async$7, "__esModule", { value: true }); const async_1$1 = async$6; const provider_1$2 = provider; class ProviderAsync extends provider_1$2.default { constructor() { super(...arguments); this._reader = new async_1$1.default(this._settings); } async read(task) { const root = this._getRootDirectory(task); const options = this._getReaderOptions(task); const entries = await this.api(root, task, options); return entries.map(entry => options.transform(entry)); } api(root, task, options) { if (task.dynamic) { return this._reader.dynamic(root, options); } return this._reader.static(task.patterns, options); } } async$7.default = ProviderAsync; var stream = {}; Object.defineProperty(stream, "__esModule", { value: true }); const stream_1$1 = require$$0; const stream_2 = stream$1; const provider_1$1 = provider; class ProviderStream extends provider_1$1.default { constructor() { super(...arguments); this._reader = new stream_2.default(this._settings); } read(task) { const root = this._getRootDirectory(task); const options = this._getReaderOptions(task); const source = this.api(root, task, options); const destination = new stream_1$1.Readable({ objectMode: true, read: () => {} }); source.once('error', error => destination.emit('error', error)).on('data', entry => destination.emit('data', options.transform(entry))).once('end', () => destination.emit('end')); destination.once('close', () => source.destroy()); return destination; } api(root, task, options) { if (task.dynamic) { return this._reader.dynamic(root, options); } return this._reader.static(task.patterns, options); } } stream.default = ProviderStream; var sync$1 = {}; var sync = {}; Object.defineProperty(sync, "__esModule", { value: true }); const fsStat = out$1; const fsWalk = out$3; const reader_1 = reader; class ReaderSync extends reader_1.default { constructor() { super(...arguments); this._walkSync = fsWalk.walkSync; this._statSync = fsStat.statSync; } dynamic(root, options) { return this._walkSync(root, options); } static(patterns, options) { const entries = []; for (const pattern of patterns) { const filepath = this._getFullEntryPath(pattern); const entry = this._getEntry(filepath, pattern, options); if (entry === null || !options.entryFilter(entry)) { continue; } entries.push(entry); } return entries; } _getEntry(filepath, pattern, options) { try { const stats = this._getStat(filepath); return this._makeEntry(stats, pattern); } catch (error) { if (options.errorFilter(error)) { return null; } throw error; } } _getStat(filepath) { return this._statSync(filepath, this._fsStatSettings); } } sync.default = ReaderSync; Object.defineProperty(sync$1, "__esModule", { value: true }); const sync_1$1 = sync; const provider_1 = provider; class ProviderSync extends provider_1.default { constructor() { super(...arguments); this._reader = new sync_1$1.default(this._settings); } read(task) { const root = this._getRootDirectory(task); const options = this._getReaderOptions(task); const entries = this.api(root, task, options); return entries.map(options.transform); } api(root, task, options) { if (task.dynamic) { return this._reader.dynamic(root, options); } return this._reader.static(task.patterns, options); } } sync$1.default = ProviderSync; var settings = {}; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_FILE_SYSTEM_ADAPTER = void 0; const fs = fs$b; const os = os$1; /** * The `os.cpus` method can return zero. We expect the number of cores to be greater than zero. * https://github.com/nodejs/node/blob/7faeddf23a98c53896f8b574a6e66589e8fb1eb8/lib/os.js#L106-L107 */ const CPU_COUNT = Math.max(os.cpus().length, 1); exports.DEFAULT_FILE_SYSTEM_ADAPTER = { lstat: fs.lstat, lstatSync: fs.lstatSync, stat: fs.stat, statSync: fs.statSync, readdir: fs.readdir, readdirSync: fs.readdirSync }; class Settings { constructor(_options = {}) { this._options = _options; this.absolute = this._getValue(this._options.absolute, false); this.baseNameMatch = this._getValue(this._options.baseNameMatch, false); this.braceExpansion = this._getValue(this._options.braceExpansion, true); this.caseSensitiveMatch = this._getValue(this._options.caseSensitiveMatch, true); this.concurrency = this._getValue(this._options.concurrency, CPU_COUNT); this.cwd = this._getValue(this._options.cwd, process.cwd()); this.deep = this._getValue(this._options.deep, Infinity); this.dot = this._getValue(this._options.dot, false); this.extglob = this._getValue(this._options.extglob, true); this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, true); this.fs = this._getFileSystemMethods(this._options.fs); this.globstar = this._getValue(this._options.globstar, true); this.ignore = this._getValue(this._options.ignore, []); this.markDirectories = this._getValue(this._options.markDirectories, false); this.objectMode = this._getValue(this._options.objectMode, false); this.onlyDirectories = this._getValue(this._options.onlyDirectories, false); this.onlyFiles = this._getValue(this._options.onlyFiles, true); this.stats = this._getValue(this._options.stats, false); this.suppressErrors = this._getValue(this._options.suppressErrors, false); this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, false); this.unique = this._getValue(this._options.unique, true); if (this.onlyDirectories) { this.onlyFiles = false; } if (this.stats) { this.objectMode = true; } // Remove the cast to the array in the next major (#404). this.ignore = [].concat(this.ignore); } _getValue(option, value) { return option === undefined ? value : option; } _getFileSystemMethods(methods = {}) { return Object.assign(Object.assign({}, exports.DEFAULT_FILE_SYSTEM_ADAPTER), methods); } } exports.default = Settings; })(settings); const taskManager = tasks$1; const async_1 = async$7; const stream_1 = stream; const sync_1 = sync$1; const settings_1 = settings; const utils = utils$k; async function FastGlob(source, options) { assertPatternsInput$1(source); const works = getWorks(source, async_1.default, options); const result = await Promise.all(works); return utils.array.flatten(result); } // https://github.com/typescript-eslint/typescript-eslint/issues/60 // eslint-disable-next-line no-redeclare (function (FastGlob) { FastGlob.glob = FastGlob; FastGlob.globSync = sync; FastGlob.globStream = stream; FastGlob.async = FastGlob; function sync(source, options) { assertPatternsInput$1(source); const works = getWorks(source, sync_1.default, options); return utils.array.flatten(works); } FastGlob.sync = sync; function stream(source, options) { assertPatternsInput$1(source); const works = getWorks(source, stream_1.default, options); /** * The stream returned by the provider cannot work with an asynchronous iterator. * To support asynchronous iterators, regardless of the number of tasks, we always multiplex streams. * This affects performance (+25%). I don't see best solution right now. */ return utils.stream.merge(works); } FastGlob.stream = stream; function generateTasks(source, options) { assertPatternsInput$1(source); const patterns = [].concat(source); const settings = new settings_1.default(options); return taskManager.generate(patterns, settings); } FastGlob.generateTasks = generateTasks; function isDynamicPattern(source, options) { assertPatternsInput$1(source); const settings = new settings_1.default(options); return utils.pattern.isDynamicPattern(source, settings); } FastGlob.isDynamicPattern = isDynamicPattern; function escapePath(source) { assertPatternsInput$1(source); return utils.path.escape(source); } FastGlob.escapePath = escapePath; function convertPathToPattern(source) { assertPatternsInput$1(source); return utils.path.convertPathToPattern(source); } FastGlob.convertPathToPattern = convertPathToPattern; (function (posix) { function escapePath(source) { assertPatternsInput$1(source); return utils.path.escapePosixPath(source); } posix.escapePath = escapePath; function convertPathToPattern(source) { assertPatternsInput$1(source); return utils.path.convertPosixPathToPattern(source); } posix.convertPathToPattern = convertPathToPattern; })(FastGlob.posix || (FastGlob.posix = {})); (function (win32) { function escapePath(source) { assertPatternsInput$1(source); return utils.path.escapeWindowsPath(source); } win32.escapePath = escapePath; function convertPathToPattern(source) { assertPatternsInput$1(source); return utils.path.convertWindowsPathToPattern(source); } win32.convertPathToPattern = convertPathToPattern; })(FastGlob.win32 || (FastGlob.win32 = {})); })(FastGlob || (FastGlob = {})); function getWorks(source, _Provider, options) { const patterns = [].concat(source); const settings = new settings_1.default(options); const tasks = taskManager.generate(patterns, settings); const provider = new _Provider(settings); return tasks.map(provider.read, provider); } function assertPatternsInput$1(input) { const source = [].concat(input); const isValidSource = source.every(item => utils.string.isString(item) && !utils.string.isEmpty(item)); if (!isValidSource) { throw new TypeError('Patterns must be a string (non empty) or an array of strings'); } } var out = FastGlob; var fastGlob = /*@__PURE__*/getDefaultExportFromCjs(out); var dirGlob$1 = {exports: {}}; var pathType$1 = {}; const { promisify } = require$$0$1; const fs$2 = fs$b; async function isType(fsStatType, statsMethodName, filePath) { if (typeof filePath !== 'string') { throw new TypeError(`Expected a string, got ${typeof filePath}`); } try { const stats = await promisify(fs$2[fsStatType])(filePath); return stats[statsMethodName](); } catch (error) { if (error.code === 'ENOENT') { return false; } throw error; } } function isTypeSync(fsStatType, statsMethodName, filePath) { if (typeof filePath !== 'string') { throw new TypeError(`Expected a string, got ${typeof filePath}`); } try { return fs$2[fsStatType](filePath)[statsMethodName](); } catch (error) { if (error.code === 'ENOENT') { return false; } throw error; } } pathType$1.isFile = isType.bind(null, 'stat', 'isFile'); pathType$1.isDirectory = isType.bind(null, 'stat', 'isDirectory'); pathType$1.isSymlink = isType.bind(null, 'lstat', 'isSymbolicLink'); pathType$1.isFileSync = isTypeSync.bind(null, 'statSync', 'isFile'); pathType$1.isDirectorySync = isTypeSync.bind(null, 'statSync', 'isDirectory'); pathType$1.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); const path$1 = path$c; const pathType = pathType$1; const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; const getPath = (filepath, cwd) => { const pth = filepath[0] === '!' ? filepath.slice(1) : filepath; return path$1.isAbsolute(pth) ? pth : path$1.join(cwd, pth); }; const addExtensions = (file, extensions) => { if (path$1.extname(file)) { return `**/${file}`; } return `**/${file}.${getExtensions(extensions)}`; }; const getGlob = (directory, options) => { if (options.files && !Array.isArray(options.files)) { throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof options.files}\``); } if (options.extensions && !Array.isArray(options.extensions)) { throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof options.extensions}\``); } if (options.files && options.extensions) { return options.files.map(x => path$1.posix.join(directory, addExtensions(x, options.extensions))); } if (options.files) { return options.files.map(x => path$1.posix.join(directory, `**/${x}`)); } if (options.extensions) { return [path$1.posix.join(directory, `**/*.${getExtensions(options.extensions)}`)]; } return [path$1.posix.join(directory, '**')]; }; dirGlob$1.exports = async (input, options) => { options = { cwd: process.cwd(), ...options }; if (typeof options.cwd !== 'string') { throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); } const globs = await Promise.all([].concat(input).map(async x => { const isDirectory = await pathType.isDirectory(getPath(x, options.cwd)); return isDirectory ? getGlob(x, options) : x; })); return [].concat.apply([], globs); // eslint-disable-line prefer-spread }; dirGlob$1.exports.sync = (input, options) => { options = { cwd: process.cwd(), ...options }; if (typeof options.cwd !== 'string') { throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); } const globs = [].concat(input).map(x => pathType.isDirectorySync(getPath(x, options.cwd)) ? getGlob(x, options) : x); return [].concat.apply([], globs); // eslint-disable-line prefer-spread }; var dirGlobExports = dirGlob$1.exports; var dirGlob = /*@__PURE__*/getDefaultExportFromCjs(dirGlobExports); // A simple implementation of make-array function makeArray(subject) { return Array.isArray(subject) ? subject : [subject]; } const EMPTY = ''; const SPACE = ' '; const ESCAPE = '\\'; const REGEX_TEST_BLANK_LINE = /^\s+$/; const REGEX_INVALID_TRAILING_BACKSLASH = /(?:[^\\]|^)\\$/; const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/; const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/; const REGEX_SPLITALL_CRLF = /\r?\n/g; // /foo, // ./foo, // ../foo, // . // .. const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/; const SLASH = '/'; // Do not use ternary expression here, since "istanbul ignore next" is buggy let TMP_KEY_IGNORE = 'node-ignore'; /* istanbul ignore else */ if (typeof Symbol !== 'undefined') { TMP_KEY_IGNORE = Symbol.for('node-ignore'); } const KEY_IGNORE = TMP_KEY_IGNORE; const define = (object, key, value) => Object.defineProperty(object, key, { value }); const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g; const RETURN_FALSE = () => false; // Sanitize the range of a regular expression // The cases are complicated, see test cases for details const sanitizeRange = range => range.replace(REGEX_REGEXP_RANGE, (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) ? match // Invalid range (out of order) which is ok for gitignore rules but // fatal for JavaScript regular expression, so eliminate it. : EMPTY); // See fixtures #59 const cleanRangeBackSlash = slashes => { const { length } = slashes; return slashes.slice(0, length - length % 2); }; // > If the pattern ends with a slash, // > it is removed for the purpose of the following description, // > but it would only find a match with a directory. // > In other words, foo/ will match a directory foo and paths underneath it, // > but will not match a regular file or a symbolic link foo // > (this is consistent with the way how pathspec works in general in Git). // '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`' // -> ignore-rules will not deal with it, because it costs extra `fs.stat` call // you could use option `mark: true` with `glob` // '`foo/`' should not continue with the '`..`' const REPLACERS = [[ // remove BOM // TODO: // Other similar zero-width characters? /^\uFEFF/, () => EMPTY], // > Trailing spaces are ignored unless they are quoted with backslash ("\") [ // (a\ ) -> (a ) // (a ) -> (a) // (a \ ) -> (a ) /\\?\s+$/, match => match.indexOf('\\') === 0 ? SPACE : EMPTY], // replace (\ ) with ' ' [/\\\s/g, () => SPACE], // Escape metacharacters // which is written down by users but means special for regular expressions. // > There are 12 characters with special meanings: // > - the backslash \, // > - the caret ^, // > - the dollar sign $, // > - the period or dot ., // > - the vertical bar or pipe symbol |, // > - the question mark ?, // > - the asterisk or star *, // > - the plus sign +, // > - the opening parenthesis (, // > - the closing parenthesis ), // > - and the opening square bracket [, // > - the opening curly brace {, // > These special characters are often called "metacharacters". [/[\\$.|*+(){^]/g, match => `\\${match}`], [ // > a question mark (?) matches a single character /(?!\\)\?/g, () => '[^/]'], // leading slash [ // > A leading slash matches the beginning of the pathname. // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c". // A leading slash matches the beginning of the pathname /^\//, () => '^'], // replace special metacharacter slash after the leading slash [/\//g, () => '\\/'], [ // > A leading "**" followed by a slash means match in all directories. // > For example, "**/foo" matches file or directory "foo" anywhere, // > the same as pattern "foo". // > "**/foo/bar" matches file or directory "bar" anywhere that is directly // > under directory "foo". // Notice that the '*'s have been replaced as '\\*' /^\^*\\\*\\\*\\\//, // '**/foo' <-> 'foo' () => '^(?:.*\\/)?'], // starting [ // there will be no leading '/' // (which has been replaced by section "leading slash") // If starts with '**', adding a '^' to the regular expression also works /^(?=[^^])/, function startingReplacer() { // If has a slash `/` at the beginning or middle return !/\/(?!$)/.test(this) // > Prior to 2.22.1 // > If the pattern does not contain a slash /, // > Git treats it as a shell glob pattern // Actually, if there is only a trailing slash, // git also treats it as a shell glob pattern // After 2.22.1 (compatible but clearer) // > If there is a separator at the beginning or middle (or both) // > of the pattern, then the pattern is relative to the directory // > level of the particular .gitignore file itself. // > Otherwise the pattern may also match at any level below // > the .gitignore level. ? '(?:^|\\/)' // > Otherwise, Git treats the pattern as a shell glob suitable for // > consumption by fnmatch(3) : '^'; }], // two globstars [ // Use lookahead assertions so that we could match more than one `'/**'` /\\\/\\\*\\\*(?=\\\/|$)/g, // Zero, one or several directories // should not use '*', or it will be replaced by the next replacer // Check if it is not the last `'/**'` (_, index, str) => index + 6 < str.length // case: /**/ // > A slash followed by two consecutive asterisks then a slash matches // > zero or more directories. // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on. // '/**/' ? '(?:\\/[^\\/]+)*' // case: /** // > A trailing `"/**"` matches everything inside. // #21: everything inside but it should not include the current folder : '\\/.+'], // normal intermediate wildcards [ // Never replace escaped '*' // ignore rule '\*' will match the path '*' // 'abc.*/' -> go // 'abc.*' -> skip this rule, // coz trailing single wildcard will be handed by [trailing wildcard] /(^|[^\\]+)(\\\*)+(?=.+)/g, // '*.js' matches '.js' // '*.js' doesn't match 'abc' (_, p1, p2) => { // 1. // > An asterisk "*" matches anything except a slash. // 2. // > Other consecutive asterisks are considered regular asterisks // > and will match according to the previous rules. const unescaped = p2.replace(/\\\*/g, '[^\\/]*'); return p1 + unescaped; }], [ // unescape, revert step 3 except for back slash // For example, if a user escape a '\\*', // after step 3, the result will be '\\\\\\*' /\\\\\\(?=[$.|*+(){^])/g, () => ESCAPE], [ // '\\\\' -> '\\' /\\\\/g, () => ESCAPE], [ // > The range notation, e.g. [a-zA-Z], // > can be used to match one of the characters in a range. // `\` is escaped by step 3 /(\\)?\[([^\]/]*?)(\\*)($|\])/g, (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE // '\\[bar]' -> '\\\\[bar\\]' ? `\\[${range}${cleanRangeBackSlash(endEscape)}${close}` : close === ']' ? endEscape.length % 2 === 0 // A normal case, and it is a range notation // '[bar]' // '[bar\\\\]' ? `[${sanitizeRange(range)}${endEscape}]` // Invalid range notaton // '[bar\\]' -> '[bar\\\\]' : '[]' : '[]'], // ending [ // 'js' will not match 'js.' // 'ab' will not match 'abc' /(?:[^*])$/, // WTF! // https://git-scm.com/docs/gitignore // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1) // which re-fixes #24, #38 // > If there is a separator at the end of the pattern then the pattern // > will only match directories, otherwise the pattern can match both // > files and directories. // 'js*' will not match 'a.js' // 'js/' will not match 'a.js' // 'js' will match 'a.js' and 'a.js/' match => /\/$/.test(match) // foo/ will not match 'foo' ? `${match}$` // foo matches 'foo' and 'foo/' : `${match}(?=$|\\/$)`], // trailing wildcard [/(\^|\\\/)?\\\*$/, (_, p1) => { const prefix = p1 // '\^': // '/*' does not match EMPTY // '/*' does not match everything // '\\\/': // 'abc/*' does not match 'abc/' ? `${p1}[^/]+` // 'a*' matches 'a' // 'a*' matches 'aa' : '[^/]*'; return `${prefix}(?=$|\\/$)`; }]]; // A simple cache, because an ignore rule only has only one certain meaning const regexCache = Object.create(null); // @param {pattern} const makeRegex = (pattern, ignoreCase) => { let source = regexCache[pattern]; if (!source) { source = REPLACERS.reduce((prev, current) => prev.replace(current[0], current[1].bind(pattern)), pattern); regexCache[pattern] = source; } return ignoreCase ? new RegExp(source, 'i') : new RegExp(source); }; const isString = subject => typeof subject === 'string'; // > A blank line matches no files, so it can serve as a separator for readability. const checkPattern = pattern => pattern && isString(pattern) && !REGEX_TEST_BLANK_LINE.test(pattern) && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern) // > A line starting with # serves as a comment. && pattern.indexOf('#') !== 0; const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF); class IgnoreRule { constructor(origin, pattern, negative, regex) { this.origin = origin; this.pattern = pattern; this.negative = negative; this.regex = regex; } } const createRule = (pattern, ignoreCase) => { const origin = pattern; let negative = false; // > An optional prefix "!" which negates the pattern; if (pattern.indexOf('!') === 0) { negative = true; pattern = pattern.substr(1); } pattern = pattern // > Put a backslash ("\") in front of the first "!" for patterns that // > begin with a literal "!", for example, `"\!important!.txt"`. .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!') // > Put a backslash ("\") in front of the first hash for patterns that // > begin with a hash. .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#'); const regex = makeRegex(pattern, ignoreCase); return new IgnoreRule(origin, pattern, negative, regex); }; const throwError = (message, Ctor) => { throw new Ctor(message); }; const checkPath = (path, originalPath, doThrow) => { if (!isString(path)) { return doThrow(`path must be a string, but got \`${originalPath}\``, TypeError); } // We don't know if we should ignore EMPTY, so throw if (!path) { return doThrow(`path must not be empty`, TypeError); } // Check if it is a relative path if (checkPath.isNotRelative(path)) { const r = '`path.relative()`d'; return doThrow(`path should be a ${r} string, but got "${originalPath}"`, RangeError); } return true; }; const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path); checkPath.isNotRelative = isNotRelative; checkPath.convert = p => p; class Ignore { constructor({ ignorecase = true, ignoreCase = ignorecase, allowRelativePaths = false } = {}) { define(this, KEY_IGNORE, true); this._rules = []; this._ignoreCase = ignoreCase; this._allowRelativePaths = allowRelativePaths; this._initCache(); } _initCache() { this._ignoreCache = Object.create(null); this._testCache = Object.create(null); } _addPattern(pattern) { // #32 if (pattern && pattern[KEY_IGNORE]) { this._rules = this._rules.concat(pattern._rules); this._added = true; return; } if (checkPattern(pattern)) { const rule = createRule(pattern, this._ignoreCase); this._added = true; this._rules.push(rule); } } // @param {Array | string | Ignore} pattern add(pattern) { this._added = false; makeArray(isString(pattern) ? splitPattern(pattern) : pattern).forEach(this._addPattern, this); // Some rules have just added to the ignore, // making the behavior changed. if (this._added) { this._initCache(); } return this; } // legacy addPattern(pattern) { return this.add(pattern); } // | ignored : unignored // negative | 0:0 | 0:1 | 1:0 | 1:1 // -------- | ------- | ------- | ------- | -------- // 0 | TEST | TEST | SKIP | X // 1 | TESTIF | SKIP | TEST | X // - SKIP: always skip // - TEST: always test // - TESTIF: only test if checkUnignored // - X: that never happen // @param {boolean} whether should check if the path is unignored, // setting `checkUnignored` to `false` could reduce additional // path matching. // @returns {TestResult} true if a file is ignored _testOne(path, checkUnignored) { let ignored = false; let unignored = false; this._rules.forEach(rule => { const { negative } = rule; if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) { return; } const matched = rule.regex.test(path); if (matched) { ignored = !negative; unignored = negative; } }); return { ignored, unignored }; } // @returns {TestResult} _test(originalPath, cache, checkUnignored, slices) { const path = originalPath // Supports nullable path && checkPath.convert(originalPath); checkPath(path, originalPath, this._allowRelativePaths ? RETURN_FALSE : throwError); return this._t(path, cache, checkUnignored, slices); } _t(path, cache, checkUnignored, slices) { if (path in cache) { return cache[path]; } if (!slices) { // path/to/a.js // ['path', 'to', 'a.js'] slices = path.split(SLASH); } slices.pop(); // If the path has no parent directory, just test it if (!slices.length) { return cache[path] = this._testOne(path, checkUnignored); } const parent = this._t(slices.join(SLASH) + SLASH, cache, checkUnignored, slices); // If the path contains a parent directory, check the parent first return cache[path] = parent.ignored // > It is not possible to re-include a file if a parent directory of // > that file is excluded. ? parent : this._testOne(path, checkUnignored); } ignores(path) { return this._test(path, this._ignoreCache, false).ignored; } createFilter() { return path => !this.ignores(path); } filter(paths) { return makeArray(paths).filter(this.createFilter()); } // @returns {TestResult} test(path) { return this._test(path, this._testCache, true); } } const factory = options => new Ignore(options); const isPathValid = path => checkPath(path && checkPath.convert(path), path, RETURN_FALSE); factory.isPathValid = isPathValid; // Fixes typescript factory.default = factory; var ignore = factory; // Windows // -------------------------------------------------------------- /* istanbul ignore if */ if ( // Detect `process` so that it can run in browsers. typeof process !== 'undefined' && (process.env && process.env.IGNORE_TEST_WIN32 || process.platform === 'win32')) { /* eslint no-control-regex: "off" */ const makePosix = str => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, '/'); checkPath.convert = makePosix; // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' // 'd:\\foo' const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i; checkPath.isNotRelative = path => REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) || isNotRelative(path); } var gitIgnore = /*@__PURE__*/getDefaultExportFromCjs(ignore); function slash(path) { const isExtendedLengthPath = /^\\\\\?\\/.test(path); const hasNonAscii = /[^\u0000-\u0080]+/.test(path); // eslint-disable-line no-control-regex if (isExtendedLengthPath || hasNonAscii) { return path; } return path.replace(/\\/g, '/'); } const toPath = urlOrPath => urlOrPath instanceof URL ? node_url.fileURLToPath(urlOrPath) : urlOrPath; const isNegativePattern = pattern => pattern[0] === '!'; const ignoreFilesGlobOptions = { ignore: ['**/node_modules', '**/flow-typed', '**/coverage', '**/.git'], absolute: true, dot: true }; const GITIGNORE_FILES_PATTERN = '**/.gitignore'; const applyBaseToPattern = (pattern, base) => isNegativePattern(pattern) ? '!' + path$d.posix.join(base, pattern.slice(1)) : path$d.posix.join(base, pattern); const parseIgnoreFile = (file, cwd) => { const base = slash(path$d.relative(cwd, path$d.dirname(file.filePath))); return file.content.split(/\r?\n/).filter(line => line && !line.startsWith('#')).map(pattern => applyBaseToPattern(pattern, base)); }; const toRelativePath = (fileOrDirectory, cwd) => { cwd = slash(cwd); if (path$d.isAbsolute(fileOrDirectory)) { if (slash(fileOrDirectory).startsWith(cwd)) { return path$d.relative(cwd, fileOrDirectory); } throw new Error(`Path ${fileOrDirectory} is not in cwd ${cwd}`); } return fileOrDirectory; }; const getIsIgnoredPredicate = (files, cwd) => { const patterns = files.flatMap(file => parseIgnoreFile(file, cwd)); const ignores = gitIgnore().add(patterns); return fileOrDirectory => { fileOrDirectory = toPath(fileOrDirectory); fileOrDirectory = toRelativePath(fileOrDirectory, cwd); return fileOrDirectory ? ignores.ignores(slash(fileOrDirectory)) : false; }; }; const normalizeOptions$1 = (options = {}) => ({ cwd: toPath(options.cwd) || process$1.cwd(), suppressErrors: Boolean(options.suppressErrors), deep: typeof options.deep === 'number' ? options.deep : Number.POSITIVE_INFINITY }); const isIgnoredByIgnoreFilesSync = (patterns, options) => { const { cwd, suppressErrors, deep } = normalizeOptions$1(options); const paths = fastGlob.sync(patterns, { cwd, suppressErrors, deep, ...ignoreFilesGlobOptions }); const files = paths.map(filePath => ({ filePath, content: fs$c.readFileSync(filePath, 'utf8') })); return getIsIgnoredPredicate(files, cwd); }; const assertPatternsInput = patterns => { if (patterns.some(pattern => typeof pattern !== 'string')) { throw new TypeError('Patterns must be a string or an array of strings'); } }; const toPatternsArray = patterns => { patterns = [...new Set([patterns].flat())]; assertPatternsInput(patterns); return patterns; }; const checkCwdOption = options => { if (!options.cwd) { return; } let stat; try { stat = fs$c.statSync(options.cwd); } catch { return; } if (!stat.isDirectory()) { throw new Error('The `cwd` option must be a path to a directory'); } }; const normalizeOptions = (options = {}) => { options = { ...options, ignore: options.ignore || [], expandDirectories: options.expandDirectories === undefined ? true : options.expandDirectories, cwd: toPath(options.cwd) }; checkCwdOption(options); return options; }; const normalizeArgumentsSync = fn => (patterns, options) => fn(toPatternsArray(patterns), normalizeOptions(options)); const getIgnoreFilesPatterns = options => { const { ignoreFiles, gitignore } = options; const patterns = ignoreFiles ? toPatternsArray(ignoreFiles) : []; if (gitignore) { patterns.push(GITIGNORE_FILES_PATTERN); } return patterns; }; const getFilterSync = options => { const ignoreFilesPatterns = getIgnoreFilesPatterns(options); return createFilterFunction(ignoreFilesPatterns.length > 0 && isIgnoredByIgnoreFilesSync(ignoreFilesPatterns, options)); }; const createFilterFunction = isIgnored => { const seen = new Set(); return fastGlobResult => { const path = fastGlobResult.path || fastGlobResult; const pathKey = path$d.normalize(path); const seenOrIgnored = seen.has(pathKey) || isIgnored && isIgnored(path); seen.add(pathKey); return !seenOrIgnored; }; }; const unionFastGlobResults = (results, filter) => results.flat().filter(fastGlobResult => filter(fastGlobResult)); const convertNegativePatterns = (patterns, options) => { const tasks = []; while (patterns.length > 0) { const index = patterns.findIndex(pattern => isNegativePattern(pattern)); if (index === -1) { tasks.push({ patterns, options }); break; } const ignorePattern = patterns[index].slice(1); for (const task of tasks) { task.options.ignore.push(ignorePattern); } if (index !== 0) { tasks.push({ patterns: patterns.slice(0, index), options: { ...options, ignore: [...options.ignore, ignorePattern] } }); } patterns = patterns.slice(index + 1); } return tasks; }; const getDirGlobOptions = (options, cwd) => ({ ...(cwd ? { cwd } : {}), ...(Array.isArray(options) ? { files: options } : options) }); const generateTasksSync = (patterns, options) => { const globTasks = convertNegativePatterns(patterns, options); const { cwd, expandDirectories } = options; if (!expandDirectories) { return globTasks; } const patternExpandOptions = getDirGlobOptions(expandDirectories, cwd); const ignoreExpandOptions = cwd ? { cwd } : undefined; return globTasks.map(task => { let { patterns, options } = task; patterns = dirGlob.sync(patterns, patternExpandOptions); options.ignore = dirGlob.sync(options.ignore, ignoreExpandOptions); return { patterns, options }; }); }; const globbySync = normalizeArgumentsSync((patterns, options) => { const tasks = generateTasksSync(patterns, options); const filter = getFilterSync(options); const results = tasks.map(task => fastGlob.sync(task.patterns, task.options)); return unionFastGlobResults(results, filter); }); var constants = require$$0$3; var origCwd = process.cwd; var cwd = null; var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform; process.cwd = function () { if (!cwd) cwd = origCwd.call(process); return cwd; }; try { process.cwd(); } catch (er) {} // This check is needed until node.js 12 is required if (typeof process.chdir === 'function') { var chdir = process.chdir; process.chdir = function (d) { cwd = null; chdir.call(process, d); }; if (Object.setPrototypeOf) Object.setPrototypeOf(process.chdir, chdir); } var polyfills$1 = patch$1; function patch$1(fs) { // (re-)implement some things that are known busted or missing. // lchmod, broken prior to 0.6.2 // back-port the fix here. if (constants.hasOwnProperty('O_SYMLINK') && process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { patchLchmod(fs); } // lutimes implementation, or no-op if (!fs.lutimes) { patchLutimes(fs); } // https://github.com/isaacs/node-graceful-fs/issues/4 // Chown should not fail on einval or eperm if non-root. // It should not fail on enosys ever, as this just indicates // that a fs doesn't support the intended operation. fs.chown = chownFix(fs.chown); fs.fchown = chownFix(fs.fchown); fs.lchown = chownFix(fs.lchown); fs.chmod = chmodFix(fs.chmod); fs.fchmod = chmodFix(fs.fchmod); fs.lchmod = chmodFix(fs.lchmod); fs.chownSync = chownFixSync(fs.chownSync); fs.fchownSync = chownFixSync(fs.fchownSync); fs.lchownSync = chownFixSync(fs.lchownSync); fs.chmodSync = chmodFixSync(fs.chmodSync); fs.fchmodSync = chmodFixSync(fs.fchmodSync); fs.lchmodSync = chmodFixSync(fs.lchmodSync); fs.stat = statFix(fs.stat); fs.fstat = statFix(fs.fstat); fs.lstat = statFix(fs.lstat); fs.statSync = statFixSync(fs.statSync); fs.fstatSync = statFixSync(fs.fstatSync); fs.lstatSync = statFixSync(fs.lstatSync); // if lchmod/lchown do not exist, then make them no-ops if (fs.chmod && !fs.lchmod) { fs.lchmod = function (path, mode, cb) { if (cb) process.nextTick(cb); }; fs.lchmodSync = function () {}; } if (fs.chown && !fs.lchown) { fs.lchown = function (path, uid, gid, cb) { if (cb) process.nextTick(cb); }; fs.lchownSync = function () {}; } // on Windows, A/V software can lock the directory, causing this // to fail with an EACCES or EPERM if the directory contains newly // created files. Try again on failure, for up to 60 seconds. // Set the timeout this long because some Windows Anti-Virus, such as Parity // bit9, may lock files for up to a minute, causing npm package install // failures. Also, take care to yield the scheduler. Windows scheduling gives // CPU to a busy looping process, which can cause the program causing the lock // contention to be starved of CPU by node, so the contention doesn't resolve. if (platform === "win32") { fs.rename = typeof fs.rename !== 'function' ? fs.rename : function (fs$rename) { function rename(from, to, cb) { var start = Date.now(); var backoff = 0; fs$rename(from, to, function CB(er) { if (er && (er.code === "EACCES" || er.code === "EPERM" || er.code === "EBUSY") && Date.now() - start < 60000) { setTimeout(function () { fs.stat(to, function (stater, st) { if (stater && stater.code === "ENOENT") fs$rename(from, to, CB);else cb(er); }); }, backoff); if (backoff < 100) backoff += 10; return; } if (cb) cb(er); }); } if (Object.setPrototypeOf) Object.setPrototypeOf(rename, fs$rename); return rename; }(fs.rename); } // if read() returns EAGAIN, then just try it again. fs.read = typeof fs.read !== 'function' ? fs.read : function (fs$read) { function read(fd, buffer, offset, length, position, callback_) { var callback; if (callback_ && typeof callback_ === 'function') { var eagCounter = 0; callback = function (er, _, __) { if (er && er.code === 'EAGAIN' && eagCounter < 10) { eagCounter++; return fs$read.call(fs, fd, buffer, offset, length, position, callback); } callback_.apply(this, arguments); }; } return fs$read.call(fs, fd, buffer, offset, length, position, callback); } // This ensures `util.promisify` works as it does for native `fs.read`. if (Object.setPrototypeOf) Object.setPrototypeOf(read, fs$read); return read; }(fs.read); fs.readSync = typeof fs.readSync !== 'function' ? fs.readSync : function (fs$readSync) { return function (fd, buffer, offset, length, position) { var eagCounter = 0; while (true) { try { return fs$readSync.call(fs, fd, buffer, offset, length, position); } catch (er) { if (er.code === 'EAGAIN' && eagCounter < 10) { eagCounter++; continue; } throw er; } } }; }(fs.readSync); function patchLchmod(fs) { fs.lchmod = function (path, mode, callback) { fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, mode, function (err, fd) { if (err) { if (callback) callback(err); return; } // prefer to return the chmod error, if one occurs, // but still try to close, and report closing errors if they occur. fs.fchmod(fd, mode, function (err) { fs.close(fd, function (err2) { if (callback) callback(err || err2); }); }); }); }; fs.lchmodSync = function (path, mode) { var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode); // prefer to return the chmod error, if one occurs, // but still try to close, and report closing errors if they occur. var threw = true; var ret; try { ret = fs.fchmodSync(fd, mode); threw = false; } finally { if (threw) { try { fs.closeSync(fd); } catch (er) {} } else { fs.closeSync(fd); } } return ret; }; } function patchLutimes(fs) { if (constants.hasOwnProperty("O_SYMLINK") && fs.futimes) { fs.lutimes = function (path, at, mt, cb) { fs.open(path, constants.O_SYMLINK, function (er, fd) { if (er) { if (cb) cb(er); return; } fs.futimes(fd, at, mt, function (er) { fs.close(fd, function (er2) { if (cb) cb(er || er2); }); }); }); }; fs.lutimesSync = function (path, at, mt) { var fd = fs.openSync(path, constants.O_SYMLINK); var ret; var threw = true; try { ret = fs.futimesSync(fd, at, mt); threw = false; } finally { if (threw) { try { fs.closeSync(fd); } catch (er) {} } else { fs.closeSync(fd); } } return ret; }; } else if (fs.futimes) { fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb); }; fs.lutimesSync = function () {}; } } function chmodFix(orig) { if (!orig) return orig; return function (target, mode, cb) { return orig.call(fs, target, mode, function (er) { if (chownErOk(er)) er = null; if (cb) cb.apply(this, arguments); }); }; } function chmodFixSync(orig) { if (!orig) return orig; return function (target, mode) { try { return orig.call(fs, target, mode); } catch (er) { if (!chownErOk(er)) throw er; } }; } function chownFix(orig) { if (!orig) return orig; return function (target, uid, gid, cb) { return orig.call(fs, target, uid, gid, function (er) { if (chownErOk(er)) er = null; if (cb) cb.apply(this, arguments); }); }; } function chownFixSync(orig) { if (!orig) return orig; return function (target, uid, gid) { try { return orig.call(fs, target, uid, gid); } catch (er) { if (!chownErOk(er)) throw er; } }; } function statFix(orig) { if (!orig) return orig; // Older versions of Node erroneously returned signed integers for // uid + gid. return function (target, options, cb) { if (typeof options === 'function') { cb = options; options = null; } function callback(er, stats) { if (stats) { if (stats.uid < 0) stats.uid += 0x100000000; if (stats.gid < 0) stats.gid += 0x100000000; } if (cb) cb.apply(this, arguments); } return options ? orig.call(fs, target, options, callback) : orig.call(fs, target, callback); }; } function statFixSync(orig) { if (!orig) return orig; // Older versions of Node erroneously returned signed integers for // uid + gid. return function (target, options) { var stats = options ? orig.call(fs, target, options) : orig.call(fs, target); if (stats) { if (stats.uid < 0) stats.uid += 0x100000000; if (stats.gid < 0) stats.gid += 0x100000000; } return stats; }; } // ENOSYS means that the fs doesn't support the op. Just ignore // that, because it doesn't matter. // // if there's no getuid, or if getuid() is something other // than 0, and the error is EINVAL or EPERM, then just ignore // it. // // This specific case is a silent failure in cp, install, tar, // and most other unix tools that manage permissions. // // When running as root, or if other types of errors are // encountered, then it's strict. function chownErOk(er) { if (!er) return true; if (er.code === "ENOSYS") return true; var nonroot = !process.getuid || process.getuid() !== 0; if (nonroot) { if (er.code === "EINVAL" || er.code === "EPERM") return true; } return false; } } var Stream = require$$0.Stream; var legacyStreams = legacy$1; function legacy$1(fs) { return { ReadStream: ReadStream, WriteStream: WriteStream }; function ReadStream(path, options) { if (!(this instanceof ReadStream)) return new ReadStream(path, options); Stream.call(this); var self = this; this.path = path; this.fd = null; this.readable = true; this.paused = false; this.flags = 'r'; this.mode = 438; /*=0666*/ this.bufferSize = 64 * 1024; options = options || {}; // Mixin options into this var keys = Object.keys(options); for (var index = 0, length = keys.length; index < length; index++) { var key = keys[index]; this[key] = options[key]; } if (this.encoding) this.setEncoding(this.encoding); if (this.start !== undefined) { if ('number' !== typeof this.start) { throw TypeError('start must be a Number'); } if (this.end === undefined) { this.end = Infinity; } else if ('number' !== typeof this.end) { throw TypeError('end must be a Number'); } if (this.start > this.end) { throw new Error('start must be <= end'); } this.pos = this.start; } if (this.fd !== null) { process.nextTick(function () { self._read(); }); return; } fs.open(this.path, this.flags, this.mode, function (err, fd) { if (err) { self.emit('error', err); self.readable = false; return; } self.fd = fd; self.emit('open', fd); self._read(); }); } function WriteStream(path, options) { if (!(this instanceof WriteStream)) return new WriteStream(path, options); Stream.call(this); this.path = path; this.fd = null; this.writable = true; this.flags = 'w'; this.encoding = 'binary'; this.mode = 438; /*=0666*/ this.bytesWritten = 0; options = options || {}; // Mixin options into this var keys = Object.keys(options); for (var index = 0, length = keys.length; index < length; index++) { var key = keys[index]; this[key] = options[key]; } if (this.start !== undefined) { if ('number' !== typeof this.start) { throw TypeError('start must be a Number'); } if (this.start < 0) { throw new Error('start must be >= zero'); } this.pos = this.start; } this.busy = false; this._queue = []; if (this.fd === null) { this._open = fs.open; this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); this.flush(); } } } var clone_1 = clone$1; var getPrototypeOf = Object.getPrototypeOf || function (obj) { return obj.__proto__; }; function clone$1(obj) { if (obj === null || typeof obj !== 'object') return obj; if (obj instanceof Object) var copy = { __proto__: getPrototypeOf(obj) };else var copy = Object.create(null); Object.getOwnPropertyNames(obj).forEach(function (key) { Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)); }); return copy; } var fs$1 = fs$b; var polyfills = polyfills$1; var legacy = legacyStreams; var clone = clone_1; var util = require$$0$1; /* istanbul ignore next - node 0.x polyfill */ var gracefulQueue; var previousSymbol; /* istanbul ignore else - node 0.x polyfill */ if (typeof Symbol === 'function' && typeof Symbol.for === 'function') { gracefulQueue = Symbol.for('graceful-fs.queue'); // This is used in testing by future versions previousSymbol = Symbol.for('graceful-fs.previous'); } else { gracefulQueue = '___graceful-fs.queue'; previousSymbol = '___graceful-fs.previous'; } function noop() {} function publishQueue(context, queue) { Object.defineProperty(context, gracefulQueue, { get: function () { return queue; } }); } var debug = noop; if (util.debuglog) debug = util.debuglog('gfs4');else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) debug = function () { var m = util.format.apply(util, arguments); m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: '); console.error(m); }; // Once time initialization if (!fs$1[gracefulQueue]) { // This queue can be shared by multiple loaded instances var queue = commonjsGlobal[gracefulQueue] || []; publishQueue(fs$1, queue); // Patch fs.close/closeSync to shared queue version, because we need // to retry() whenever a close happens *anywhere* in the program. // This is essential when multiple graceful-fs instances are // in play at the same time. fs$1.close = function (fs$close) { function close(fd, cb) { return fs$close.call(fs$1, fd, function (err) { // This function uses the graceful-fs shared queue if (!err) { resetQueue(); } if (typeof cb === 'function') cb.apply(this, arguments); }); } Object.defineProperty(close, previousSymbol, { value: fs$close }); return close; }(fs$1.close); fs$1.closeSync = function (fs$closeSync) { function closeSync(fd) { // This function uses the graceful-fs shared queue fs$closeSync.apply(fs$1, arguments); resetQueue(); } Object.defineProperty(closeSync, previousSymbol, { value: fs$closeSync }); return closeSync; }(fs$1.closeSync); if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { process.on('exit', function () { debug(fs$1[gracefulQueue]); require$$5.equal(fs$1[gracefulQueue].length, 0); }); } } if (!commonjsGlobal[gracefulQueue]) { publishQueue(commonjsGlobal, fs$1[gracefulQueue]); } var gracefulFs = patch(clone(fs$1)); if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs$1.__patched) { gracefulFs = patch(fs$1); fs$1.__patched = true; } function patch(fs) { // Everything that references the open() function needs to be in here polyfills(fs); fs.gracefulify = patch; fs.createReadStream = createReadStream; fs.createWriteStream = createWriteStream; var fs$readFile = fs.readFile; fs.readFile = readFile; function readFile(path, options, cb) { if (typeof options === 'function') cb = options, options = null; return go$readFile(path, options, cb); function go$readFile(path, options, cb, startTime) { return fs$readFile(path, options, function (err) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$readFile, [path, options, cb], err, startTime || Date.now(), Date.now()]);else { if (typeof cb === 'function') cb.apply(this, arguments); } }); } } var fs$writeFile = fs.writeFile; fs.writeFile = writeFile; function writeFile(path, data, options, cb) { if (typeof options === 'function') cb = options, options = null; return go$writeFile(path, data, options, cb); function go$writeFile(path, data, options, cb, startTime) { return fs$writeFile(path, data, options, function (err) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$writeFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()]);else { if (typeof cb === 'function') cb.apply(this, arguments); } }); } } var fs$appendFile = fs.appendFile; if (fs$appendFile) fs.appendFile = appendFile; function appendFile(path, data, options, cb) { if (typeof options === 'function') cb = options, options = null; return go$appendFile(path, data, options, cb); function go$appendFile(path, data, options, cb, startTime) { return fs$appendFile(path, data, options, function (err) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$appendFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()]);else { if (typeof cb === 'function') cb.apply(this, arguments); } }); } } var fs$copyFile = fs.copyFile; if (fs$copyFile) fs.copyFile = copyFile; function copyFile(src, dest, flags, cb) { if (typeof flags === 'function') { cb = flags; flags = 0; } return go$copyFile(src, dest, flags, cb); function go$copyFile(src, dest, flags, cb, startTime) { return fs$copyFile(src, dest, flags, function (err) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$copyFile, [src, dest, flags, cb], err, startTime || Date.now(), Date.now()]);else { if (typeof cb === 'function') cb.apply(this, arguments); } }); } } var fs$readdir = fs.readdir; fs.readdir = readdir; var noReaddirOptionVersions = /^v[0-5]\./; function readdir(path, options, cb) { if (typeof options === 'function') cb = options, options = null; var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir(path, options, cb, startTime) { return fs$readdir(path, fs$readdirCallback(path, options, cb, startTime)); } : function go$readdir(path, options, cb, startTime) { return fs$readdir(path, options, fs$readdirCallback(path, options, cb, startTime)); }; return go$readdir(path, options, cb); function fs$readdirCallback(path, options, cb, startTime) { return function (err, files) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$readdir, [path, options, cb], err, startTime || Date.now(), Date.now()]);else { if (files && files.sort) files.sort(); if (typeof cb === 'function') cb.call(this, err, files); } }; } } if (process.version.substr(0, 4) === 'v0.8') { var legStreams = legacy(fs); ReadStream = legStreams.ReadStream; WriteStream = legStreams.WriteStream; } var fs$ReadStream = fs.ReadStream; if (fs$ReadStream) { ReadStream.prototype = Object.create(fs$ReadStream.prototype); ReadStream.prototype.open = ReadStream$open; } var fs$WriteStream = fs.WriteStream; if (fs$WriteStream) { WriteStream.prototype = Object.create(fs$WriteStream.prototype); WriteStream.prototype.open = WriteStream$open; } Object.defineProperty(fs, 'ReadStream', { get: function () { return ReadStream; }, set: function (val) { ReadStream = val; }, enumerable: true, configurable: true }); Object.defineProperty(fs, 'WriteStream', { get: function () { return WriteStream; }, set: function (val) { WriteStream = val; }, enumerable: true, configurable: true }); // legacy names var FileReadStream = ReadStream; Object.defineProperty(fs, 'FileReadStream', { get: function () { return FileReadStream; }, set: function (val) { FileReadStream = val; }, enumerable: true, configurable: true }); var FileWriteStream = WriteStream; Object.defineProperty(fs, 'FileWriteStream', { get: function () { return FileWriteStream; }, set: function (val) { FileWriteStream = val; }, enumerable: true, configurable: true }); function ReadStream(path, options) { if (this instanceof ReadStream) return fs$ReadStream.apply(this, arguments), this;else return ReadStream.apply(Object.create(ReadStream.prototype), arguments); } function ReadStream$open() { var that = this; open(that.path, that.flags, that.mode, function (err, fd) { if (err) { if (that.autoClose) that.destroy(); that.emit('error', err); } else { that.fd = fd; that.emit('open', fd); that.read(); } }); } function WriteStream(path, options) { if (this instanceof WriteStream) return fs$WriteStream.apply(this, arguments), this;else return WriteStream.apply(Object.create(WriteStream.prototype), arguments); } function WriteStream$open() { var that = this; open(that.path, that.flags, that.mode, function (err, fd) { if (err) { that.destroy(); that.emit('error', err); } else { that.fd = fd; that.emit('open', fd); } }); } function createReadStream(path, options) { return new fs.ReadStream(path, options); } function createWriteStream(path, options) { return new fs.WriteStream(path, options); } var fs$open = fs.open; fs.open = open; function open(path, flags, mode, cb) { if (typeof mode === 'function') cb = mode, mode = null; return go$open(path, flags, mode, cb); function go$open(path, flags, mode, cb, startTime) { return fs$open(path, flags, mode, function (err, fd) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$open, [path, flags, mode, cb], err, startTime || Date.now(), Date.now()]);else { if (typeof cb === 'function') cb.apply(this, arguments); } }); } } return fs; } function enqueue(elem) { debug('ENQUEUE', elem[0].name, elem[1]); fs$1[gracefulQueue].push(elem); retry(); } // keep track of the timeout between retry() calls var retryTimer; // reset the startTime and lastTime to now // this resets the start of the 60 second overall timeout as well as the // delay between attempts so that we'll retry these jobs sooner function resetQueue() { var now = Date.now(); for (var i = 0; i < fs$1[gracefulQueue].length; ++i) { // entries that are only a length of 2 are from an older version, don't // bother modifying those since they'll be retried anyway. if (fs$1[gracefulQueue][i].length > 2) { fs$1[gracefulQueue][i][3] = now; // startTime fs$1[gracefulQueue][i][4] = now; // lastTime } } // call retry to make sure we're actively processing the queue retry(); } function retry() { // clear the timer and remove it to help prevent unintended concurrency clearTimeout(retryTimer); retryTimer = undefined; if (fs$1[gracefulQueue].length === 0) return; var elem = fs$1[gracefulQueue].shift(); var fn = elem[0]; var args = elem[1]; // these items may be unset if they were added by an older graceful-fs var err = elem[2]; var startTime = elem[3]; var lastTime = elem[4]; // if we don't have a startTime we have no way of knowing if we've waited // long enough, so go ahead and retry this item now if (startTime === undefined) { debug('RETRY', fn.name, args); fn.apply(null, args); } else if (Date.now() - startTime >= 60000) { // it's been more than 60 seconds total, bail now debug('TIMEOUT', fn.name, args); var cb = args.pop(); if (typeof cb === 'function') cb.call(null, err); } else { // the amount of time between the last attempt and right now var sinceAttempt = Date.now() - lastTime; // the amount of time between when we first tried, and when we last tried // rounded up to at least 1 var sinceStart = Math.max(lastTime - startTime, 1); // backoff. wait longer than the total time we've been retrying, but only // up to a maximum of 100ms var desiredDelay = Math.min(sinceStart * 1.2, 100); // it's been long enough since the last retry, do it again if (sinceAttempt >= desiredDelay) { debug('RETRY', fn.name, args); fn.apply(null, args.concat([startTime])); } else { // if we can't do this job yet, push it to the end of the queue // and let the next iteration check again fs$1[gracefulQueue].push(elem); } } // schedule our next run if one isn't already scheduled if (retryTimer === undefined) { retryTimer = setTimeout(retry, 0); } } var gracefulFs$1 = /*@__PURE__*/getDefaultExportFromCjs(gracefulFs); function isPathCwd(path_) { let cwd = process$1.cwd(); path_ = path$d.resolve(path_); if (process$1.platform === 'win32') { cwd = cwd.toLowerCase(); path_ = path_.toLowerCase(); } return path_ === cwd; } function isPathInside(childPath, parentPath) { const relation = path$d.relative(parentPath, childPath); return Boolean(relation && relation !== '..' && !relation.startsWith(`..${path$d.sep}`) && relation !== path$d.resolve(childPath)); } const assert = require$$5; const path = path$c; const fs = fs$b; let glob = undefined; try { glob = require("glob"); } catch (_err) { // treat glob as optional. } const defaultGlobOpts = { nosort: true, silent: true }; // for EMFILE handling let timeout = 0; const isWindows = process.platform === "win32"; const defaults = options => { const methods = ['unlink', 'chmod', 'stat', 'lstat', 'rmdir', 'readdir']; methods.forEach(m => { options[m] = options[m] || fs[m]; m = m + 'Sync'; options[m] = options[m] || fs[m]; }); options.maxBusyTries = options.maxBusyTries || 3; options.emfileWait = options.emfileWait || 1000; if (options.glob === false) { options.disableGlob = true; } if (options.disableGlob !== true && glob === undefined) { throw Error('glob dependency not found, set `options.disableGlob = true` if intentional'); } options.disableGlob = options.disableGlob || false; options.glob = options.glob || defaultGlobOpts; }; const rimraf = (p, options, cb) => { if (typeof options === 'function') { cb = options; options = {}; } assert(p, 'rimraf: missing path'); assert.equal(typeof p, 'string', 'rimraf: path should be a string'); assert.equal(typeof cb, 'function', 'rimraf: callback function required'); assert(options, 'rimraf: invalid options argument provided'); assert.equal(typeof options, 'object', 'rimraf: options should be object'); defaults(options); let busyTries = 0; let errState = null; let n = 0; const next = er => { errState = errState || er; if (--n === 0) cb(errState); }; const afterGlob = (er, results) => { if (er) return cb(er); n = results.length; if (n === 0) return cb(); results.forEach(p => { const CB = er => { if (er) { if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && busyTries < options.maxBusyTries) { busyTries++; // try again, with the same exact callback as this one. return setTimeout(() => rimraf_(p, options, CB), busyTries * 100); } // this one won't happen if graceful-fs is used. if (er.code === "EMFILE" && timeout < options.emfileWait) { return setTimeout(() => rimraf_(p, options, CB), timeout++); } // already gone if (er.code === "ENOENT") er = null; } timeout = 0; next(er); }; rimraf_(p, options, CB); }); }; if (options.disableGlob || !glob.hasMagic(p)) return afterGlob(null, [p]); options.lstat(p, (er, stat) => { if (!er) return afterGlob(null, [p]); glob(p, options.glob, afterGlob); }); }; // Two possible strategies. // 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR // 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR // // Both result in an extra syscall when you guess wrong. However, there // are likely far more normal files in the world than directories. This // is based on the assumption that a the average number of files per // directory is >= 1. // // If anyone ever complains about this, then I guess the strategy could // be made configurable somehow. But until then, YAGNI. const rimraf_ = (p, options, cb) => { assert(p); assert(options); assert(typeof cb === 'function'); // sunos lets the root user unlink directories, which is... weird. // so we have to lstat here and make sure it's not a dir. options.lstat(p, (er, st) => { if (er && er.code === "ENOENT") return cb(null); // Windows can EPERM on stat. Life is suffering. if (er && er.code === "EPERM" && isWindows) fixWinEPERM(p, options, er, cb); if (st && st.isDirectory()) return rmdir(p, options, er, cb); options.unlink(p, er => { if (er) { if (er.code === "ENOENT") return cb(null); if (er.code === "EPERM") return isWindows ? fixWinEPERM(p, options, er, cb) : rmdir(p, options, er, cb); if (er.code === "EISDIR") return rmdir(p, options, er, cb); } return cb(er); }); }); }; const fixWinEPERM = (p, options, er, cb) => { assert(p); assert(options); assert(typeof cb === 'function'); options.chmod(p, 0o666, er2 => { if (er2) cb(er2.code === "ENOENT" ? null : er);else options.stat(p, (er3, stats) => { if (er3) cb(er3.code === "ENOENT" ? null : er);else if (stats.isDirectory()) rmdir(p, options, er, cb);else options.unlink(p, cb); }); }); }; const fixWinEPERMSync = (p, options, er) => { assert(p); assert(options); try { options.chmodSync(p, 0o666); } catch (er2) { if (er2.code === "ENOENT") return;else throw er; } let stats; try { stats = options.statSync(p); } catch (er3) { if (er3.code === "ENOENT") return;else throw er; } if (stats.isDirectory()) rmdirSync(p, options, er);else options.unlinkSync(p); }; const rmdir = (p, options, originalEr, cb) => { assert(p); assert(options); assert(typeof cb === 'function'); // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) // if we guessed wrong, and it's not a directory, then // raise the original error. options.rmdir(p, er => { if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) rmkids(p, options, cb);else if (er && er.code === "ENOTDIR") cb(originalEr);else cb(er); }); }; const rmkids = (p, options, cb) => { assert(p); assert(options); assert(typeof cb === 'function'); options.readdir(p, (er, files) => { if (er) return cb(er); let n = files.length; if (n === 0) return options.rmdir(p, cb); let errState; files.forEach(f => { rimraf(path.join(p, f), options, er => { if (errState) return; if (er) return cb(errState = er); if (--n === 0) options.rmdir(p, cb); }); }); }); }; // this looks simpler, and is strictly *faster*, but will // tie up the JavaScript thread and fail on excessively // deep directory trees. const rimrafSync = (p, options) => { options = options || {}; defaults(options); assert(p, 'rimraf: missing path'); assert.equal(typeof p, 'string', 'rimraf: path should be a string'); assert(options, 'rimraf: missing options'); assert.equal(typeof options, 'object', 'rimraf: options should be object'); let results; if (options.disableGlob || !glob.hasMagic(p)) { results = [p]; } else { try { options.lstatSync(p); results = [p]; } catch (er) { results = glob.sync(p, options.glob); } } if (!results.length) return; for (let i = 0; i < results.length; i++) { const p = results[i]; let st; try { st = options.lstatSync(p); } catch (er) { if (er.code === "ENOENT") return; // Windows can EPERM on stat. Life is suffering. if (er.code === "EPERM" && isWindows) fixWinEPERMSync(p, options, er); } try { // sunos lets the root user unlink directories, which is... weird. if (st && st.isDirectory()) rmdirSync(p, options, null);else options.unlinkSync(p); } catch (er) { if (er.code === "ENOENT") return; if (er.code === "EPERM") return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er); if (er.code !== "EISDIR") throw er; rmdirSync(p, options, er); } } }; const rmdirSync = (p, options, originalEr) => { assert(p); assert(options); try { options.rmdirSync(p); } catch (er) { if (er.code === "ENOENT") return; if (er.code === "ENOTDIR") throw originalEr; if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") rmkidsSync(p, options); } }; const rmkidsSync = (p, options) => { assert(p); assert(options); options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options)); // We only end up here once we got ENOTEMPTY at least once, and // at this point, we are guaranteed to have removed all the kids. // So, we know that it won't be ENOENT or ENOTDIR or anything else. // try really hard to delete stuff on windows, because it has a // PROFOUNDLY annoying habit of not closing handles promptly when // files are deleted, resulting in spurious ENOTEMPTY errors. const retries = isWindows ? 100 : 1; let i = 0; do { let threw = true; try { const ret = options.rmdirSync(p, options); threw = false; return ret; } finally { if (++i < retries && threw) continue; } } while (true); }; var rimraf_1 = rimraf; rimraf.sync = rimrafSync; var rimraf$1 = /*@__PURE__*/getDefaultExportFromCjs(rimraf_1); typeof os$1.homedir === 'undefined' ? '' : os$1.homedir().replace(/\\/g, '/'); node_util.promisify(rimraf$1); const rimrafOptions = { glob: false, unlink: gracefulFs$1.unlink, unlinkSync: gracefulFs$1.unlinkSync, chmod: gracefulFs$1.chmod, chmodSync: gracefulFs$1.chmodSync, stat: gracefulFs$1.stat, statSync: gracefulFs$1.statSync, lstat: gracefulFs$1.lstat, lstatSync: gracefulFs$1.lstatSync, rmdir: gracefulFs$1.rmdir, rmdirSync: gracefulFs$1.rmdirSync, readdir: gracefulFs$1.readdir, readdirSync: gracefulFs$1.readdirSync }; function safeCheck(file, cwd) { if (isPathCwd(file)) { throw new Error('Cannot delete the current working directory. Can be overridden with the `force` option.'); } if (!isPathInside(file, cwd)) { throw new Error('Cannot delete files/directories outside the current working directory. Can be overridden with the `force` option.'); } } function normalizePatterns(patterns) { patterns = Array.isArray(patterns) ? patterns : [patterns]; patterns = patterns.map(pattern => { if (process$1.platform === 'win32' && isGlob$2(pattern) === false) { return slash(pattern); } return pattern; }); return patterns; } function deleteSync(patterns, { force, dryRun, cwd = process$1.cwd(), ...options } = {}) { options = { expandDirectories: false, onlyFiles: false, followSymbolicLinks: false, cwd, ...options }; patterns = normalizePatterns(patterns); const files = globbySync(patterns, options).sort((a, b) => b.localeCompare(a)); const removedFiles = files.map(file => { file = path$d.resolve(cwd, file); if (!force) { safeCheck(file, cwd); } if (!dryRun) { rimraf$1.sync(file, rimrafOptions); } return file; }); removedFiles.sort((a, b) => a.localeCompare(b)); return removedFiles; } var clean = (options => { return done => { deleteSync(options.paths); done(); }; }); const defaultOptions = { name: 'hash-manifest.json', replace: false, versionPattern: '[name]?version=[hash]', formatter: name => name }; function md5(string) { return crypto.createHash('md5').update(string).digest('hex'); } function tryRequire(file) { try { return JSON.parse(fs$b.readFileSync(file, 'utf-8')); } catch (err) { if (err.code === 'ENOENT') return null; throw err; } } function mkdirPath(dest) { const dir = path$c.dirname(dest); try { fs$b.readdirSync(dir); } catch (err) { mkdirPath(dir); fs$b.mkdirSync(dir); } } function generateVersionString(versionPattern, name, hash) { return versionPattern.replace('[name]', name).replace('[hash]', hash); } function addToManifest(keyFilePath, valueFilePath, code, options) { const manifest = tryRequire(options.name) || {}; manifest[`${keyFilePath}`] = generateVersionString(options.versionPattern, valueFilePath, md5(code)); mkdirPath(options.name); fs$b.writeFileSync(options.name, JSON.stringify(manifest, null, 4), 'utf8'); } function hash$1 (options = {}) { options = { ...defaultOptions, ...options }; return through.obj((chunk, enc, cb) => { const chunkPath = chunk.path.replace(chunk.cwd + path$c.sep, ''); if (!chunkPath.includes('.map')) { const fileName = options.formatter(chunkPath.split(path$c.sep).join('/')); const code = chunk.contents; addToManifest(fileName, fileName, code, options); } cb(null, chunk); }); } var Config = { projectTitle: 'frontend-tasks', versionManifest: false }; var css = ((options = {}) => { options = { flatten: true, ...options }; return () => { return gulp.src(options.src).pipe(plumber({ errorHandler: function (error) { log.error(Config.projectTitle + ' - CSS Error', error.toString()); this.emit('end'); } })).pipe(sourcemaps.init()).pipe(postcss()).pipe(sourcemaps.write('.')).pipe(gulpIf(options.flatten, flatten$1())).pipe(gulp.dest(options.dest)).pipe(gulpIf(Config.versionManifest !== false, hash$1(Config.versionManifest))); }; }); const copyFiles = async (pattern, dest, flat = true) => { const files = await glob$1.glob(pattern, { nodir: flat }); files.forEach(file => { const destPath = path$c.join(dest, path$c.basename(file)); fs$d.copy(file, destPath, err => { if (err) { log.error(`Error copying ${file}:`, err); } }); }); }; var copy = (options => { return done => { options.paths.forEach(async path => { const { src, dest, flat } = path; if (!src || !dest) { throw new Error(`${JSON.stringify(path)} path must have "src" and "dest" properties`); } await copyFiles(src, dest, flat); }); done(); return true; }; }); function hash(options = {}) { options = { ...defaultOptions, ...options }; return { name: 'hash-version-manifest', generateBundle: function (outputOptions, bundle) { const filePath = options.formatter(outputOptions.dir.split(path$c.sep).join('/')); Object.entries(bundle).forEach(([key, chunk]) => { const fileExtension = chunk.fileName.split('.').pop(); const keyFileName = `${filePath}/${chunk.name}.${fileExtension}`; const valueFileName = `${filePath}/${chunk.fileName}`; if (chunk.isEntry && !valueFileName.includes('.map')) { addToManifest(keyFileName, valueFileName, chunk.code, options); } }); } }; } const isDev = environments.development; const isProd = environments.production; var rollupJS = (async (options = { inputOptions: {}, outputOptions: {}, babelOptions: {}, resolveOptions: {}, postcssOptions: {}, commonjsOptions: {}, cleanupOptions: {}, watchOptions: {} }) => { const inputOptions = { input: '', plugins: [pluginNodeResolve.nodeResolve({ ...options.resolveOptions }), postcss$1({ ...options.postcssOptions }), svg$1(), commonjs({ ...options.commonjsOptions }), pluginBabel.babel({ ...options.babelOptions }), Config.versionManifest !== false && hash(Config.versionManifest), isProd() && cleanup({ ...options.cleanupOptions }), isProd() && terser()], onwarn(warning, warn) { if (warning.code === 'UNRESOLVED_IMPORT') { const message = `'${warning.source}' is imported by ${warning.importer}, but could not be resolved. If this is an external dependency (https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency) - please add it to inputOptions.external (https://rollupjs.org/guide/en/#external)`; throw new Error(message); } // Use default for everything else warn(warning); }, ...options.inputOptions }; const outputOptions = { dir: 'public', entryFileNames: '[name].js', format: 'es', sourcemap: true, ...options.outputOptions }; if (isDev() && options.watchOptions !== false) { return new Promise(resolve => { const watcher = rollup.watch({ ...inputOptions, output: [outputOptions], watch: { ...options.watchOptions } }); watcher.on('event', event => { if (event.code === 'START') { log(Config.projectTitle, 'Starting "rollup"...'); } if (event.code === 'BUNDLE_END') { log(Config.projectTitle, 'END "rollup" after ' + (event.duration / 1000).toFixed(2) + ' s'); if (event.result) { event.result.close(); } } if (event.code === 'END') { resolve(); } if (event.code === 'ERROR' || event.code === 'FATAL') { log.error('rollup watch ERROR', event); } }); }); } else { const bundle = await rollup.rollup(inputOptions); return await bundle.write(outputOptions); } }); // TODO refactor to glob var js = ((options = { src: [], dest: '' }) => { return () => { return rollupJS({ inputOptions: { input: glob$2.sync(options.src), ...(options.inputOptions || {}) }, outputOptions: { dir: options.dest, ...(options.outputOptions || {}) }, babelOptions: options.babelOptions || {}, resolveOptions: options.resolveOptions || {}, postcssOptions: options.postcssOptions || {}, commonjsOptions: options.commonjsOptions || {}, cleanupOptions: options.cleanupOptions || {} }); }; }); var lintCSS = (options => { return () => { return gulp.src(options.src).pipe(postcss([stylelint])); }; }); var lintJS = (options => { return () => { return gulp.src(options.src).pipe(eslint({ configFile: options.configFile || '.eslintrc', useEslintrc: true })).pipe(eslint.format()).pipe(eslint.failAfterError()); }; }); const spawn = childProcess.spawn; var run = (options => { return cb => { const cmd = spawn(options.cmd, options.args, { stdio: 'inherit' }); cmd.on('close', function (code) { log(options.cmd + ' exited with code ' + code); cb(code); }); cmd.on('error', function (error) { log.error(options.cmd + ' errored with msg: ' + error); cb(error); }); }; }); const defaultConfig = { mode: { symbol: true }, dest: '.' }; const compileSvgSprite = (src, config = defaultConfig, cwdPath) => { const spriter = new SVGSprite(config); const cwd = cwdPath ? path$c.resolve(cwdPath) : process.cwd(); // Find SVG files recursively via `glob` const files = glob$1.glob.sync(src, { cwd }); files.forEach(file => { try { spriter.add(new File({ path: path$c.join(cwd, file), // Absolute path to the SVG file base: cwd, // Base path (see `name` argument) contents: fs$b.readFileSync(path$c.join(cwd, file)) // SVG file contents })); } catch (e) { console.error(e); } }); // Compile the sprite spriter.compile((error, result) => { /* Write `result` files to disk (or do whatever with them ...) */ for (const mode of Object.values(result)) { for (const resource of Object.values(mode)) { fs$b.mkdirSync(path$c.dirname(resource.path), { recursive: true }); fs$b.writeFileSync(resource.path, resource.contents); } } }); }; const svg = options => { return done => { options.paths.forEach(async path => { const { src, config, cwd } = path; if (!src) { throw new Error(`${JSON.stringify(path)} path must have "src" property`); } await compileSvgSprite(src, config, cwd); }); done(); return true; }; }; var watch = (options => { return () => { // notify({ title: Config.projectTitle, message: 'Watching for changes...' }).write(''); options.paths.forEach(path => { gulp.watch(path.src, path.tasks).on('change', function () { log.info(Config.projectTitle, path.changeMessage || 'Change'); }).on('error', function (error) { log.info(Config.projectTitle, path.errorMessage || 'Error:' + error.message); }); }); }; }); const options = (options = {}) => { Object.assign(Config, options); }; const tasks = { browserSync, clean, copy, css, js, lintCSS, lintJS, run, svg, watch }; // API // options({ // projectTitle: 'frontend-tasks', // showNotifications: true, // versionManifest: false, // }); // tasks.clean({ paths: [] }); // tasks.copy({ paths: [] }); // tasks.js({ src, dest }); // tasks.css({ src, dest }); // tasks.run({ cmd: 'ls', args: ['-la'] }); // tasks.svg({ paths: [] }); // tasks.nodemon(); // tasks.browserSync(); exports.Config = Config; exports.GulpHashPlugin = hash$1; exports.RollupHashPlugin = hash; exports.options = options; exports.tasks = tasks;