From e652dbddd1625ea7b774729b0f1f349bb3e7af89 Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 30 Mar 2023 10:30:48 -0700 Subject: [PATCH] deps: minimatch@7.4.3 (#6308) --- node_modules/.gitignore | 3 - .../models/node_modules/minimatch/LICENSE | 15 - .../minimatch/dist/cjs/index-cjs.js | 7 - .../node_modules/minimatch/dist/cjs/index.js | 1090 ----------------- .../minimatch/dist/cjs/package.json | 3 - .../node_modules/minimatch/dist/mjs/index.js | 1077 ---------------- .../minimatch/dist/mjs/package.json | 3 - .../node_modules/minimatch/package.json | 86 -- node_modules/@tufjs/models/package.json | 8 +- node_modules/minimatch/dist/cjs/_parse.js | 300 +++++ .../dist/cjs/assert-valid-pattern.js | 14 + node_modules/minimatch/dist/cjs/extglob.js | 4 + node_modules/minimatch/dist/cjs/parse.js | 650 ++++++++++ node_modules/minimatch/dist/mjs/_parse.js | 296 +++++ .../dist/mjs/assert-valid-pattern.js | 10 + node_modules/minimatch/dist/mjs/extglob.js | 3 + node_modules/minimatch/dist/mjs/parse.js | 646 ++++++++++ node_modules/minimatch/package.json | 2 +- node_modules/tuf-js/package.json | 10 +- package-lock.json | 39 +- package.json | 2 +- 21 files changed, 1946 insertions(+), 2322 deletions(-) delete mode 100644 node_modules/@tufjs/models/node_modules/minimatch/LICENSE delete mode 100644 node_modules/@tufjs/models/node_modules/minimatch/dist/cjs/index-cjs.js delete mode 100644 node_modules/@tufjs/models/node_modules/minimatch/dist/cjs/index.js delete mode 100644 node_modules/@tufjs/models/node_modules/minimatch/dist/cjs/package.json delete mode 100644 node_modules/@tufjs/models/node_modules/minimatch/dist/mjs/index.js delete mode 100644 node_modules/@tufjs/models/node_modules/minimatch/dist/mjs/package.json delete mode 100644 node_modules/@tufjs/models/node_modules/minimatch/package.json create mode 100644 node_modules/minimatch/dist/cjs/_parse.js create mode 100644 node_modules/minimatch/dist/cjs/assert-valid-pattern.js create mode 100644 node_modules/minimatch/dist/cjs/extglob.js create mode 100644 node_modules/minimatch/dist/cjs/parse.js create mode 100644 node_modules/minimatch/dist/mjs/_parse.js create mode 100644 node_modules/minimatch/dist/mjs/assert-valid-pattern.js create mode 100644 node_modules/minimatch/dist/mjs/extglob.js create mode 100644 node_modules/minimatch/dist/mjs/parse.js diff --git a/node_modules/.gitignore b/node_modules/.gitignore index 1f08633a59586..acdf10b731829 100644 --- a/node_modules/.gitignore +++ b/node_modules/.gitignore @@ -38,9 +38,6 @@ !/@tufjs/ /@tufjs/* !/@tufjs/models -!/@tufjs/models/node_modules/ -/@tufjs/models/node_modules/* -!/@tufjs/models/node_modules/minimatch !/abbrev !/abort-controller !/agent-base diff --git a/node_modules/@tufjs/models/node_modules/minimatch/LICENSE b/node_modules/@tufjs/models/node_modules/minimatch/LICENSE deleted file mode 100644 index 1493534e60dce..0000000000000 --- a/node_modules/@tufjs/models/node_modules/minimatch/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) 2011-2023 Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/@tufjs/models/node_modules/minimatch/dist/cjs/index-cjs.js b/node_modules/@tufjs/models/node_modules/minimatch/dist/cjs/index-cjs.js deleted file mode 100644 index db73b6b933a8a..0000000000000 --- a/node_modules/@tufjs/models/node_modules/minimatch/dist/cjs/index-cjs.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -const index_js_1 = __importDefault(require("./index.js")); -module.exports = Object.assign(index_js_1.default, { default: index_js_1.default, minimatch: index_js_1.default }); -//# sourceMappingURL=index-cjs.js.map \ No newline at end of file diff --git a/node_modules/@tufjs/models/node_modules/minimatch/dist/cjs/index.js b/node_modules/@tufjs/models/node_modules/minimatch/dist/cjs/index.js deleted file mode 100644 index 63fc3bdd0b109..0000000000000 --- a/node_modules/@tufjs/models/node_modules/minimatch/dist/cjs/index.js +++ /dev/null @@ -1,1090 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.Minimatch = exports.match = exports.makeRe = exports.braceExpand = exports.defaults = exports.filter = exports.GLOBSTAR = exports.sep = exports.minimatch = void 0; -const minimatch = (p, pattern, options = {}) => { - assertValidPattern(pattern); - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false; - } - return new Minimatch(pattern, options).match(p); -}; -exports.minimatch = minimatch; -exports.default = exports.minimatch; -// Optimized checking for the most common glob patterns. -const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/; -const starDotExtTest = (ext) => (f) => !f.startsWith('.') && f.endsWith(ext); -const starDotExtTestDot = (ext) => (f) => f.endsWith(ext); -const starDotExtTestNocase = (ext) => { - ext = ext.toLowerCase(); - return (f) => !f.startsWith('.') && f.toLowerCase().endsWith(ext); -}; -const starDotExtTestNocaseDot = (ext) => { - ext = ext.toLowerCase(); - return (f) => f.toLowerCase().endsWith(ext); -}; -const starDotStarRE = /^\*+\.\*+$/; -const starDotStarTest = (f) => !f.startsWith('.') && f.includes('.'); -const starDotStarTestDot = (f) => f !== '.' && f !== '..' && f.includes('.'); -const dotStarRE = /^\.\*+$/; -const dotStarTest = (f) => f !== '.' && f !== '..' && f.startsWith('.'); -const starRE = /^\*+$/; -const starTest = (f) => f.length !== 0 && !f.startsWith('.'); -const starTestDot = (f) => f.length !== 0 && f !== '.' && f !== '..'; -const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/; -const qmarksTestNocase = ([$0, ext = '']) => { - const noext = qmarksTestNoExt([$0]); - if (!ext) - return noext; - ext = ext.toLowerCase(); - return (f) => noext(f) && f.toLowerCase().endsWith(ext); -}; -const qmarksTestNocaseDot = ([$0, ext = '']) => { - const noext = qmarksTestNoExtDot([$0]); - if (!ext) - return noext; - ext = ext.toLowerCase(); - return (f) => noext(f) && f.toLowerCase().endsWith(ext); -}; -const qmarksTestDot = ([$0, ext = '']) => { - const noext = qmarksTestNoExtDot([$0]); - return !ext ? noext : (f) => noext(f) && f.endsWith(ext); -}; -const qmarksTest = ([$0, ext = '']) => { - const noext = qmarksTestNoExt([$0]); - return !ext ? noext : (f) => noext(f) && f.endsWith(ext); -}; -const qmarksTestNoExt = ([$0]) => { - const len = $0.length; - return (f) => f.length === len && !f.startsWith('.'); -}; -const qmarksTestNoExtDot = ([$0]) => { - const len = $0.length; - return (f) => f.length === len && f !== '.' && f !== '..'; -}; -/* c8 ignore start */ -const platform = typeof process === 'object' && process - ? (typeof process.env === 'object' && - process.env && - process.env.__MINIMATCH_TESTING_PLATFORM__) || - process.platform - : 'posix'; -const isWindows = platform === 'win32'; -const path = isWindows ? { sep: '\\' } : { sep: '/' }; -/* c8 ignore stop */ -exports.sep = path.sep; -exports.minimatch.sep = exports.sep; -exports.GLOBSTAR = Symbol('globstar **'); -exports.minimatch.GLOBSTAR = exports.GLOBSTAR; -const brace_expansion_1 = __importDefault(require("brace-expansion")); -const plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)' }, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' }, -}; -// any single thing other than / -// don't need to escape / when using new RegExp() -const qmark = '[^/]'; -// * => any number of characters -const star = qmark + '*?'; -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -const twoStarDot = '(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?'; -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -const twoStarNoDot = '(?:(?!(?:\\/|^)\\.).)*?'; -// "abc" -> { a:true, b:true, c:true } -const charSet = (s) => s.split('').reduce((set, c) => { - set[c] = true; - return set; -}, {}); -// characters that need to be escaped in RegExp. -const reSpecials = charSet('().*{}+?[]^$\\!'); -// characters that indicate we have to add the pattern start -const addPatternStartSet = charSet('[.('); -const filter = (pattern, options = {}) => (p) => (0, exports.minimatch)(p, pattern, options); -exports.filter = filter; -exports.minimatch.filter = exports.filter; -const ext = (a, b = {}) => Object.assign({}, a, b); -const defaults = (def) => { - if (!def || typeof def !== 'object' || !Object.keys(def).length) { - return exports.minimatch; - } - const orig = exports.minimatch; - const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options)); - return Object.assign(m, { - Minimatch: class Minimatch extends orig.Minimatch { - constructor(pattern, options = {}) { - super(pattern, ext(def, options)); - } - static defaults(options) { - return orig.defaults(ext(def, options)).Minimatch; - } - }, - filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)), - defaults: (options) => orig.defaults(ext(def, options)), - makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)), - braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)), - match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)), - sep: orig.sep, - GLOBSTAR: exports.GLOBSTAR, - }); -}; -exports.defaults = defaults; -exports.minimatch.defaults = exports.defaults; -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -const braceExpand = (pattern, options = {}) => { - assertValidPattern(pattern); - // Thanks to Yeting Li for - // improving this regexp to avoid a ReDOS vulnerability. - if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { - // shortcut. no need to expand. - return [pattern]; - } - return (0, brace_expansion_1.default)(pattern); -}; -exports.braceExpand = braceExpand; -exports.minimatch.braceExpand = exports.braceExpand; -const MAX_PATTERN_LENGTH = 1024 * 64; -const assertValidPattern = (pattern) => { - if (typeof pattern !== 'string') { - throw new TypeError('invalid pattern'); - } - if (pattern.length > MAX_PATTERN_LENGTH) { - throw new TypeError('pattern is too long'); - } -}; -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -const SUBPARSE = Symbol('subparse'); -const makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe(); -exports.makeRe = makeRe; -exports.minimatch.makeRe = exports.makeRe; -const match = (list, pattern, options = {}) => { - const mm = new Minimatch(pattern, options); - list = list.filter(f => mm.match(f)); - if (mm.options.nonull && !list.length) { - list.push(pattern); - } - return list; -}; -exports.match = match; -exports.minimatch.match = exports.match; -// replace stuff like \* with * -const globUnescape = (s) => s.replace(/\\(.)/g, '$1'); -const charUnescape = (s) => s.replace(/\\([^-\]])/g, '$1'); -const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); -const braExpEscape = (s) => s.replace(/[[\]\\]/g, '\\$&'); -class Minimatch { - options; - set; - pattern; - windowsPathsNoEscape; - nonegate; - negate; - comment; - empty; - preserveMultipleSlashes; - partial; - globSet; - globParts; - regexp; - constructor(pattern, options = {}) { - assertValidPattern(pattern); - options = options || {}; - this.options = options; - this.pattern = pattern; - this.windowsPathsNoEscape = - !!options.windowsPathsNoEscape || options.allowWindowsEscape === false; - if (this.windowsPathsNoEscape) { - this.pattern = this.pattern.replace(/\\/g, '/'); - } - this.preserveMultipleSlashes = !!options.preserveMultipleSlashes; - this.regexp = null; - this.negate = false; - this.nonegate = !!options.nonegate; - this.comment = false; - this.empty = false; - this.partial = !!options.partial; - this.globSet = []; - this.globParts = []; - this.set = []; - // make the set of regexps etc. - this.make(); - } - debug(..._) { } - make() { - const pattern = this.pattern; - const options = this.options; - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true; - return; - } - if (!pattern) { - this.empty = true; - return; - } - // step 1: figure out negation, etc. - this.parseNegate(); - // step 2: expand braces - this.globSet = this.braceExpand(); - if (options.debug) { - this.debug = (...args) => console.error(...args); - } - this.debug(this.pattern, this.globSet); - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - const rawGlobParts = this.globSet.map(s => this.slashSplit(s)); - // consecutive globstars are an unncessary perf killer - // also, **/*/... is equivalent to */**/..., so swap all of those - // this turns a pattern like **/*/**/*/x into */*/**/x - // and a pattern like **/x/**/*/y becomes **/x/*/**/y - // the *later* we can push the **, the more efficient it is, - // because we can avoid having to do a recursive walk until - // the walked tree is as shallow as possible. - // Note that this is only true up to the last pattern, though, because - // a/*/** will only match a/b if b is a dir, but a/**/* will match a/b - // regardless, since it's "0 or more path segments" if it's not final. - if (this.options.noglobstar) { - // ** is * anyway - this.globParts = rawGlobParts; - } - else { - // do this swap BEFORE the reduce, so that we can turn a string - // of **/*/**/* into */*/**/** and then reduce the **'s into one - for (const parts of rawGlobParts) { - let swapped; - do { - swapped = false; - for (let i = 0; i < parts.length - 1; i++) { - if (parts[i] === '*' && parts[i - 1] === '**') { - parts[i] = '**'; - parts[i - 1] = '*'; - swapped = true; - } - } - } while (swapped); - } - this.globParts = rawGlobParts.map(parts => { - parts = parts.reduce((set, part) => { - const prev = set[set.length - 1]; - if (part === '**' && prev === '**') { - return set; - } - if (part === '..') { - if (prev && prev !== '..' && prev !== '.' && prev !== '**') { - set.pop(); - return set; - } - } - set.push(part); - return set; - }, []); - return parts.length === 0 ? [''] : parts; - }); - } - this.debug(this.pattern, this.globParts); - // glob --> regexps - let set = this.globParts.map((s, _, __) => s.map(ss => this.parse(ss))); - this.debug(this.pattern, set); - // filter out everything that didn't compile properly. - this.set = set.filter(s => s.indexOf(false) === -1); - // do not treat the ? in UNC paths as magic - if (isWindows) { - for (let i = 0; i < this.set.length; i++) { - const p = this.set[i]; - if (p[0] === '' && - p[1] === '' && - this.globParts[i][2] === '?' && - typeof p[3] === 'string' && - /^[a-z]:$/i.test(p[3])) { - p[2] = '?'; - } - } - } - this.debug(this.pattern, this.set); - } - parseNegate() { - if (this.nonegate) - return; - const pattern = this.pattern; - let negate = false; - let negateOffset = 0; - for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) { - negate = !negate; - negateOffset++; - } - if (negateOffset) - this.pattern = pattern.slice(negateOffset); - this.negate = negate; - } - // set partial to true to test if, for example, - // "/a/b" matches the start of "/*/b/*/d" - // Partial means, if you run out of file before you run - // out of pattern, then that's fine, as long as all - // the parts match. - matchOne(file, pattern, partial = false) { - const options = this.options; - // a UNC pattern like //?/c:/* can match a path like c:/x - // and vice versa - if (isWindows) { - const fileUNC = file[0] === '' && - file[1] === '' && - file[2] === '?' && - typeof file[3] === 'string' && - /^[a-z]:$/i.test(file[3]); - const patternUNC = pattern[0] === '' && - pattern[1] === '' && - pattern[2] === '?' && - typeof pattern[3] === 'string' && - /^[a-z]:$/i.test(pattern[3]); - if (fileUNC && patternUNC) { - const fd = file[3]; - const pd = pattern[3]; - if (fd.toLowerCase() === pd.toLowerCase()) { - file[3] = pd; - } - } - else if (patternUNC && typeof file[0] === 'string') { - const pd = pattern[3]; - const fd = file[0]; - if (pd.toLowerCase() === fd.toLowerCase()) { - pattern[3] = fd; - pattern = pattern.slice(3); - } - } - else if (fileUNC && typeof pattern[0] === 'string') { - const fd = file[3]; - if (fd.toLowerCase() === pattern[0].toLowerCase()) { - pattern[0] = fd; - file = file.slice(3); - } - } - } - this.debug('matchOne', this, { file, pattern }); - this.debug('matchOne', file.length, pattern.length); - for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { - this.debug('matchOne loop'); - var p = pattern[pi]; - var f = file[fi]; - this.debug(pattern, p, f); - // should be impossible. - // some invalid regexp stuff in the set. - /* c8 ignore start */ - if (p === false) { - return false; - } - /* c8 ignore stop */ - if (p === exports.GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]); - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi; - var pr = pi + 1; - if (pr === pl) { - this.debug('** at the end'); - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || - file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) - return false; - } - return true; - } - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr]; - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee); - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee); - // found a match. - return true; - } - else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || - swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr); - break; - } - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue'); - fr++; - } - } - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - /* c8 ignore start */ - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr); - if (fr === fl) { - return true; - } - } - /* c8 ignore stop */ - return false; - } - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - let hit; - if (typeof p === 'string') { - hit = f === p; - this.debug('string match', p, f, hit); - } - else { - hit = p.test(f); - this.debug('pattern match', p, f, hit); - } - if (!hit) - return false; - } - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true; - } - else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial; - } - else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - return fi === fl - 1 && file[fi] === ''; - /* c8 ignore start */ - } - else { - // should be unreachable. - throw new Error('wtf?'); - } - /* c8 ignore stop */ - } - braceExpand() { - return (0, exports.braceExpand)(this.pattern, this.options); - } - parse(pattern, isSub) { - assertValidPattern(pattern); - const options = this.options; - // shortcuts - if (pattern === '**') { - if (!options.noglobstar) - return exports.GLOBSTAR; - else - pattern = '*'; - } - if (pattern === '') - return ''; - // far and away, the most common glob pattern parts are - // *, *.*, and *. Add a fast check method for those. - let m; - let fastTest = null; - if (isSub !== SUBPARSE) { - if ((m = pattern.match(starRE))) { - fastTest = options.dot ? starTestDot : starTest; - } - else if ((m = pattern.match(starDotExtRE))) { - fastTest = (options.nocase - ? options.dot - ? starDotExtTestNocaseDot - : starDotExtTestNocase - : options.dot - ? starDotExtTestDot - : starDotExtTest)(m[1]); - } - else if ((m = pattern.match(qmarksRE))) { - fastTest = (options.nocase - ? options.dot - ? qmarksTestNocaseDot - : qmarksTestNocase - : options.dot - ? qmarksTestDot - : qmarksTest)(m); - } - else if ((m = pattern.match(starDotStarRE))) { - fastTest = options.dot ? starDotStarTestDot : starDotStarTest; - } - else if ((m = pattern.match(dotStarRE))) { - fastTest = dotStarTest; - } - } - let re = ''; - let hasMagic = false; - let escaping = false; - // ? => one single character - const patternListStack = []; - const negativeLists = []; - let stateChar = false; - let inClass = false; - let reClassStart = -1; - let classStart = -1; - let cs; - let pl; - let sp; - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. However, if the pattern - // starts with ., then traversal patterns can match. - let dotTravAllowed = pattern.charAt(0) === '.'; - let dotFileAllowed = options.dot || dotTravAllowed; - const patternStart = () => dotTravAllowed - ? '' - : dotFileAllowed - ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' - : '(?!\\.)'; - const subPatternStart = (p) => p.charAt(0) === '.' - ? '' - : options.dot - ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' - : '(?!\\.)'; - const clearStateChar = () => { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star; - hasMagic = true; - break; - case '?': - re += qmark; - hasMagic = true; - break; - default: - re += '\\' + stateChar; - break; - } - this.debug('clearStateChar %j %j', stateChar, re); - stateChar = false; - } - }; - for (let i = 0, c; i < pattern.length && (c = pattern.charAt(i)); i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c); - // skip over any that are escaped. - if (escaping) { - // completely not allowed, even escaped. - // should be impossible. - /* c8 ignore start */ - if (c === '/') { - return false; - } - /* c8 ignore stop */ - if (reSpecials[c]) { - re += '\\'; - } - re += c; - escaping = false; - continue; - } - switch (c) { - // Should already be path-split by now. - /* c8 ignore start */ - case '/': { - return false; - } - /* c8 ignore stop */ - case '\\': - if (inClass && pattern.charAt(i + 1) === '-') { - re += c; - continue; - } - clearStateChar(); - escaping = true; - continue; - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c); - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class'); - if (c === '!' && i === classStart + 1) - c = '^'; - re += c; - continue; - } - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - this.debug('call clearStateChar %j', stateChar); - clearStateChar(); - stateChar = c; - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) - clearStateChar(); - continue; - case '(': { - if (inClass) { - re += '('; - continue; - } - if (!stateChar) { - re += '\\('; - continue; - } - const plEntry = { - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close, - }; - this.debug(this.pattern, '\t', plEntry); - patternListStack.push(plEntry); - // negation is (?:(?!(?:js)(?:))[^/]*) - re += plEntry.open; - // next entry starts with a dot maybe? - if (plEntry.start === 0 && plEntry.type !== '!') { - dotTravAllowed = true; - re += subPatternStart(pattern.slice(i + 1)); - } - this.debug('plType %j %j', stateChar, re); - stateChar = false; - continue; - } - case ')': { - const plEntry = patternListStack[patternListStack.length - 1]; - if (inClass || !plEntry) { - re += '\\)'; - continue; - } - patternListStack.pop(); - // closing an extglob - clearStateChar(); - hasMagic = true; - pl = plEntry; - // negation is (?:(?!js)[^/]*) - // The others are (?:) - re += pl.close; - if (pl.type === '!') { - negativeLists.push(Object.assign(pl, { reEnd: re.length })); - } - continue; - } - case '|': { - const plEntry = patternListStack[patternListStack.length - 1]; - if (inClass || !plEntry) { - re += '\\|'; - continue; - } - clearStateChar(); - re += '|'; - // next subpattern can start with a dot? - if (plEntry.start === 0 && plEntry.type !== '!') { - dotTravAllowed = true; - re += subPatternStart(pattern.slice(i + 1)); - } - continue; - } - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar(); - if (inClass) { - re += '\\' + c; - continue; - } - inClass = true; - classStart = i; - reClassStart = re.length; - re += c; - continue; - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c; - continue; - } - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - cs = pattern.substring(classStart + 1, i); - try { - RegExp('[' + braExpEscape(charUnescape(cs)) + ']'); - // looks good, finish up the class. - re += c; - } - catch (er) { - // out of order ranges in JS are errors, but in glob syntax, - // they're just a range that matches nothing. - re = re.substring(0, reClassStart) + '(?:$.)'; // match nothing ever - } - hasMagic = true; - inClass = false; - continue; - default: - // swallow any state char that wasn't consumed - clearStateChar(); - if (reSpecials[c] && !(c === '^' && inClass)) { - re += '\\'; - } - re += c; - break; - } // switch - } // for - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.slice(classStart + 1); - sp = this.parse(cs, SUBPARSE); - re = re.substring(0, reClassStart) + '\\[' + sp[0]; - hasMagic = hasMagic || sp[1]; - } - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - let tail; - tail = re.slice(pl.reStart + pl.open.length); - this.debug(this.pattern, 'setting tail', re, pl); - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, (_, $1, $2) => { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\'; - // should already be done - /* c8 ignore start */ - } - /* c8 ignore stop */ - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|'; - }); - this.debug('tail=%j\n %s', tail, tail, pl, re); - const t = pl.type === '*' ? star : pl.type === '?' ? qmark : '\\' + pl.type; - hasMagic = true; - re = re.slice(0, pl.reStart) + t + '\\(' + tail; - } - // handle trailing things that only matter at the very end. - clearStateChar(); - if (escaping) { - // trailing \\ - re += '\\\\'; - } - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - const addPatternStart = addPatternStartSet[re.charAt(0)]; - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (let n = negativeLists.length - 1; n > -1; n--) { - const nl = negativeLists[n]; - const nlBefore = re.slice(0, nl.reStart); - const nlFirst = re.slice(nl.reStart, nl.reEnd - 8); - let nlAfter = re.slice(nl.reEnd); - const nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + nlAfter; - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - const closeParensBefore = nlBefore.split(')').length; - const openParensBefore = nlBefore.split('(').length - closeParensBefore; - let cleanAfter = nlAfter; - for (let i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, ''); - } - nlAfter = cleanAfter; - const dollar = nlAfter === '' && isSub !== SUBPARSE ? '(?:$|\\/)' : ''; - re = nlBefore + nlFirst + nlAfter + dollar + nlLast; - } - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re; - } - if (addPatternStart) { - re = patternStart() + re; - } - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic]; - } - // if it's nocase, and the lcase/uppercase don't match, it's magic - if (options.nocase && !hasMagic && !options.nocaseMagicOnly) { - hasMagic = pattern.toUpperCase() !== pattern.toLowerCase(); - } - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern); - } - const flags = options.nocase ? 'i' : ''; - try { - const ext = fastTest - ? { - _glob: pattern, - _src: re, - test: fastTest, - } - : { - _glob: pattern, - _src: re, - }; - return Object.assign(new RegExp('^' + re + '$', flags), ext); - /* c8 ignore start */ - } - catch (er) { - // should be impossible - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - this.debug('invalid regexp', er); - return new RegExp('$.'); - } - /* c8 ignore stop */ - } - makeRe() { - if (this.regexp || this.regexp === false) - return this.regexp; - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - const set = this.set; - if (!set.length) { - this.regexp = false; - return this.regexp; - } - const options = this.options; - const twoStar = options.noglobstar - ? star - : options.dot - ? twoStarDot - : twoStarNoDot; - const flags = options.nocase ? 'i' : ''; - // regexpify non-globstar patterns - // if ** is only item, then we just do one twoStar - // if ** is first, and there are more, prepend (\/|twoStar\/)? to next - // if ** is last, append (\/twoStar|) to previous - // if ** is in the middle, append (\/|\/twoStar\/) to previous - // then filter out GLOBSTAR symbols - let re = set - .map(pattern => { - const pp = pattern.map(p => typeof p === 'string' - ? regExpEscape(p) - : p === exports.GLOBSTAR - ? exports.GLOBSTAR - : p._src); - pp.forEach((p, i) => { - const next = pp[i + 1]; - const prev = pp[i - 1]; - if (p !== exports.GLOBSTAR || prev === exports.GLOBSTAR) { - return; - } - if (prev === undefined) { - if (next !== undefined && next !== exports.GLOBSTAR) { - pp[i + 1] = '(?:\\/|' + twoStar + '\\/)?' + next; - } - else { - pp[i] = twoStar; - } - } - else if (next === undefined) { - pp[i - 1] = prev + '(?:\\/|' + twoStar + ')?'; - } - else if (next !== exports.GLOBSTAR) { - pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next; - pp[i + 1] = exports.GLOBSTAR; - } - }); - return pp.filter(p => p !== exports.GLOBSTAR).join('/'); - }) - .join('|'); - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$'; - // can match anything, as long as it's not this. - if (this.negate) - re = '^(?!' + re + ').*$'; - try { - this.regexp = new RegExp(re, flags); - /* c8 ignore start */ - } - catch (ex) { - // should be impossible - this.regexp = false; - } - /* c8 ignore stop */ - return this.regexp; - } - slashSplit(p) { - // if p starts with // on windows, we preserve that - // so that UNC paths aren't broken. Otherwise, any number of - // / characters are coalesced into one, unless - // preserveMultipleSlashes is set to true. - if (this.preserveMultipleSlashes) { - return p.split('/'); - } - else if (isWindows && /^\/\/[^\/]+/.test(p)) { - // add an extra '' for the one we lose - return ['', ...p.split(/\/+/)]; - } - else { - return p.split(/\/+/); - } - } - match(f, partial = this.partial) { - this.debug('match', f, this.pattern); - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) { - return false; - } - if (this.empty) { - return f === ''; - } - if (f === '/' && partial) { - return true; - } - const options = this.options; - // windows: need to use /, not \ - if (path.sep !== '/') { - f = f.split(path.sep).join('/'); - } - // treat the test path as a set of pathparts. - const ff = this.slashSplit(f); - this.debug(this.pattern, 'split', ff); - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - const set = this.set; - this.debug(this.pattern, 'set', set); - // Find the basename of the path by looking for the last non-empty segment - let filename = ff[ff.length - 1]; - if (!filename) { - for (let i = ff.length - 2; !filename && i >= 0; i--) { - filename = ff[i]; - } - } - for (let i = 0; i < set.length; i++) { - const pattern = set[i]; - let file = ff; - if (options.matchBase && pattern.length === 1) { - file = [filename]; - } - const hit = this.matchOne(file, pattern, partial); - if (hit) { - if (options.flipNegate) { - return true; - } - return !this.negate; - } - } - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) { - return false; - } - return this.negate; - } - static defaults(def) { - return exports.minimatch.defaults(def).Minimatch; - } -} -exports.Minimatch = Minimatch; -exports.minimatch.Minimatch = Minimatch; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/@tufjs/models/node_modules/minimatch/dist/cjs/package.json b/node_modules/@tufjs/models/node_modules/minimatch/dist/cjs/package.json deleted file mode 100644 index 5bbefffbabee3..0000000000000 --- a/node_modules/@tufjs/models/node_modules/minimatch/dist/cjs/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "commonjs" -} diff --git a/node_modules/@tufjs/models/node_modules/minimatch/dist/mjs/index.js b/node_modules/@tufjs/models/node_modules/minimatch/dist/mjs/index.js deleted file mode 100644 index 59ac1968b5ded..0000000000000 --- a/node_modules/@tufjs/models/node_modules/minimatch/dist/mjs/index.js +++ /dev/null @@ -1,1077 +0,0 @@ -export const minimatch = (p, pattern, options = {}) => { - assertValidPattern(pattern); - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false; - } - return new Minimatch(pattern, options).match(p); -}; -export default minimatch; -// Optimized checking for the most common glob patterns. -const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/; -const starDotExtTest = (ext) => (f) => !f.startsWith('.') && f.endsWith(ext); -const starDotExtTestDot = (ext) => (f) => f.endsWith(ext); -const starDotExtTestNocase = (ext) => { - ext = ext.toLowerCase(); - return (f) => !f.startsWith('.') && f.toLowerCase().endsWith(ext); -}; -const starDotExtTestNocaseDot = (ext) => { - ext = ext.toLowerCase(); - return (f) => f.toLowerCase().endsWith(ext); -}; -const starDotStarRE = /^\*+\.\*+$/; -const starDotStarTest = (f) => !f.startsWith('.') && f.includes('.'); -const starDotStarTestDot = (f) => f !== '.' && f !== '..' && f.includes('.'); -const dotStarRE = /^\.\*+$/; -const dotStarTest = (f) => f !== '.' && f !== '..' && f.startsWith('.'); -const starRE = /^\*+$/; -const starTest = (f) => f.length !== 0 && !f.startsWith('.'); -const starTestDot = (f) => f.length !== 0 && f !== '.' && f !== '..'; -const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/; -const qmarksTestNocase = ([$0, ext = '']) => { - const noext = qmarksTestNoExt([$0]); - if (!ext) - return noext; - ext = ext.toLowerCase(); - return (f) => noext(f) && f.toLowerCase().endsWith(ext); -}; -const qmarksTestNocaseDot = ([$0, ext = '']) => { - const noext = qmarksTestNoExtDot([$0]); - if (!ext) - return noext; - ext = ext.toLowerCase(); - return (f) => noext(f) && f.toLowerCase().endsWith(ext); -}; -const qmarksTestDot = ([$0, ext = '']) => { - const noext = qmarksTestNoExtDot([$0]); - return !ext ? noext : (f) => noext(f) && f.endsWith(ext); -}; -const qmarksTest = ([$0, ext = '']) => { - const noext = qmarksTestNoExt([$0]); - return !ext ? noext : (f) => noext(f) && f.endsWith(ext); -}; -const qmarksTestNoExt = ([$0]) => { - const len = $0.length; - return (f) => f.length === len && !f.startsWith('.'); -}; -const qmarksTestNoExtDot = ([$0]) => { - const len = $0.length; - return (f) => f.length === len && f !== '.' && f !== '..'; -}; -/* c8 ignore start */ -const platform = typeof process === 'object' && process - ? (typeof process.env === 'object' && - process.env && - process.env.__MINIMATCH_TESTING_PLATFORM__) || - process.platform - : 'posix'; -const isWindows = platform === 'win32'; -const path = isWindows ? { sep: '\\' } : { sep: '/' }; -/* c8 ignore stop */ -export const sep = path.sep; -minimatch.sep = sep; -export const GLOBSTAR = Symbol('globstar **'); -minimatch.GLOBSTAR = GLOBSTAR; -import expand from 'brace-expansion'; -const plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)' }, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' }, -}; -// any single thing other than / -// don't need to escape / when using new RegExp() -const qmark = '[^/]'; -// * => any number of characters -const star = qmark + '*?'; -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -const twoStarDot = '(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?'; -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -const twoStarNoDot = '(?:(?!(?:\\/|^)\\.).)*?'; -// "abc" -> { a:true, b:true, c:true } -const charSet = (s) => s.split('').reduce((set, c) => { - set[c] = true; - return set; -}, {}); -// characters that need to be escaped in RegExp. -const reSpecials = charSet('().*{}+?[]^$\\!'); -// characters that indicate we have to add the pattern start -const addPatternStartSet = charSet('[.('); -export const filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options); -minimatch.filter = filter; -const ext = (a, b = {}) => Object.assign({}, a, b); -export const defaults = (def) => { - if (!def || typeof def !== 'object' || !Object.keys(def).length) { - return minimatch; - } - const orig = minimatch; - const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options)); - return Object.assign(m, { - Minimatch: class Minimatch extends orig.Minimatch { - constructor(pattern, options = {}) { - super(pattern, ext(def, options)); - } - static defaults(options) { - return orig.defaults(ext(def, options)).Minimatch; - } - }, - filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)), - defaults: (options) => orig.defaults(ext(def, options)), - makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)), - braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)), - match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)), - sep: orig.sep, - GLOBSTAR: GLOBSTAR, - }); -}; -minimatch.defaults = defaults; -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -export const braceExpand = (pattern, options = {}) => { - assertValidPattern(pattern); - // Thanks to Yeting Li for - // improving this regexp to avoid a ReDOS vulnerability. - if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { - // shortcut. no need to expand. - return [pattern]; - } - return expand(pattern); -}; -minimatch.braceExpand = braceExpand; -const MAX_PATTERN_LENGTH = 1024 * 64; -const assertValidPattern = (pattern) => { - if (typeof pattern !== 'string') { - throw new TypeError('invalid pattern'); - } - if (pattern.length > MAX_PATTERN_LENGTH) { - throw new TypeError('pattern is too long'); - } -}; -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -const SUBPARSE = Symbol('subparse'); -export const makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe(); -minimatch.makeRe = makeRe; -export const match = (list, pattern, options = {}) => { - const mm = new Minimatch(pattern, options); - list = list.filter(f => mm.match(f)); - if (mm.options.nonull && !list.length) { - list.push(pattern); - } - return list; -}; -minimatch.match = match; -// replace stuff like \* with * -const globUnescape = (s) => s.replace(/\\(.)/g, '$1'); -const charUnescape = (s) => s.replace(/\\([^-\]])/g, '$1'); -const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); -const braExpEscape = (s) => s.replace(/[[\]\\]/g, '\\$&'); -export class Minimatch { - options; - set; - pattern; - windowsPathsNoEscape; - nonegate; - negate; - comment; - empty; - preserveMultipleSlashes; - partial; - globSet; - globParts; - regexp; - constructor(pattern, options = {}) { - assertValidPattern(pattern); - options = options || {}; - this.options = options; - this.pattern = pattern; - this.windowsPathsNoEscape = - !!options.windowsPathsNoEscape || options.allowWindowsEscape === false; - if (this.windowsPathsNoEscape) { - this.pattern = this.pattern.replace(/\\/g, '/'); - } - this.preserveMultipleSlashes = !!options.preserveMultipleSlashes; - this.regexp = null; - this.negate = false; - this.nonegate = !!options.nonegate; - this.comment = false; - this.empty = false; - this.partial = !!options.partial; - this.globSet = []; - this.globParts = []; - this.set = []; - // make the set of regexps etc. - this.make(); - } - debug(..._) { } - make() { - const pattern = this.pattern; - const options = this.options; - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true; - return; - } - if (!pattern) { - this.empty = true; - return; - } - // step 1: figure out negation, etc. - this.parseNegate(); - // step 2: expand braces - this.globSet = this.braceExpand(); - if (options.debug) { - this.debug = (...args) => console.error(...args); - } - this.debug(this.pattern, this.globSet); - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - const rawGlobParts = this.globSet.map(s => this.slashSplit(s)); - // consecutive globstars are an unncessary perf killer - // also, **/*/... is equivalent to */**/..., so swap all of those - // this turns a pattern like **/*/**/*/x into */*/**/x - // and a pattern like **/x/**/*/y becomes **/x/*/**/y - // the *later* we can push the **, the more efficient it is, - // because we can avoid having to do a recursive walk until - // the walked tree is as shallow as possible. - // Note that this is only true up to the last pattern, though, because - // a/*/** will only match a/b if b is a dir, but a/**/* will match a/b - // regardless, since it's "0 or more path segments" if it's not final. - if (this.options.noglobstar) { - // ** is * anyway - this.globParts = rawGlobParts; - } - else { - // do this swap BEFORE the reduce, so that we can turn a string - // of **/*/**/* into */*/**/** and then reduce the **'s into one - for (const parts of rawGlobParts) { - let swapped; - do { - swapped = false; - for (let i = 0; i < parts.length - 1; i++) { - if (parts[i] === '*' && parts[i - 1] === '**') { - parts[i] = '**'; - parts[i - 1] = '*'; - swapped = true; - } - } - } while (swapped); - } - this.globParts = rawGlobParts.map(parts => { - parts = parts.reduce((set, part) => { - const prev = set[set.length - 1]; - if (part === '**' && prev === '**') { - return set; - } - if (part === '..') { - if (prev && prev !== '..' && prev !== '.' && prev !== '**') { - set.pop(); - return set; - } - } - set.push(part); - return set; - }, []); - return parts.length === 0 ? [''] : parts; - }); - } - this.debug(this.pattern, this.globParts); - // glob --> regexps - let set = this.globParts.map((s, _, __) => s.map(ss => this.parse(ss))); - this.debug(this.pattern, set); - // filter out everything that didn't compile properly. - this.set = set.filter(s => s.indexOf(false) === -1); - // do not treat the ? in UNC paths as magic - if (isWindows) { - for (let i = 0; i < this.set.length; i++) { - const p = this.set[i]; - if (p[0] === '' && - p[1] === '' && - this.globParts[i][2] === '?' && - typeof p[3] === 'string' && - /^[a-z]:$/i.test(p[3])) { - p[2] = '?'; - } - } - } - this.debug(this.pattern, this.set); - } - parseNegate() { - if (this.nonegate) - return; - const pattern = this.pattern; - let negate = false; - let negateOffset = 0; - for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) { - negate = !negate; - negateOffset++; - } - if (negateOffset) - this.pattern = pattern.slice(negateOffset); - this.negate = negate; - } - // set partial to true to test if, for example, - // "/a/b" matches the start of "/*/b/*/d" - // Partial means, if you run out of file before you run - // out of pattern, then that's fine, as long as all - // the parts match. - matchOne(file, pattern, partial = false) { - const options = this.options; - // a UNC pattern like //?/c:/* can match a path like c:/x - // and vice versa - if (isWindows) { - const fileUNC = file[0] === '' && - file[1] === '' && - file[2] === '?' && - typeof file[3] === 'string' && - /^[a-z]:$/i.test(file[3]); - const patternUNC = pattern[0] === '' && - pattern[1] === '' && - pattern[2] === '?' && - typeof pattern[3] === 'string' && - /^[a-z]:$/i.test(pattern[3]); - if (fileUNC && patternUNC) { - const fd = file[3]; - const pd = pattern[3]; - if (fd.toLowerCase() === pd.toLowerCase()) { - file[3] = pd; - } - } - else if (patternUNC && typeof file[0] === 'string') { - const pd = pattern[3]; - const fd = file[0]; - if (pd.toLowerCase() === fd.toLowerCase()) { - pattern[3] = fd; - pattern = pattern.slice(3); - } - } - else if (fileUNC && typeof pattern[0] === 'string') { - const fd = file[3]; - if (fd.toLowerCase() === pattern[0].toLowerCase()) { - pattern[0] = fd; - file = file.slice(3); - } - } - } - this.debug('matchOne', this, { file, pattern }); - this.debug('matchOne', file.length, pattern.length); - for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { - this.debug('matchOne loop'); - var p = pattern[pi]; - var f = file[fi]; - this.debug(pattern, p, f); - // should be impossible. - // some invalid regexp stuff in the set. - /* c8 ignore start */ - if (p === false) { - return false; - } - /* c8 ignore stop */ - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]); - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi; - var pr = pi + 1; - if (pr === pl) { - this.debug('** at the end'); - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || - file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) - return false; - } - return true; - } - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr]; - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee); - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee); - // found a match. - return true; - } - else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || - swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr); - break; - } - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue'); - fr++; - } - } - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - /* c8 ignore start */ - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr); - if (fr === fl) { - return true; - } - } - /* c8 ignore stop */ - return false; - } - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - let hit; - if (typeof p === 'string') { - hit = f === p; - this.debug('string match', p, f, hit); - } - else { - hit = p.test(f); - this.debug('pattern match', p, f, hit); - } - if (!hit) - return false; - } - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true; - } - else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial; - } - else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - return fi === fl - 1 && file[fi] === ''; - /* c8 ignore start */ - } - else { - // should be unreachable. - throw new Error('wtf?'); - } - /* c8 ignore stop */ - } - braceExpand() { - return braceExpand(this.pattern, this.options); - } - parse(pattern, isSub) { - assertValidPattern(pattern); - const options = this.options; - // shortcuts - if (pattern === '**') { - if (!options.noglobstar) - return GLOBSTAR; - else - pattern = '*'; - } - if (pattern === '') - return ''; - // far and away, the most common glob pattern parts are - // *, *.*, and *. Add a fast check method for those. - let m; - let fastTest = null; - if (isSub !== SUBPARSE) { - if ((m = pattern.match(starRE))) { - fastTest = options.dot ? starTestDot : starTest; - } - else if ((m = pattern.match(starDotExtRE))) { - fastTest = (options.nocase - ? options.dot - ? starDotExtTestNocaseDot - : starDotExtTestNocase - : options.dot - ? starDotExtTestDot - : starDotExtTest)(m[1]); - } - else if ((m = pattern.match(qmarksRE))) { - fastTest = (options.nocase - ? options.dot - ? qmarksTestNocaseDot - : qmarksTestNocase - : options.dot - ? qmarksTestDot - : qmarksTest)(m); - } - else if ((m = pattern.match(starDotStarRE))) { - fastTest = options.dot ? starDotStarTestDot : starDotStarTest; - } - else if ((m = pattern.match(dotStarRE))) { - fastTest = dotStarTest; - } - } - let re = ''; - let hasMagic = false; - let escaping = false; - // ? => one single character - const patternListStack = []; - const negativeLists = []; - let stateChar = false; - let inClass = false; - let reClassStart = -1; - let classStart = -1; - let cs; - let pl; - let sp; - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. However, if the pattern - // starts with ., then traversal patterns can match. - let dotTravAllowed = pattern.charAt(0) === '.'; - let dotFileAllowed = options.dot || dotTravAllowed; - const patternStart = () => dotTravAllowed - ? '' - : dotFileAllowed - ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' - : '(?!\\.)'; - const subPatternStart = (p) => p.charAt(0) === '.' - ? '' - : options.dot - ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' - : '(?!\\.)'; - const clearStateChar = () => { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star; - hasMagic = true; - break; - case '?': - re += qmark; - hasMagic = true; - break; - default: - re += '\\' + stateChar; - break; - } - this.debug('clearStateChar %j %j', stateChar, re); - stateChar = false; - } - }; - for (let i = 0, c; i < pattern.length && (c = pattern.charAt(i)); i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c); - // skip over any that are escaped. - if (escaping) { - // completely not allowed, even escaped. - // should be impossible. - /* c8 ignore start */ - if (c === '/') { - return false; - } - /* c8 ignore stop */ - if (reSpecials[c]) { - re += '\\'; - } - re += c; - escaping = false; - continue; - } - switch (c) { - // Should already be path-split by now. - /* c8 ignore start */ - case '/': { - return false; - } - /* c8 ignore stop */ - case '\\': - if (inClass && pattern.charAt(i + 1) === '-') { - re += c; - continue; - } - clearStateChar(); - escaping = true; - continue; - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c); - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class'); - if (c === '!' && i === classStart + 1) - c = '^'; - re += c; - continue; - } - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - this.debug('call clearStateChar %j', stateChar); - clearStateChar(); - stateChar = c; - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) - clearStateChar(); - continue; - case '(': { - if (inClass) { - re += '('; - continue; - } - if (!stateChar) { - re += '\\('; - continue; - } - const plEntry = { - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close, - }; - this.debug(this.pattern, '\t', plEntry); - patternListStack.push(plEntry); - // negation is (?:(?!(?:js)(?:))[^/]*) - re += plEntry.open; - // next entry starts with a dot maybe? - if (plEntry.start === 0 && plEntry.type !== '!') { - dotTravAllowed = true; - re += subPatternStart(pattern.slice(i + 1)); - } - this.debug('plType %j %j', stateChar, re); - stateChar = false; - continue; - } - case ')': { - const plEntry = patternListStack[patternListStack.length - 1]; - if (inClass || !plEntry) { - re += '\\)'; - continue; - } - patternListStack.pop(); - // closing an extglob - clearStateChar(); - hasMagic = true; - pl = plEntry; - // negation is (?:(?!js)[^/]*) - // The others are (?:) - re += pl.close; - if (pl.type === '!') { - negativeLists.push(Object.assign(pl, { reEnd: re.length })); - } - continue; - } - case '|': { - const plEntry = patternListStack[patternListStack.length - 1]; - if (inClass || !plEntry) { - re += '\\|'; - continue; - } - clearStateChar(); - re += '|'; - // next subpattern can start with a dot? - if (plEntry.start === 0 && plEntry.type !== '!') { - dotTravAllowed = true; - re += subPatternStart(pattern.slice(i + 1)); - } - continue; - } - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar(); - if (inClass) { - re += '\\' + c; - continue; - } - inClass = true; - classStart = i; - reClassStart = re.length; - re += c; - continue; - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c; - continue; - } - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - cs = pattern.substring(classStart + 1, i); - try { - RegExp('[' + braExpEscape(charUnescape(cs)) + ']'); - // looks good, finish up the class. - re += c; - } - catch (er) { - // out of order ranges in JS are errors, but in glob syntax, - // they're just a range that matches nothing. - re = re.substring(0, reClassStart) + '(?:$.)'; // match nothing ever - } - hasMagic = true; - inClass = false; - continue; - default: - // swallow any state char that wasn't consumed - clearStateChar(); - if (reSpecials[c] && !(c === '^' && inClass)) { - re += '\\'; - } - re += c; - break; - } // switch - } // for - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.slice(classStart + 1); - sp = this.parse(cs, SUBPARSE); - re = re.substring(0, reClassStart) + '\\[' + sp[0]; - hasMagic = hasMagic || sp[1]; - } - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - let tail; - tail = re.slice(pl.reStart + pl.open.length); - this.debug(this.pattern, 'setting tail', re, pl); - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, (_, $1, $2) => { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\'; - // should already be done - /* c8 ignore start */ - } - /* c8 ignore stop */ - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|'; - }); - this.debug('tail=%j\n %s', tail, tail, pl, re); - const t = pl.type === '*' ? star : pl.type === '?' ? qmark : '\\' + pl.type; - hasMagic = true; - re = re.slice(0, pl.reStart) + t + '\\(' + tail; - } - // handle trailing things that only matter at the very end. - clearStateChar(); - if (escaping) { - // trailing \\ - re += '\\\\'; - } - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - const addPatternStart = addPatternStartSet[re.charAt(0)]; - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (let n = negativeLists.length - 1; n > -1; n--) { - const nl = negativeLists[n]; - const nlBefore = re.slice(0, nl.reStart); - const nlFirst = re.slice(nl.reStart, nl.reEnd - 8); - let nlAfter = re.slice(nl.reEnd); - const nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + nlAfter; - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - const closeParensBefore = nlBefore.split(')').length; - const openParensBefore = nlBefore.split('(').length - closeParensBefore; - let cleanAfter = nlAfter; - for (let i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, ''); - } - nlAfter = cleanAfter; - const dollar = nlAfter === '' && isSub !== SUBPARSE ? '(?:$|\\/)' : ''; - re = nlBefore + nlFirst + nlAfter + dollar + nlLast; - } - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re; - } - if (addPatternStart) { - re = patternStart() + re; - } - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic]; - } - // if it's nocase, and the lcase/uppercase don't match, it's magic - if (options.nocase && !hasMagic && !options.nocaseMagicOnly) { - hasMagic = pattern.toUpperCase() !== pattern.toLowerCase(); - } - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern); - } - const flags = options.nocase ? 'i' : ''; - try { - const ext = fastTest - ? { - _glob: pattern, - _src: re, - test: fastTest, - } - : { - _glob: pattern, - _src: re, - }; - return Object.assign(new RegExp('^' + re + '$', flags), ext); - /* c8 ignore start */ - } - catch (er) { - // should be impossible - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - this.debug('invalid regexp', er); - return new RegExp('$.'); - } - /* c8 ignore stop */ - } - makeRe() { - if (this.regexp || this.regexp === false) - return this.regexp; - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - const set = this.set; - if (!set.length) { - this.regexp = false; - return this.regexp; - } - const options = this.options; - const twoStar = options.noglobstar - ? star - : options.dot - ? twoStarDot - : twoStarNoDot; - const flags = options.nocase ? 'i' : ''; - // regexpify non-globstar patterns - // if ** is only item, then we just do one twoStar - // if ** is first, and there are more, prepend (\/|twoStar\/)? to next - // if ** is last, append (\/twoStar|) to previous - // if ** is in the middle, append (\/|\/twoStar\/) to previous - // then filter out GLOBSTAR symbols - let re = set - .map(pattern => { - const pp = pattern.map(p => typeof p === 'string' - ? regExpEscape(p) - : p === GLOBSTAR - ? GLOBSTAR - : p._src); - pp.forEach((p, i) => { - const next = pp[i + 1]; - const prev = pp[i - 1]; - if (p !== GLOBSTAR || prev === GLOBSTAR) { - return; - } - if (prev === undefined) { - if (next !== undefined && next !== GLOBSTAR) { - pp[i + 1] = '(?:\\/|' + twoStar + '\\/)?' + next; - } - else { - pp[i] = twoStar; - } - } - else if (next === undefined) { - pp[i - 1] = prev + '(?:\\/|' + twoStar + ')?'; - } - else if (next !== GLOBSTAR) { - pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next; - pp[i + 1] = GLOBSTAR; - } - }); - return pp.filter(p => p !== GLOBSTAR).join('/'); - }) - .join('|'); - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$'; - // can match anything, as long as it's not this. - if (this.negate) - re = '^(?!' + re + ').*$'; - try { - this.regexp = new RegExp(re, flags); - /* c8 ignore start */ - } - catch (ex) { - // should be impossible - this.regexp = false; - } - /* c8 ignore stop */ - return this.regexp; - } - slashSplit(p) { - // if p starts with // on windows, we preserve that - // so that UNC paths aren't broken. Otherwise, any number of - // / characters are coalesced into one, unless - // preserveMultipleSlashes is set to true. - if (this.preserveMultipleSlashes) { - return p.split('/'); - } - else if (isWindows && /^\/\/[^\/]+/.test(p)) { - // add an extra '' for the one we lose - return ['', ...p.split(/\/+/)]; - } - else { - return p.split(/\/+/); - } - } - match(f, partial = this.partial) { - this.debug('match', f, this.pattern); - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) { - return false; - } - if (this.empty) { - return f === ''; - } - if (f === '/' && partial) { - return true; - } - const options = this.options; - // windows: need to use /, not \ - if (path.sep !== '/') { - f = f.split(path.sep).join('/'); - } - // treat the test path as a set of pathparts. - const ff = this.slashSplit(f); - this.debug(this.pattern, 'split', ff); - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - const set = this.set; - this.debug(this.pattern, 'set', set); - // Find the basename of the path by looking for the last non-empty segment - let filename = ff[ff.length - 1]; - if (!filename) { - for (let i = ff.length - 2; !filename && i >= 0; i--) { - filename = ff[i]; - } - } - for (let i = 0; i < set.length; i++) { - const pattern = set[i]; - let file = ff; - if (options.matchBase && pattern.length === 1) { - file = [filename]; - } - const hit = this.matchOne(file, pattern, partial); - if (hit) { - if (options.flipNegate) { - return true; - } - return !this.negate; - } - } - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) { - return false; - } - return this.negate; - } - static defaults(def) { - return minimatch.defaults(def).Minimatch; - } -} -minimatch.Minimatch = Minimatch; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/@tufjs/models/node_modules/minimatch/dist/mjs/package.json b/node_modules/@tufjs/models/node_modules/minimatch/dist/mjs/package.json deleted file mode 100644 index 3dbc1ca591c05..0000000000000 --- a/node_modules/@tufjs/models/node_modules/minimatch/dist/mjs/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/node_modules/@tufjs/models/node_modules/minimatch/package.json b/node_modules/@tufjs/models/node_modules/minimatch/package.json deleted file mode 100644 index 58f289adf75e7..0000000000000 --- a/node_modules/@tufjs/models/node_modules/minimatch/package.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "author": "Isaac Z. Schlueter (http://blog.izs.me)", - "name": "minimatch", - "description": "a glob matcher in javascript", - "version": "6.2.0", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/minimatch.git" - }, - "main": "./dist/cjs/index-cjs.js", - "module": "./dist/mjs/index.js", - "types": "./dist/cjs/index.d.ts", - "exports": { - ".": { - "import": { - "types": "./dist/mjs/index.d.ts", - "default": "./dist/mjs/index.js" - }, - "require": { - "types": "./dist/cjs/index-cjs.d.ts", - "default": "./dist/cjs/index-cjs.js" - } - } - }, - "files": [ - "dist" - ], - "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "preprepare": "rm -rf dist", - "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json", - "postprepare": "bash fixup.sh", - "pretest": "npm run prepare", - "presnap": "npm run prepare", - "test": "c8 tap", - "snap": "c8 tap", - "format": "prettier --write . --loglevel warn", - "benchmark": "node benchmark/index.js", - "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts" - }, - "prettier": { - "semi": false, - "printWidth": 80, - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "jsxSingleQuote": false, - "bracketSameLine": true, - "arrowParens": "avoid", - "endOfLine": "lf" - }, - "engines": { - "node": ">=10" - }, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "devDependencies": { - "@types/brace-expansion": "^1.1.0", - "@types/node": "^18.11.9", - "@types/tap": "^15.0.7", - "c8": "^7.12.0", - "eslint-config-prettier": "^8.6.0", - "mkdirp": "1", - "prettier": "^2.8.2", - "tap": "^16.3.3", - "ts-node": "^10.9.1", - "typedoc": "^0.23.21", - "typescript": "^4.9.3" - }, - "tap": { - "coverage": false, - "node-arg": [ - "--no-warnings", - "--loader", - "ts-node/esm" - ], - "ts": false - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "license": "ISC" -} diff --git a/node_modules/@tufjs/models/package.json b/node_modules/@tufjs/models/package.json index f3746c27041fd..d8b2a189a1425 100644 --- a/node_modules/@tufjs/models/package.json +++ b/node_modules/@tufjs/models/package.json @@ -1,6 +1,6 @@ { "name": "@tufjs/models", - "version": "1.0.0", + "version": "1.0.1", "description": "TUF metadata models", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -26,14 +26,14 @@ "bugs": { "url": "https://github.com/theupdateframework/tuf-js/issues" }, - "homepage": "https://github.com/theupdateframework/tuf-js/packages/models#readme", + "homepage": "https://github.com/theupdateframework/tuf-js/tree/main/packages/models#readme", "devDependencies": { "@types/minimatch": "^5.1.2", - "@types/node": "^18.14.1", + "@types/node": "^18.15.3", "typescript": "^4.9.5" }, "dependencies": { - "minimatch": "^6.1.0" + "minimatch": "^7.4.2" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" diff --git a/node_modules/minimatch/dist/cjs/_parse.js b/node_modules/minimatch/dist/cjs/_parse.js new file mode 100644 index 0000000000000..4387a26171dfe --- /dev/null +++ b/node_modules/minimatch/dist/cjs/_parse.js @@ -0,0 +1,300 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.parse = void 0; +// parse a single path portion +const brace_expressions_js_1 = require("./brace-expressions.js"); +const assert_valid_pattern_js_1 = require("./assert-valid-pattern.js"); +const globUnescape = (s) => s.replace(/\\(.)/g, '$1'); +const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +// "abc" -> { a:true, b:true, c:true } +const charSet = (s) => s.split('').reduce((set, c) => { + set[c] = true; + return set; +}, {}); +const plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)' }, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' }, +}; +// characters that need to be escaped in RegExp. +const reSpecials = charSet('().*{}+?[]^$\\!'); +// characters that indicate we have to add the pattern start +const addPatternStartSet = charSet('[.('); +// any single thing other than / +// don't need to escape / when using new RegExp() +const qmark = '[^/]'; +// * => any number of characters +const star = qmark + '*?'; +// TODO: take an offset and length, so we can sub-parse the extglobs +const parse = (options, pattern, debug) => { + (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); + if (pattern === '') + return ''; + let re = ''; + let hasMagic = false; + let escaping = false; + // ? => one single character + const patternListStack = []; + const negativeLists = []; + let stateChar = false; + let uflag = false; + let pl; + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. However, if the pattern + // starts with ., then traversal patterns can match. + let dotTravAllowed = pattern.charAt(0) === '.'; + let dotFileAllowed = options.dot || dotTravAllowed; + const patternStart = () => dotTravAllowed + ? '' + : dotFileAllowed + ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' + : '(?!\\.)'; + const subPatternStart = (p) => p.charAt(0) === '.' + ? '' + : options.dot + ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' + : '(?!\\.)'; + const clearStateChar = () => { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star; + hasMagic = true; + break; + case '?': + re += qmark; + hasMagic = true; + break; + default: + re += '\\' + stateChar; + break; + } + debug('clearStateChar %j %j', stateChar, re); + stateChar = false; + } + }; + for (let i = 0, c; i < pattern.length && (c = pattern.charAt(i)); i++) { + debug('%s\t%s %s %j', pattern, i, re, c); + // skip over any that are escaped. + if (escaping) { + // completely not allowed, even escaped. + // should be impossible. + /* c8 ignore start */ + if (c === '/') { + return false; + } + /* c8 ignore stop */ + if (reSpecials[c]) { + re += '\\'; + } + re += c; + escaping = false; + continue; + } + switch (c) { + // Should already be path-split by now. + /* c8 ignore start */ + case '/': { + return false; + } + /* c8 ignore stop */ + case '\\': + clearStateChar(); + escaping = true; + continue; + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c); + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + debug('call clearStateChar %j', stateChar); + clearStateChar(); + stateChar = c; + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) + clearStateChar(); + continue; + case '(': { + if (!stateChar) { + re += '\\('; + continue; + } + const plEntry = { + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close, + }; + debug(pattern, '\t', plEntry); + patternListStack.push(plEntry); + // negation is (?:(?!(?:js)(?:))[^/]*) + re += plEntry.open; + // next entry starts with a dot maybe? + if (plEntry.start === 0 && plEntry.type !== '!') { + dotTravAllowed = true; + re += subPatternStart(pattern.slice(i + 1)); + } + debug('plType %j %j', stateChar, re); + stateChar = false; + continue; + } + case ')': { + const plEntry = patternListStack[patternListStack.length - 1]; + if (!plEntry) { + re += '\\)'; + continue; + } + patternListStack.pop(); + // closing an extglob + clearStateChar(); + hasMagic = true; + pl = plEntry; + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close; + if (pl.type === '!') { + negativeLists.push(Object.assign(pl, { reEnd: re.length })); + } + continue; + } + case '|': { + const plEntry = patternListStack[patternListStack.length - 1]; + if (!plEntry) { + re += '\\|'; + continue; + } + clearStateChar(); + re += '|'; + // next subpattern can start with a dot? + if (plEntry.start === 0 && plEntry.type !== '!') { + dotTravAllowed = true; + re += subPatternStart(pattern.slice(i + 1)); + } + continue; + } + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar(); + const [src, needUflag, consumed, magic] = (0, brace_expressions_js_1.parseClass)(pattern, i); + if (consumed) { + re += src; + uflag = uflag || needUflag; + i += consumed - 1; + hasMagic = hasMagic || magic; + } + else { + re += '\\['; + } + continue; + case ']': + re += '\\' + c; + continue; + default: + // swallow any state char that wasn't consumed + clearStateChar(); + re += regExpEscape(c); + break; + } // switch + } // for + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + let tail; + tail = re.slice(pl.reStart + pl.open.length); + debug(pattern, 'setting tail', re, pl); + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, (_, $1, $2) => { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\'; + // should already be done + /* c8 ignore start */ + } + /* c8 ignore stop */ + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|'; + }); + debug('tail=%j\n %s', tail, tail, pl, re); + const t = pl.type === '*' ? star : pl.type === '?' ? qmark : '\\' + pl.type; + hasMagic = true; + re = re.slice(0, pl.reStart) + t + '\\(' + tail; + } + // handle trailing things that only matter at the very end. + clearStateChar(); + if (escaping) { + // trailing \\ + re += '\\\\'; + } + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + const addPatternStart = addPatternStartSet[re.charAt(0)]; + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (let n = negativeLists.length - 1; n > -1; n--) { + const nl = negativeLists[n]; + const nlBefore = re.slice(0, nl.reStart); + const nlFirst = re.slice(nl.reStart, nl.reEnd - 8); + let nlAfter = re.slice(nl.reEnd); + const nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + nlAfter; + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + const closeParensBefore = nlBefore.split(')').length; + const openParensBefore = nlBefore.split('(').length - closeParensBefore; + let cleanAfter = nlAfter; + for (let i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, ''); + } + nlAfter = cleanAfter; + const dollar = nlAfter === '' ? '(?:$|\\/)' : ''; + re = nlBefore + nlFirst + nlAfter + dollar + nlLast; + } + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re; + } + if (addPatternStart) { + re = patternStart() + re; + } + // if it's nocase, and the lcase/uppercase don't match, it's magic + if (options.nocase && !hasMagic && !options.nocaseMagicOnly) { + hasMagic = pattern.toUpperCase() !== pattern.toLowerCase(); + } + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(re); + } + return re; +}; +exports.parse = parse; +//# sourceMappingURL=_parse.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/cjs/assert-valid-pattern.js b/node_modules/minimatch/dist/cjs/assert-valid-pattern.js new file mode 100644 index 0000000000000..5fc86bbd0116c --- /dev/null +++ b/node_modules/minimatch/dist/cjs/assert-valid-pattern.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.assertValidPattern = void 0; +const MAX_PATTERN_LENGTH = 1024 * 64; +const assertValidPattern = (pattern) => { + if (typeof pattern !== 'string') { + throw new TypeError('invalid pattern'); + } + if (pattern.length > MAX_PATTERN_LENGTH) { + throw new TypeError('pattern is too long'); + } +}; +exports.assertValidPattern = assertValidPattern; +//# sourceMappingURL=assert-valid-pattern.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/cjs/extglob.js b/node_modules/minimatch/dist/cjs/extglob.js new file mode 100644 index 0000000000000..8d7607b7f7ead --- /dev/null +++ b/node_modules/minimatch/dist/cjs/extglob.js @@ -0,0 +1,4 @@ +"use strict"; +// translate an extglob into a regular expression +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=extglob.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/cjs/parse.js b/node_modules/minimatch/dist/cjs/parse.js new file mode 100644 index 0000000000000..2fff625bcbb6e --- /dev/null +++ b/node_modules/minimatch/dist/cjs/parse.js @@ -0,0 +1,650 @@ +"use strict"; +// parse a single path portion +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AST = void 0; +const brace_expressions_1 = require("./brace-expressions"); +const types = new Set(['!', '?', '+', '*', '@']); +const isExtglobType = (c) => types.has(c); +// characters that indicate a start of pattern needs the "no dots" bit +const addPatternStart = new Set(['[', '.']); +const justDots = new Set(['..', '.']); +const reSpecials = new Set('().*{}+?[]^$\\!'); +const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +// any single thing other than / +// don't need to escape / when using new RegExp() +const qmark = '[^/]'; +// * => any number of characters +const star = qmark + '*?'; +class AST { + type; + #root; + #parts = []; + #parent; + #parentIndex; + #negs; + #filledNegs = false; + #options; + constructor(type, parent, options = {}) { + this.type = type; + this.#parent = parent; + this.#root = this.#parent ? this.#parent.#root : this; + this.#options = this.#root === this ? options : this.#root.#options; + this.#negs = this.#root === this ? [] : this.#root.#negs; + if (type === '!' && !this.#root.#filledNegs) + this.#negs.push(this); + this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0; + } + fillNegs() { + if (this !== this.#root) { + this.#root.fillNegs(); + return this; + } + if (this.#filledNegs) + return this; + this.#filledNegs = true; + let n; + while ((n = this.#negs.pop())) { + if (n.type !== '!') + continue; + // walk up the tree, appending everthing that comes AFTER parentIndex + let p = n; + let pp = p.#parent; + while (pp) { + for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) { + for (const part of n.#parts) { + /* c8 ignore start */ + if (typeof part === 'string') { + throw new Error('string part in extglob AST??'); + } + /* c8 ignore stop */ + part.copyIn(pp.#parts[i]); + } + } + p = pp; + pp = p.#parent; + } + } + return this; + } + push(...parts) { + for (const p of parts) { + if (p === '') + continue; + /* c8 ignore start */ + if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) { + throw new Error('invalid part: ' + p); + } + /* c8 ignore stop */ + this.#parts.push(p); + } + } + toJSON() { + const ret = this.type === null ? this.#parts.slice() : [this.type, ...this.#parts]; + if (this.isStart() && !this.type) + ret.unshift([]); + if (this.isEnd() && + (this === this.#root || + (this.#root.#filledNegs && this.#parent?.type === '!'))) { + ret.push({}); + } + return ret; + } + isStart() { + if (this.#root === this) + return true; + // if (this.type) return !!this.#parent?.isStart() + if (!this.#parent?.isStart()) + return false; + return this.#parentIndex === 0; + } + isEnd() { + if (this.#root === this) + return true; + if (this.#parent?.type === '!') + return true; + if (!this.#parent?.isEnd()) + return false; + if (!this.type) + return this.#parent?.isEnd(); + return (this.#parentIndex === (this.#parent ? this.#parent.#parts.length : 0) - 1); + } + copyIn(part) { + if (typeof part === 'string') + this.push(part); + else + this.push(part.clone(this)); + } + clone(parent) { + const c = new AST(this.type, parent); + for (const p of this.#parts) { + c.copyIn(p); + } + return c; + } + static #parseAST(str, ast, pos, opt) { + let escaping = false; + if (ast.type === null) { + // outside of a extglob, append until we find a start + let i = pos; + let acc = ''; + while (i < str.length) { + const c = str.charAt(i++); + // still accumulate escapes at this point, but we do ignore + // starts that are escaped + if (escaping || c === '\\') { + escaping = !escaping; + acc += c; + continue; + } + if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') { + ast.push(acc); + acc = ''; + const ext = new AST(c, ast); + i = AST.#parseAST(str, ext, i, opt); + ast.push(ext); + continue; + } + acc += c; + } + ast.push(acc); + return i; + } + // some kind of extglob, pos is at the ( + // find the next | or ) + let i = pos + 1; + let part = new AST(null, ast); + const parts = []; + let acc = ''; + while (i < str.length) { + const c = str.charAt(i++); + // still accumulate escapes at this point, but we do ignore + // starts that are escaped + if (escaping || c === '\\') { + escaping = !escaping; + acc += c; + continue; + } + if (isExtglobType(c) && str.charAt(i) === '(') { + part.push(acc); + acc = ''; + const ext = new AST(c, part); + part.push(ext); + i = AST.#parseAST(str, ext, i, opt); + continue; + } + if (c === '|') { + part.push(acc); + acc = ''; + parts.push(part); + part = new AST(null, ast); + continue; + } + if (c === ')') { + part.push(acc); + acc = ''; + ast.push(...parts, part); + return i; + } + acc += c; + } + // if we got here, it was a malformed extglob! not an extglob, but + // maybe something else in there. + ast.type = null; + ast.#parts = [str.substring(pos)]; + return i; + } + static fromGlob(pattern, options = {}) { + const ast = new AST(null, undefined, options); + AST.#parseAST(pattern, ast, 0, options); + console.log('parsed', pattern, JSON.stringify(ast)); + return ast; + } + toRegExpSource() { + if (this.#root === this) + this.fillNegs(); + if (!this.type) { + const src = this.#parts + .map(p => { + if (typeof p === 'string') + return AST.#parseGlob(p, this.#options); + else + return p.toRegExpSource(); + }) + .join(''); + let start = ''; + if (this.isStart() && typeof this.#parts[0] === 'string') { + // '.' and '..' cannot match unless the pattern is that exactly + const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]); + if (dotTravAllowed) { + start = '(?:^|\\/)'; + } + else { + const dotsAllowed = this.#options.dot || + // no need to prevent dots if it can't match a dot, or if a sub-pattern + // will be preventing it anyway. + !addPatternStart.has(src.charAt(0)); + start = dotsAllowed ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' : '(?!\\.)'; + } + } + let end = ''; + if (this.isEnd() && + (this === this.#root || + (this.#root.#filledNegs && this.#parent?.type === '!'))) { + end = '(?:$|\\/)'; + } + return start + src + end; + } + // some kind of extglob + const start = this.type === '!' ? '(?:(?!(?:' : '(?:'; + const body = this.#parts + .map(p => { + /* c8 ignore start */ + if (typeof p === 'string') { + throw new Error('string type in extglob ast??'); + } + /* c8 ignore stop */ + return p.toRegExpSource(); + }) + .join('|'); + const close = this.type === '!' + ? '))[^/]*?)' + : this.type === '@' + ? ')' + : `)${this.type}`; + return start + body + close; + } + static #parseGlob(glob, options) { + let escaping = false; + let re = ''; + let uflag = false; + let hasMagic = false; + for (let i = 0; i < glob.length; i++) { + const c = glob.charAt(i); + if (escaping) { + escaping = false; + re += (reSpecials.has(c) ? '\\' : '') + c; + continue; + } + if (c === '\\') { + if (i === glob.length - 1) { + re += '\\\\'; + } + else { + escaping = true; + } + continue; + } + if (c === '[') { + const [src, needUflag, consumed, magic] = (0, brace_expressions_1.parseClass)(glob, i); + if (consumed) { + re += src; + uflag = uflag || needUflag; + i += consumed - 1; + hasMagic = hasMagic || magic; + continue; + } + } + if (c === '*') { + re += star; + hasMagic = true; + continue; + } + if (c === '?') { + re += qmark; + hasMagic = true; + continue; + } + re += regExpEscape(c); + } + return re; + } +} +exports.AST = AST; +const pattern = 'a@(i|w!(x|y)z+(l|m)|j)'; +const ast = AST.fromGlob(pattern).fillNegs(); +console.log('negged', pattern, JSON.stringify(ast)); +console.log('to re src', pattern, ast.toRegExpSource()); +// // the type (exttype or null for strings), and array of children tokens +// +// // append everything after a negative extglob to each of the parts +// // of the negative extglob node. So, eg, [a, [!, x, y], z] +// +// // +// // +// // +// // +// +// const globUnescape = (s: string) => s.replace(/\\(.)/g, '$1') +// const regExpEscape = (s: string) => +// s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +// +// // "abc" -> { a:true, b:true, c:true } +// const charSet = (s: string) => +// s.split('').reduce((set: { [k: string]: boolean }, c) => { +// set[c] = true +// return set +// }, {}) +// +// // characters that need to be escaped in RegExp. +// const reSpecials = charSet('().*{}+?[]^$\\!') +// +// // characters that indicate we have to add the pattern start +// const addPatternStartSet = charSet('[.(') +// +// // any single thing other than / +// // don't need to escape / when using new RegExp() +// const qmark = '[^/]' +// +// // * => any number of characters +// const star = qmark + '*?' +// +// // TODO: take an offset and length, so we can sub-parse the extglobs +// const parse = ( +// options: MinimatchOptions, +// pattern: string, +// debug: (...a: any[]) => void +// ): false | string => { +// assertValidPattern(pattern) +// +// if (pattern === '') return '' +// +// let re = '' +// let hasMagic = false +// let escaping = false +// // ? => one single character +// let uflag = false +// +// // . and .. never match anything that doesn't start with ., +// // even when options.dot is set. However, if the pattern +// // starts with ., then traversal patterns can match. +// let dotTravAllowed = pattern.charAt(0) === '.' +// let dotFileAllowed = options.dot || dotTravAllowed +// const patternStart = () => +// dotTravAllowed +// ? '' +// : dotFileAllowed +// ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' +// : '(?!\\.)' +// const subPatternStart = (p: string) => +// p.charAt(0) === '.' +// ? '' +// : options.dot +// ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' +// : '(?!\\.)' +// +// const clearStateChar = () => { +// if (stateChar) { +// // we had some state-tracking character +// // that wasn't consumed by this pass. +// switch (stateChar) { +// case '*': +// re += star +// hasMagic = true +// break +// case '?': +// re += qmark +// hasMagic = true +// break +// default: +// re += '\\' + stateChar +// break +// } +// debug('clearStateChar %j %j', stateChar, re) +// stateChar = false +// } +// } +// +// for ( +// let i = 0, c: string; +// i < pattern.length && (c = pattern.charAt(i)); +// i++ +// ) { +// debug('%s\t%s %s %j', pattern, i, re, c) +// +// // skip over any that are escaped. +// if (escaping) { +// // completely not allowed, even escaped. +// // should be impossible. +// /* c8 ignore start */ +// if (c === '/') { +// return false +// } +// /* c8 ignore stop */ +// +// if (reSpecials[c]) { +// re += '\\' +// } +// re += c +// escaping = false +// continue +// } +// +// switch (c) { +// // Should already be path-split by now. +// /* c8 ignore start */ +// case '/': { +// return false +// } +// /* c8 ignore stop */ +// +// case '\\': +// clearStateChar() +// escaping = true +// continue +// +// // the various stateChar values +// // for the "extglob" stuff. +// case '?': +// case '*': +// case '+': +// case '@': +// case '!': +// debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) +// +// // if we already have a stateChar, then it means +// // that there was something like ** or +? in there. +// // Handle the stateChar, then proceed with this one. +// debug('call clearStateChar %j', stateChar) +// clearStateChar() +// stateChar = c +// // if extglob is disabled, then +(asdf|foo) isn't a thing. +// // just clear the statechar *now*, rather than even diving into +// // the patternList stuff. +// if (options.noext) clearStateChar() +// continue +// +// case '(': { +// if (!stateChar) { +// re += '\\(' +// continue +// } +// +// const plEntry: PatternListEntry = { +// type: stateChar, +// start: i - 1, +// reStart: re.length, +// open: plTypes[stateChar].open, +// close: plTypes[stateChar].close, +// } +// debug(pattern, '\t', plEntry) +// patternListStack.push(plEntry) +// // negation is (?:(?!(?:js)(?:))[^/]*) +// re += plEntry.open +// // next entry starts with a dot maybe? +// if (plEntry.start === 0 && plEntry.type !== '!') { +// dotTravAllowed = true +// re += subPatternStart(pattern.slice(i + 1)) +// } +// debug('plType %j %j', stateChar, re) +// stateChar = false +// continue +// } +// +// case ')': { +// const plEntry = patternListStack[patternListStack.length - 1] +// if (!plEntry) { +// re += '\\)' +// continue +// } +// patternListStack.pop() +// +// // closing an extglob +// clearStateChar() +// hasMagic = true +// pl = plEntry +// // negation is (?:(?!js)[^/]*) +// // The others are (?:) +// re += pl.close +// if (pl.type === '!') { +// negativeLists.push(Object.assign(pl, { reEnd: re.length })) +// } +// continue +// } +// +// case '|': { +// const plEntry = patternListStack[patternListStack.length - 1] +// if (!plEntry) { +// re += '\\|' +// continue +// } +// +// clearStateChar() +// re += '|' +// // next subpattern can start with a dot? +// if (plEntry.start === 0 && plEntry.type !== '!') { +// dotTravAllowed = true +// re += subPatternStart(pattern.slice(i + 1)) +// } +// continue +// } +// +// // these are mostly the same in regexp and glob +// case '[': +// // swallow any state-tracking char before the [ +// clearStateChar() +// const [src, needUflag, consumed, magic] = parseClass(pattern, i) +// if (consumed) { +// re += src +// uflag = uflag || needUflag +// i += consumed - 1 +// hasMagic = hasMagic || magic +// } else { +// re += '\\[' +// } +// continue +// +// case ']': +// re += '\\' + c +// continue +// +// default: +// // swallow any state char that wasn't consumed +// clearStateChar() +// +// re += regExpEscape(c) +// break +// } // switch +// } // for +// +// // handle the case where we had a +( thing at the *end* +// // of the pattern. +// // each pattern list stack adds 3 chars, and we need to go through +// // and escape any | chars that were passed through as-is for the regexp. +// // Go through and escape them, taking care not to double-escape any +// // | chars that were already escaped. +// for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { +// let tail: string +// tail = re.slice(pl.reStart + pl.open.length) +// debug(pattern, 'setting tail', re, pl) +// // maybe some even number of \, then maybe 1 \, followed by a | +// tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, (_, $1, $2) => { +// if (!$2) { +// // the | isn't already escaped, so escape it. +// $2 = '\\' +// // should already be done +// /* c8 ignore start */ +// } +// /* c8 ignore stop */ +// +// // need to escape all those slashes *again*, without escaping the +// // one that we need for escaping the | character. As it works out, +// // escaping an even number of slashes can be done by simply repeating +// // it exactly after itself. That's why this trick works. +// // +// // I am sorry that you have to see this. +// return $1 + $1 + $2 + '|' +// }) +// +// debug('tail=%j\n %s', tail, tail, pl, re) +// const t = pl.type === '*' ? star : pl.type === '?' ? qmark : '\\' + pl.type +// +// hasMagic = true +// re = re.slice(0, pl.reStart) + t + '\\(' + tail +// } +// +// // handle trailing things that only matter at the very end. +// clearStateChar() +// if (escaping) { +// // trailing \\ +// re += '\\\\' +// } +// +// // only need to apply the nodot start if the re starts with +// // something that could conceivably capture a dot +// const addPatternStart = addPatternStartSet[re.charAt(0)] +// +// // Hack to work around lack of negative lookbehind in JS +// // A pattern like: *.!(x).!(y|z) needs to ensure that a name +// // like 'a.xyz.yz' doesn't match. So, the first negative +// // lookahead, has to look ALL the way ahead, to the end of +// // the pattern. +// for (let n = negativeLists.length - 1; n > -1; n--) { +// const nl = negativeLists[n] +// +// const nlBefore = re.slice(0, nl.reStart) +// const nlFirst = re.slice(nl.reStart, nl.reEnd - 8) +// let nlAfter = re.slice(nl.reEnd) +// const nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + nlAfter +// +// // Handle nested stuff like *(*.js|!(*.json)), where open parens +// // mean that we should *not* include the ) in the bit that is considered +// // "after" the negated section. +// const closeParensBefore = nlBefore.split(')').length +// const openParensBefore = nlBefore.split('(').length - closeParensBefore +// let cleanAfter = nlAfter +// for (let i = 0; i < openParensBefore; i++) { +// cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') +// } +// nlAfter = cleanAfter +// +// const dollar = nlAfter === '' ? '(?:$|\\/)' : '' +// +// re = nlBefore + nlFirst + nlAfter + dollar + nlLast +// } +// +// // if the re is not "" at this point, then we need to make sure +// // it doesn't match against an empty path part. +// // Otherwise a/* will match a/, which it should not. +// if (re !== '' && hasMagic) { +// re = '(?=.)' + re +// } +// +// if (addPatternStart) { +// re = patternStart() + re +// } +// +// // if it's nocase, and the lcase/uppercase don't match, it's magic +// if (options.nocase && !hasMagic && !options.nocaseMagicOnly) { +// hasMagic = pattern.toUpperCase() !== pattern.toLowerCase() +// } +// +// // skip the regexp for non-magical patterns +// // unescape anything in it, though, so that it'll be +// // an exact match against a file etc. +// if (!hasMagic) { +// return globUnescape(re) +// } +// +// return re +// } +//# sourceMappingURL=parse.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/mjs/_parse.js b/node_modules/minimatch/dist/mjs/_parse.js new file mode 100644 index 0000000000000..db6a28ab08a74 --- /dev/null +++ b/node_modules/minimatch/dist/mjs/_parse.js @@ -0,0 +1,296 @@ +// parse a single path portion +import { parseClass } from './brace-expressions.js'; +import { assertValidPattern } from './assert-valid-pattern.js'; +const globUnescape = (s) => s.replace(/\\(.)/g, '$1'); +const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +// "abc" -> { a:true, b:true, c:true } +const charSet = (s) => s.split('').reduce((set, c) => { + set[c] = true; + return set; +}, {}); +const plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)' }, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' }, +}; +// characters that need to be escaped in RegExp. +const reSpecials = charSet('().*{}+?[]^$\\!'); +// characters that indicate we have to add the pattern start +const addPatternStartSet = charSet('[.('); +// any single thing other than / +// don't need to escape / when using new RegExp() +const qmark = '[^/]'; +// * => any number of characters +const star = qmark + '*?'; +// TODO: take an offset and length, so we can sub-parse the extglobs +export const parse = (options, pattern, debug) => { + assertValidPattern(pattern); + if (pattern === '') + return ''; + let re = ''; + let hasMagic = false; + let escaping = false; + // ? => one single character + const patternListStack = []; + const negativeLists = []; + let stateChar = false; + let uflag = false; + let pl; + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. However, if the pattern + // starts with ., then traversal patterns can match. + let dotTravAllowed = pattern.charAt(0) === '.'; + let dotFileAllowed = options.dot || dotTravAllowed; + const patternStart = () => dotTravAllowed + ? '' + : dotFileAllowed + ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' + : '(?!\\.)'; + const subPatternStart = (p) => p.charAt(0) === '.' + ? '' + : options.dot + ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' + : '(?!\\.)'; + const clearStateChar = () => { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star; + hasMagic = true; + break; + case '?': + re += qmark; + hasMagic = true; + break; + default: + re += '\\' + stateChar; + break; + } + debug('clearStateChar %j %j', stateChar, re); + stateChar = false; + } + }; + for (let i = 0, c; i < pattern.length && (c = pattern.charAt(i)); i++) { + debug('%s\t%s %s %j', pattern, i, re, c); + // skip over any that are escaped. + if (escaping) { + // completely not allowed, even escaped. + // should be impossible. + /* c8 ignore start */ + if (c === '/') { + return false; + } + /* c8 ignore stop */ + if (reSpecials[c]) { + re += '\\'; + } + re += c; + escaping = false; + continue; + } + switch (c) { + // Should already be path-split by now. + /* c8 ignore start */ + case '/': { + return false; + } + /* c8 ignore stop */ + case '\\': + clearStateChar(); + escaping = true; + continue; + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c); + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + debug('call clearStateChar %j', stateChar); + clearStateChar(); + stateChar = c; + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) + clearStateChar(); + continue; + case '(': { + if (!stateChar) { + re += '\\('; + continue; + } + const plEntry = { + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close, + }; + debug(pattern, '\t', plEntry); + patternListStack.push(plEntry); + // negation is (?:(?!(?:js)(?:))[^/]*) + re += plEntry.open; + // next entry starts with a dot maybe? + if (plEntry.start === 0 && plEntry.type !== '!') { + dotTravAllowed = true; + re += subPatternStart(pattern.slice(i + 1)); + } + debug('plType %j %j', stateChar, re); + stateChar = false; + continue; + } + case ')': { + const plEntry = patternListStack[patternListStack.length - 1]; + if (!plEntry) { + re += '\\)'; + continue; + } + patternListStack.pop(); + // closing an extglob + clearStateChar(); + hasMagic = true; + pl = plEntry; + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close; + if (pl.type === '!') { + negativeLists.push(Object.assign(pl, { reEnd: re.length })); + } + continue; + } + case '|': { + const plEntry = patternListStack[patternListStack.length - 1]; + if (!plEntry) { + re += '\\|'; + continue; + } + clearStateChar(); + re += '|'; + // next subpattern can start with a dot? + if (plEntry.start === 0 && plEntry.type !== '!') { + dotTravAllowed = true; + re += subPatternStart(pattern.slice(i + 1)); + } + continue; + } + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar(); + const [src, needUflag, consumed, magic] = parseClass(pattern, i); + if (consumed) { + re += src; + uflag = uflag || needUflag; + i += consumed - 1; + hasMagic = hasMagic || magic; + } + else { + re += '\\['; + } + continue; + case ']': + re += '\\' + c; + continue; + default: + // swallow any state char that wasn't consumed + clearStateChar(); + re += regExpEscape(c); + break; + } // switch + } // for + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + let tail; + tail = re.slice(pl.reStart + pl.open.length); + debug(pattern, 'setting tail', re, pl); + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, (_, $1, $2) => { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\'; + // should already be done + /* c8 ignore start */ + } + /* c8 ignore stop */ + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|'; + }); + debug('tail=%j\n %s', tail, tail, pl, re); + const t = pl.type === '*' ? star : pl.type === '?' ? qmark : '\\' + pl.type; + hasMagic = true; + re = re.slice(0, pl.reStart) + t + '\\(' + tail; + } + // handle trailing things that only matter at the very end. + clearStateChar(); + if (escaping) { + // trailing \\ + re += '\\\\'; + } + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + const addPatternStart = addPatternStartSet[re.charAt(0)]; + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (let n = negativeLists.length - 1; n > -1; n--) { + const nl = negativeLists[n]; + const nlBefore = re.slice(0, nl.reStart); + const nlFirst = re.slice(nl.reStart, nl.reEnd - 8); + let nlAfter = re.slice(nl.reEnd); + const nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + nlAfter; + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + const closeParensBefore = nlBefore.split(')').length; + const openParensBefore = nlBefore.split('(').length - closeParensBefore; + let cleanAfter = nlAfter; + for (let i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, ''); + } + nlAfter = cleanAfter; + const dollar = nlAfter === '' ? '(?:$|\\/)' : ''; + re = nlBefore + nlFirst + nlAfter + dollar + nlLast; + } + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re; + } + if (addPatternStart) { + re = patternStart() + re; + } + // if it's nocase, and the lcase/uppercase don't match, it's magic + if (options.nocase && !hasMagic && !options.nocaseMagicOnly) { + hasMagic = pattern.toUpperCase() !== pattern.toLowerCase(); + } + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(re); + } + return re; +}; +//# sourceMappingURL=_parse.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/mjs/assert-valid-pattern.js b/node_modules/minimatch/dist/mjs/assert-valid-pattern.js new file mode 100644 index 0000000000000..7b534fc30200b --- /dev/null +++ b/node_modules/minimatch/dist/mjs/assert-valid-pattern.js @@ -0,0 +1,10 @@ +const MAX_PATTERN_LENGTH = 1024 * 64; +export const assertValidPattern = (pattern) => { + if (typeof pattern !== 'string') { + throw new TypeError('invalid pattern'); + } + if (pattern.length > MAX_PATTERN_LENGTH) { + throw new TypeError('pattern is too long'); + } +}; +//# sourceMappingURL=assert-valid-pattern.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/mjs/extglob.js b/node_modules/minimatch/dist/mjs/extglob.js new file mode 100644 index 0000000000000..4033f4d60e34d --- /dev/null +++ b/node_modules/minimatch/dist/mjs/extglob.js @@ -0,0 +1,3 @@ +// translate an extglob into a regular expression +export {}; +//# sourceMappingURL=extglob.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/mjs/parse.js b/node_modules/minimatch/dist/mjs/parse.js new file mode 100644 index 0000000000000..70a26dee58f30 --- /dev/null +++ b/node_modules/minimatch/dist/mjs/parse.js @@ -0,0 +1,646 @@ +// parse a single path portion +import { parseClass } from './brace-expressions'; +const types = new Set(['!', '?', '+', '*', '@']); +const isExtglobType = (c) => types.has(c); +// characters that indicate a start of pattern needs the "no dots" bit +const addPatternStart = new Set(['[', '.']); +const justDots = new Set(['..', '.']); +const reSpecials = new Set('().*{}+?[]^$\\!'); +const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +// any single thing other than / +// don't need to escape / when using new RegExp() +const qmark = '[^/]'; +// * => any number of characters +const star = qmark + '*?'; +export class AST { + type; + #root; + #parts = []; + #parent; + #parentIndex; + #negs; + #filledNegs = false; + #options; + constructor(type, parent, options = {}) { + this.type = type; + this.#parent = parent; + this.#root = this.#parent ? this.#parent.#root : this; + this.#options = this.#root === this ? options : this.#root.#options; + this.#negs = this.#root === this ? [] : this.#root.#negs; + if (type === '!' && !this.#root.#filledNegs) + this.#negs.push(this); + this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0; + } + fillNegs() { + if (this !== this.#root) { + this.#root.fillNegs(); + return this; + } + if (this.#filledNegs) + return this; + this.#filledNegs = true; + let n; + while ((n = this.#negs.pop())) { + if (n.type !== '!') + continue; + // walk up the tree, appending everthing that comes AFTER parentIndex + let p = n; + let pp = p.#parent; + while (pp) { + for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) { + for (const part of n.#parts) { + /* c8 ignore start */ + if (typeof part === 'string') { + throw new Error('string part in extglob AST??'); + } + /* c8 ignore stop */ + part.copyIn(pp.#parts[i]); + } + } + p = pp; + pp = p.#parent; + } + } + return this; + } + push(...parts) { + for (const p of parts) { + if (p === '') + continue; + /* c8 ignore start */ + if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) { + throw new Error('invalid part: ' + p); + } + /* c8 ignore stop */ + this.#parts.push(p); + } + } + toJSON() { + const ret = this.type === null ? this.#parts.slice() : [this.type, ...this.#parts]; + if (this.isStart() && !this.type) + ret.unshift([]); + if (this.isEnd() && + (this === this.#root || + (this.#root.#filledNegs && this.#parent?.type === '!'))) { + ret.push({}); + } + return ret; + } + isStart() { + if (this.#root === this) + return true; + // if (this.type) return !!this.#parent?.isStart() + if (!this.#parent?.isStart()) + return false; + return this.#parentIndex === 0; + } + isEnd() { + if (this.#root === this) + return true; + if (this.#parent?.type === '!') + return true; + if (!this.#parent?.isEnd()) + return false; + if (!this.type) + return this.#parent?.isEnd(); + return (this.#parentIndex === (this.#parent ? this.#parent.#parts.length : 0) - 1); + } + copyIn(part) { + if (typeof part === 'string') + this.push(part); + else + this.push(part.clone(this)); + } + clone(parent) { + const c = new AST(this.type, parent); + for (const p of this.#parts) { + c.copyIn(p); + } + return c; + } + static #parseAST(str, ast, pos, opt) { + let escaping = false; + if (ast.type === null) { + // outside of a extglob, append until we find a start + let i = pos; + let acc = ''; + while (i < str.length) { + const c = str.charAt(i++); + // still accumulate escapes at this point, but we do ignore + // starts that are escaped + if (escaping || c === '\\') { + escaping = !escaping; + acc += c; + continue; + } + if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') { + ast.push(acc); + acc = ''; + const ext = new AST(c, ast); + i = AST.#parseAST(str, ext, i, opt); + ast.push(ext); + continue; + } + acc += c; + } + ast.push(acc); + return i; + } + // some kind of extglob, pos is at the ( + // find the next | or ) + let i = pos + 1; + let part = new AST(null, ast); + const parts = []; + let acc = ''; + while (i < str.length) { + const c = str.charAt(i++); + // still accumulate escapes at this point, but we do ignore + // starts that are escaped + if (escaping || c === '\\') { + escaping = !escaping; + acc += c; + continue; + } + if (isExtglobType(c) && str.charAt(i) === '(') { + part.push(acc); + acc = ''; + const ext = new AST(c, part); + part.push(ext); + i = AST.#parseAST(str, ext, i, opt); + continue; + } + if (c === '|') { + part.push(acc); + acc = ''; + parts.push(part); + part = new AST(null, ast); + continue; + } + if (c === ')') { + part.push(acc); + acc = ''; + ast.push(...parts, part); + return i; + } + acc += c; + } + // if we got here, it was a malformed extglob! not an extglob, but + // maybe something else in there. + ast.type = null; + ast.#parts = [str.substring(pos)]; + return i; + } + static fromGlob(pattern, options = {}) { + const ast = new AST(null, undefined, options); + AST.#parseAST(pattern, ast, 0, options); + console.log('parsed', pattern, JSON.stringify(ast)); + return ast; + } + toRegExpSource() { + if (this.#root === this) + this.fillNegs(); + if (!this.type) { + const src = this.#parts + .map(p => { + if (typeof p === 'string') + return AST.#parseGlob(p, this.#options); + else + return p.toRegExpSource(); + }) + .join(''); + let start = ''; + if (this.isStart() && typeof this.#parts[0] === 'string') { + // '.' and '..' cannot match unless the pattern is that exactly + const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]); + if (dotTravAllowed) { + start = '(?:^|\\/)'; + } + else { + const dotsAllowed = this.#options.dot || + // no need to prevent dots if it can't match a dot, or if a sub-pattern + // will be preventing it anyway. + !addPatternStart.has(src.charAt(0)); + start = dotsAllowed ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' : '(?!\\.)'; + } + } + let end = ''; + if (this.isEnd() && + (this === this.#root || + (this.#root.#filledNegs && this.#parent?.type === '!'))) { + end = '(?:$|\\/)'; + } + return start + src + end; + } + // some kind of extglob + const start = this.type === '!' ? '(?:(?!(?:' : '(?:'; + const body = this.#parts + .map(p => { + /* c8 ignore start */ + if (typeof p === 'string') { + throw new Error('string type in extglob ast??'); + } + /* c8 ignore stop */ + return p.toRegExpSource(); + }) + .join('|'); + const close = this.type === '!' + ? '))[^/]*?)' + : this.type === '@' + ? ')' + : `)${this.type}`; + return start + body + close; + } + static #parseGlob(glob, options) { + let escaping = false; + let re = ''; + let uflag = false; + let hasMagic = false; + for (let i = 0; i < glob.length; i++) { + const c = glob.charAt(i); + if (escaping) { + escaping = false; + re += (reSpecials.has(c) ? '\\' : '') + c; + continue; + } + if (c === '\\') { + if (i === glob.length - 1) { + re += '\\\\'; + } + else { + escaping = true; + } + continue; + } + if (c === '[') { + const [src, needUflag, consumed, magic] = parseClass(glob, i); + if (consumed) { + re += src; + uflag = uflag || needUflag; + i += consumed - 1; + hasMagic = hasMagic || magic; + continue; + } + } + if (c === '*') { + re += star; + hasMagic = true; + continue; + } + if (c === '?') { + re += qmark; + hasMagic = true; + continue; + } + re += regExpEscape(c); + } + return re; + } +} +const pattern = 'a@(i|w!(x|y)z+(l|m)|j)'; +const ast = AST.fromGlob(pattern).fillNegs(); +console.log('negged', pattern, JSON.stringify(ast)); +console.log('to re src', pattern, ast.toRegExpSource()); +// // the type (exttype or null for strings), and array of children tokens +// +// // append everything after a negative extglob to each of the parts +// // of the negative extglob node. So, eg, [a, [!, x, y], z] +// +// // +// // +// // +// // +// +// const globUnescape = (s: string) => s.replace(/\\(.)/g, '$1') +// const regExpEscape = (s: string) => +// s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +// +// // "abc" -> { a:true, b:true, c:true } +// const charSet = (s: string) => +// s.split('').reduce((set: { [k: string]: boolean }, c) => { +// set[c] = true +// return set +// }, {}) +// +// // characters that need to be escaped in RegExp. +// const reSpecials = charSet('().*{}+?[]^$\\!') +// +// // characters that indicate we have to add the pattern start +// const addPatternStartSet = charSet('[.(') +// +// // any single thing other than / +// // don't need to escape / when using new RegExp() +// const qmark = '[^/]' +// +// // * => any number of characters +// const star = qmark + '*?' +// +// // TODO: take an offset and length, so we can sub-parse the extglobs +// const parse = ( +// options: MinimatchOptions, +// pattern: string, +// debug: (...a: any[]) => void +// ): false | string => { +// assertValidPattern(pattern) +// +// if (pattern === '') return '' +// +// let re = '' +// let hasMagic = false +// let escaping = false +// // ? => one single character +// let uflag = false +// +// // . and .. never match anything that doesn't start with ., +// // even when options.dot is set. However, if the pattern +// // starts with ., then traversal patterns can match. +// let dotTravAllowed = pattern.charAt(0) === '.' +// let dotFileAllowed = options.dot || dotTravAllowed +// const patternStart = () => +// dotTravAllowed +// ? '' +// : dotFileAllowed +// ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' +// : '(?!\\.)' +// const subPatternStart = (p: string) => +// p.charAt(0) === '.' +// ? '' +// : options.dot +// ? '(?!(?:^|\\/)\\.{1,2}(?:$|\\/))' +// : '(?!\\.)' +// +// const clearStateChar = () => { +// if (stateChar) { +// // we had some state-tracking character +// // that wasn't consumed by this pass. +// switch (stateChar) { +// case '*': +// re += star +// hasMagic = true +// break +// case '?': +// re += qmark +// hasMagic = true +// break +// default: +// re += '\\' + stateChar +// break +// } +// debug('clearStateChar %j %j', stateChar, re) +// stateChar = false +// } +// } +// +// for ( +// let i = 0, c: string; +// i < pattern.length && (c = pattern.charAt(i)); +// i++ +// ) { +// debug('%s\t%s %s %j', pattern, i, re, c) +// +// // skip over any that are escaped. +// if (escaping) { +// // completely not allowed, even escaped. +// // should be impossible. +// /* c8 ignore start */ +// if (c === '/') { +// return false +// } +// /* c8 ignore stop */ +// +// if (reSpecials[c]) { +// re += '\\' +// } +// re += c +// escaping = false +// continue +// } +// +// switch (c) { +// // Should already be path-split by now. +// /* c8 ignore start */ +// case '/': { +// return false +// } +// /* c8 ignore stop */ +// +// case '\\': +// clearStateChar() +// escaping = true +// continue +// +// // the various stateChar values +// // for the "extglob" stuff. +// case '?': +// case '*': +// case '+': +// case '@': +// case '!': +// debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) +// +// // if we already have a stateChar, then it means +// // that there was something like ** or +? in there. +// // Handle the stateChar, then proceed with this one. +// debug('call clearStateChar %j', stateChar) +// clearStateChar() +// stateChar = c +// // if extglob is disabled, then +(asdf|foo) isn't a thing. +// // just clear the statechar *now*, rather than even diving into +// // the patternList stuff. +// if (options.noext) clearStateChar() +// continue +// +// case '(': { +// if (!stateChar) { +// re += '\\(' +// continue +// } +// +// const plEntry: PatternListEntry = { +// type: stateChar, +// start: i - 1, +// reStart: re.length, +// open: plTypes[stateChar].open, +// close: plTypes[stateChar].close, +// } +// debug(pattern, '\t', plEntry) +// patternListStack.push(plEntry) +// // negation is (?:(?!(?:js)(?:))[^/]*) +// re += plEntry.open +// // next entry starts with a dot maybe? +// if (plEntry.start === 0 && plEntry.type !== '!') { +// dotTravAllowed = true +// re += subPatternStart(pattern.slice(i + 1)) +// } +// debug('plType %j %j', stateChar, re) +// stateChar = false +// continue +// } +// +// case ')': { +// const plEntry = patternListStack[patternListStack.length - 1] +// if (!plEntry) { +// re += '\\)' +// continue +// } +// patternListStack.pop() +// +// // closing an extglob +// clearStateChar() +// hasMagic = true +// pl = plEntry +// // negation is (?:(?!js)[^/]*) +// // The others are (?:) +// re += pl.close +// if (pl.type === '!') { +// negativeLists.push(Object.assign(pl, { reEnd: re.length })) +// } +// continue +// } +// +// case '|': { +// const plEntry = patternListStack[patternListStack.length - 1] +// if (!plEntry) { +// re += '\\|' +// continue +// } +// +// clearStateChar() +// re += '|' +// // next subpattern can start with a dot? +// if (plEntry.start === 0 && plEntry.type !== '!') { +// dotTravAllowed = true +// re += subPatternStart(pattern.slice(i + 1)) +// } +// continue +// } +// +// // these are mostly the same in regexp and glob +// case '[': +// // swallow any state-tracking char before the [ +// clearStateChar() +// const [src, needUflag, consumed, magic] = parseClass(pattern, i) +// if (consumed) { +// re += src +// uflag = uflag || needUflag +// i += consumed - 1 +// hasMagic = hasMagic || magic +// } else { +// re += '\\[' +// } +// continue +// +// case ']': +// re += '\\' + c +// continue +// +// default: +// // swallow any state char that wasn't consumed +// clearStateChar() +// +// re += regExpEscape(c) +// break +// } // switch +// } // for +// +// // handle the case where we had a +( thing at the *end* +// // of the pattern. +// // each pattern list stack adds 3 chars, and we need to go through +// // and escape any | chars that were passed through as-is for the regexp. +// // Go through and escape them, taking care not to double-escape any +// // | chars that were already escaped. +// for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { +// let tail: string +// tail = re.slice(pl.reStart + pl.open.length) +// debug(pattern, 'setting tail', re, pl) +// // maybe some even number of \, then maybe 1 \, followed by a | +// tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, (_, $1, $2) => { +// if (!$2) { +// // the | isn't already escaped, so escape it. +// $2 = '\\' +// // should already be done +// /* c8 ignore start */ +// } +// /* c8 ignore stop */ +// +// // need to escape all those slashes *again*, without escaping the +// // one that we need for escaping the | character. As it works out, +// // escaping an even number of slashes can be done by simply repeating +// // it exactly after itself. That's why this trick works. +// // +// // I am sorry that you have to see this. +// return $1 + $1 + $2 + '|' +// }) +// +// debug('tail=%j\n %s', tail, tail, pl, re) +// const t = pl.type === '*' ? star : pl.type === '?' ? qmark : '\\' + pl.type +// +// hasMagic = true +// re = re.slice(0, pl.reStart) + t + '\\(' + tail +// } +// +// // handle trailing things that only matter at the very end. +// clearStateChar() +// if (escaping) { +// // trailing \\ +// re += '\\\\' +// } +// +// // only need to apply the nodot start if the re starts with +// // something that could conceivably capture a dot +// const addPatternStart = addPatternStartSet[re.charAt(0)] +// +// // Hack to work around lack of negative lookbehind in JS +// // A pattern like: *.!(x).!(y|z) needs to ensure that a name +// // like 'a.xyz.yz' doesn't match. So, the first negative +// // lookahead, has to look ALL the way ahead, to the end of +// // the pattern. +// for (let n = negativeLists.length - 1; n > -1; n--) { +// const nl = negativeLists[n] +// +// const nlBefore = re.slice(0, nl.reStart) +// const nlFirst = re.slice(nl.reStart, nl.reEnd - 8) +// let nlAfter = re.slice(nl.reEnd) +// const nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + nlAfter +// +// // Handle nested stuff like *(*.js|!(*.json)), where open parens +// // mean that we should *not* include the ) in the bit that is considered +// // "after" the negated section. +// const closeParensBefore = nlBefore.split(')').length +// const openParensBefore = nlBefore.split('(').length - closeParensBefore +// let cleanAfter = nlAfter +// for (let i = 0; i < openParensBefore; i++) { +// cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') +// } +// nlAfter = cleanAfter +// +// const dollar = nlAfter === '' ? '(?:$|\\/)' : '' +// +// re = nlBefore + nlFirst + nlAfter + dollar + nlLast +// } +// +// // if the re is not "" at this point, then we need to make sure +// // it doesn't match against an empty path part. +// // Otherwise a/* will match a/, which it should not. +// if (re !== '' && hasMagic) { +// re = '(?=.)' + re +// } +// +// if (addPatternStart) { +// re = patternStart() + re +// } +// +// // if it's nocase, and the lcase/uppercase don't match, it's magic +// if (options.nocase && !hasMagic && !options.nocaseMagicOnly) { +// hasMagic = pattern.toUpperCase() !== pattern.toLowerCase() +// } +// +// // skip the regexp for non-magical patterns +// // unescape anything in it, though, so that it'll be +// // an exact match against a file etc. +// if (!hasMagic) { +// return globUnescape(re) +// } +// +// return re +// } +//# sourceMappingURL=parse.js.map \ No newline at end of file diff --git a/node_modules/minimatch/package.json b/node_modules/minimatch/package.json index 02c1589c64dd6..95364b1548246 100644 --- a/node_modules/minimatch/package.json +++ b/node_modules/minimatch/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me)", "name": "minimatch", "description": "a glob matcher in javascript", - "version": "7.4.2", + "version": "7.4.3", "repository": { "type": "git", "url": "git://github.com/isaacs/minimatch.git" diff --git a/node_modules/tuf-js/package.json b/node_modules/tuf-js/package.json index 29436c760ff20..4396e202369b8 100644 --- a/node_modules/tuf-js/package.json +++ b/node_modules/tuf-js/package.json @@ -1,6 +1,6 @@ { "name": "tuf-js", - "version": "1.1.1", + "version": "1.1.2", "description": "JavaScript implementation of The Update Framework (TUF)", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -26,17 +26,17 @@ "bugs": { "url": "https://github.com/theupdateframework/tuf-js/issues" }, - "homepage": "https://github.com/theupdateframework/tuf-js/packages/client#readme", + "homepage": "https://github.com/theupdateframework/tuf-js/tree/main/packages/client#readme", "devDependencies": { - "@tufjs/repo-mock": "1.0.0", + "@tufjs/repo-mock": "1.0.1", "@types/make-fetch-happen": "^10.0.1", - "@types/node": "^18.14.5", + "@types/node": "^18.15.3", "nock": "^13.2.9", "typescript": "^4.9.5" }, "dependencies": { "make-fetch-happen": "^11.0.1", - "@tufjs/models": "1.0.0" + "@tufjs/models": "1.0.1" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" diff --git a/package-lock.json b/package-lock.json index b92b0988e12f6..8c69514938e5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -118,7 +118,7 @@ "libnpmteam": "^5.0.3", "libnpmversion": "^4.0.2", "make-fetch-happen": "^11.0.3", - "minimatch": "^7.4.2", + "minimatch": "^7.4.3", "minipass": "^4.2.5", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", @@ -2497,32 +2497,17 @@ "dev": true }, "node_modules/@tufjs/models": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-1.0.0.tgz", - "integrity": "sha512-RRMu4uMxWnZlxaIBxahSb2IssFZiu188sndesZflWOe1cA/qUqtemSIoBWbuVKPvvdktapImWNnKpBcc+VrCQw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-1.0.1.tgz", + "integrity": "sha512-AY0VoG/AXdlSOocuREfPoEW4SNhOPp/7fw6mpAxfVIny1uZ+0fEtMoCi7NhELSlqQIRLMu7RgfKhkxT+AJ+EXg==", "inBundle": true, "dependencies": { - "minimatch": "^6.1.0" + "minimatch": "^7.4.2" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@tufjs/models/node_modules/minimatch": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz", - "integrity": "sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==", - "inBundle": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@types/debug": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", @@ -8509,9 +8494,9 @@ } }, "node_modules/minimatch": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.2.tgz", - "integrity": "sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA==", + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.3.tgz", + "integrity": "sha512-5UB4yYusDtkRPbRiy1cqZ1IpGNcJCGlEMG17RKzPddpyiPKoCdwohbED8g4QXT0ewCt8LTkQXuljsUfQ3FKM4A==", "inBundle": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -14120,12 +14105,12 @@ } }, "node_modules/tuf-js": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.1.tgz", - "integrity": "sha512-WTp382/PR96k0dI4GD5RdiRhgOU0rAC7+lnoih/5pZg3cyb3aNMqDozleEEWwyfT3+FOg7Qz9JU3n6A44tLSHw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.2.tgz", + "integrity": "sha512-gBfbnS6khluxjvoFCpRV0fhWT265xNfpiNXOcBX0Ze6HGbPhe93UG5V5DdKcgm/aXsMadnY76l/h6j63GmJS5g==", "inBundle": true, "dependencies": { - "@tufjs/models": "1.0.0", + "@tufjs/models": "1.0.1", "make-fetch-happen": "^11.0.1" }, "engines": { diff --git a/package.json b/package.json index f879f5dd4dec3..ecb17e93e4083 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "libnpmteam": "^5.0.3", "libnpmversion": "^4.0.2", "make-fetch-happen": "^11.0.3", - "minimatch": "^7.4.2", + "minimatch": "^7.4.3", "minipass": "^4.2.5", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2",