- if (!this.preserveMultipleSlashes) {
- for (let i = 1; i < parts.length - 1; i++) {
- const p = parts[i];
- // don't squeeze out UNC patterns
- if (i === 1 && p === '' && parts[0] === '')
- continue;
- if (p === '.' || p === '') {
- didSomething = true;
- parts.splice(i, 1);
- i--;
- }
- }
- if (parts[0] === '.' &&
- parts.length === 2 &&
- (parts[1] === '.' || parts[1] === '')) {
- didSomething = true;
- parts.pop();
- }
- }
- // //../ -> /
- let dd = 0;
- while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
- const p = parts[dd - 1];
- if (p && p !== '.' && p !== '..' && p !== '**') {
- didSomething = true;
- parts.splice(dd - 1, 2);
- dd -= 2;
- }
- }
- } while (didSomething);
- return parts.length === 0 ? [''] : parts;
- }
- // First phase: single-pattern processing
- // is 1 or more portions
- // is 1 or more portions
- // is any portion other than ., .., '', or **
- // is . or ''
- //
- // **/.. is *brutal* for filesystem walking performance, because
- // it effectively resets the recursive walk each time it occurs,
- // and ** cannot be reduced out by a .. pattern part like a regexp
- // or most strings (other than .., ., and '') can be.
- //
- // /**/..//
/ -> {/..//
/,/**//
/}
- // // -> /
- // //../ -> /
- // **/**/ -> **/
- //
- // **/*/ -> */**/ <== not valid because ** doesn't follow
- // this WOULD be allowed if ** did follow symlinks, or * didn't
- firstPhasePreProcess(globParts) {
- let didSomething = false;
- do {
- didSomething = false;
- // /**/..//
/ -> {/..//
/,/**//
/}
- for (let parts of globParts) {
- let gs = -1;
- while (-1 !== (gs = parts.indexOf('**', gs + 1))) {
- let gss = gs;
- while (parts[gss + 1] === '**') {
- // /**/**/ -> /**/
- gss++;
- }
- // eg, if gs is 2 and gss is 4, that means we have 3 **
- // parts, and can remove 2 of them.
- if (gss > gs) {
- parts.splice(gs + 1, gss - gs);
- }
- let next = parts[gs + 1];
- const p = parts[gs + 2];
- const p2 = parts[gs + 3];
- if (next !== '..')
- continue;
- if (!p ||
- p === '.' ||
- p === '..' ||
- !p2 ||
- p2 === '.' ||
- p2 === '..') {
- continue;
- }
- didSomething = true;
- // edit parts in place, and push the new one
- parts.splice(gs, 1);
- const other = parts.slice(0);
- other[gs] = '**';
- globParts.push(other);
- gs--;
- }
- // // -> /
- if (!this.preserveMultipleSlashes) {
- for (let i = 1; i < parts.length - 1; i++) {
- const p = parts[i];
- // don't squeeze out UNC patterns
- if (i === 1 && p === '' && parts[0] === '')
- continue;
- if (p === '.' || p === '') {
- didSomething = true;
- parts.splice(i, 1);
- i--;
- }
- }
- if (parts[0] === '.' &&
- parts.length === 2 &&
- (parts[1] === '.' || parts[1] === '')) {
- didSomething = true;
- parts.pop();
- }
- }
- // //../ -> /
- let dd = 0;
- while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
- const p = parts[dd - 1];
- if (p && p !== '.' && p !== '..' && p !== '**') {
- didSomething = true;
- const needDot = dd === 1 && parts[dd + 1] === '**';
- const splin = needDot ? ['.'] : [];
- parts.splice(dd - 1, 2, ...splin);
- if (parts.length === 0)
- parts.push('');
- dd -= 2;
- }
- }
- }
- } while (didSomething);
- return globParts;
- }
- // second phase: multi-pattern dedupes
- // {/*/,//} -> /*/
- // {/,/} -> /
- // {/**/,/} -> /**/
- //
- // {/**/,/**//} -> /**/
- // ^-- not valid because ** doens't follow symlinks
- secondPhasePreProcess(globParts) {
- for (let i = 0; i < globParts.length - 1; i++) {
- for (let j = i + 1; j < globParts.length; j++) {
- const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes);
- if (matched) {
- globParts[i] = [];
- globParts[j] = matched;
- break;
- }
- }
- }
- return globParts.filter(gs => gs.length);
- }
- partsMatch(a, b, emptyGSMatch = false) {
- let ai = 0;
- let bi = 0;
- let result = [];
- let which = '';
- while (ai < a.length && bi < b.length) {
- if (a[ai] === b[bi]) {
- result.push(which === 'b' ? b[bi] : a[ai]);
- ai++;
- bi++;
- }
- else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) {
- result.push(a[ai]);
- ai++;
- }
- else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) {
- result.push(b[bi]);
- bi++;
- }
- else if (a[ai] === '*' &&
- b[bi] &&
- (this.options.dot || !b[bi].startsWith('.')) &&
- b[bi] !== '**') {
- if (which === 'b')
- return false;
- which = 'a';
- result.push(a[ai]);
- ai++;
- bi++;
- }
- else if (b[bi] === '*' &&
- a[ai] &&
- (this.options.dot || !a[ai].startsWith('.')) &&
- a[ai] !== '**') {
- if (which === 'a')
- return false;
- which = 'b';
- result.push(b[bi]);
- ai++;
- bi++;
- }
- else {
- return false;
- }
- }
- // if we fall out of the loop, it means they two are identical
- // as long as their lengths match
- return a.length === b.length && result;
- }
- 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) {
- let fileStartIndex = 0;
- let patternStartIndex = 0;
- // UNC paths like //?/X:/... can match X:/... and vice versa
- // Drive letters in absolute drive or unc paths are always compared
- // case-insensitively.
- if (this.isWindows) {
- const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0]);
- const fileUNC = !fileDrive &&
- file[0] === '' &&
- file[1] === '' &&
- file[2] === '?' &&
- /^[a-z]:$/i.test(file[3]);
- const patternDrive = typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0]);
- const patternUNC = !patternDrive &&
- pattern[0] === '' &&
- pattern[1] === '' &&
- pattern[2] === '?' &&
- typeof pattern[3] === 'string' &&
- /^[a-z]:$/i.test(pattern[3]);
- const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined;
- const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined;
- if (typeof fdi === 'number' && typeof pdi === 'number') {
- const [fd, pd] = [
- file[fdi],
- pattern[pdi],
- ];
- if (fd.toLowerCase() === pd.toLowerCase()) {
- pattern[pdi] = fd;
- patternStartIndex = pdi;
- fileStartIndex = fdi;
- }
- }
- }
- // resolve and reduce . and .. portions in the file as well.
- // dont' need to do the second phase, because it's only one string[]
- const { optimizationLevel = 1 } = this.options;
- if (optimizationLevel >= 2) {
- file = this.levelTwoFileOptimize(file);
- }
- if (pattern.includes(exports.GLOBSTAR)) {
- return this.#matchGlobstar(file, pattern, partial, fileStartIndex, patternStartIndex);
- }
- return this.#matchOne(file, pattern, partial, fileStartIndex, patternStartIndex);
- }
- #matchGlobstar(file, pattern, partial, fileIndex, patternIndex) {
- const firstgs = pattern.indexOf(exports.GLOBSTAR, patternIndex);
- const lastgs = pattern.lastIndexOf(exports.GLOBSTAR);
- const [head, body, tail] = partial ? [
- pattern.slice(patternIndex, firstgs),
- pattern.slice(firstgs + 1),
- [],
- ] : [
- pattern.slice(patternIndex, firstgs),
- pattern.slice(firstgs + 1, lastgs),
- pattern.slice(lastgs + 1),
- ];
- if (head.length) {
- const fileHead = file.slice(fileIndex, fileIndex + head.length);
- if (!this.#matchOne(fileHead, head, partial, 0, 0))
- return false;
- fileIndex += head.length;
- }
- let fileTailMatch = 0;
- if (tail.length) {
- if (tail.length + fileIndex > file.length)
- return false;
- let tailStart = file.length - tail.length;
- if (this.#matchOne(file, tail, partial, tailStart, 0)) {
- fileTailMatch = tail.length;
- }
- else {
- if (file[file.length - 1] !== '' ||
- fileIndex + tail.length === file.length) {
- return false;
- }
- tailStart--;
- if (!this.#matchOne(file, tail, partial, tailStart, 0))
- return false;
- fileTailMatch = tail.length + 1;
- }
- }
- if (!body.length) {
- let sawSome = !!fileTailMatch;
- for (let i = fileIndex; i < file.length - fileTailMatch; i++) {
- const f = String(file[i]);
- sawSome = true;
- if (f === '.' || f === '..' ||
- (!this.options.dot && f.startsWith('.'))) {
- return false;
- }
- }
- return partial || sawSome;
- }
- const bodySegments = [[[], 0]];
- let currentBody = bodySegments[0];
- let nonGsParts = 0;
- const nonGsPartsSums = [0];
- for (const b of body) {
- if (b === exports.GLOBSTAR) {
- nonGsPartsSums.push(nonGsParts);
- currentBody = [[], 0];
- bodySegments.push(currentBody);
- }
- else {
- currentBody[0].push(b);
- nonGsParts++;
- }
- }
- let i = bodySegments.length - 1;
- const fileLength = file.length - fileTailMatch;
- for (const b of bodySegments) {
- b[1] = fileLength - (nonGsPartsSums[i--] + b[0].length);
- }
- return !!this.#matchGlobStarBodySections(file, bodySegments, fileIndex, 0, partial, 0, !!fileTailMatch);
- }
- #matchGlobStarBodySections(file, bodySegments, fileIndex, bodyIndex, partial, globStarDepth, sawTail) {
- const bs = bodySegments[bodyIndex];
- if (!bs) {
- for (let i = fileIndex; i < file.length; i++) {
- sawTail = true;
- const f = file[i];
- if (f === '.' || f === '..' ||
- (!this.options.dot && f.startsWith('.'))) {
- return false;
- }
- }
- return sawTail;
- }
- const [body, after] = bs;
- while (fileIndex <= after) {
- const m = this.#matchOne(file.slice(0, fileIndex + body.length), body, partial, fileIndex, 0);
- if (m && globStarDepth < this.maxGlobstarRecursion) {
- const sub = this.#matchGlobStarBodySections(file, bodySegments, fileIndex + body.length, bodyIndex + 1, partial, globStarDepth + 1, sawTail);
- if (sub !== false)
- return sub;
- }
- const f = file[fileIndex];
- if (f === '.' || f === '..' ||
- (!this.options.dot && f.startsWith('.'))) {
- return false;
- }
- fileIndex++;
- }
- return partial || null;
- }
- #matchOne(file, pattern, partial, fileIndex, patternIndex) {
- let fi;
- let pi;
- let pl;
- let fl;
- for (fi = fileIndex, pi = patternIndex,
- fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
- this.debug('matchOne loop');
- let p = pattern[pi];
- let f = file[fi];
- this.debug(pattern, p, f);
- /* c8 ignore start */
- if (p === false || p === exports.GLOBSTAR)
- return false;
- /* c8 ignore stop */
- 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;
- }
- if (fi === fl && pi === pl) {
- return true;
- }
- else if (fi === fl) {
- return partial;
- }
- else if (pi === pl) {
- return fi === fl - 1 && file[fi] === '';
- /* c8 ignore start */
- }
- else {
- throw new Error('wtf?');
- }
- /* c8 ignore stop */
- }
- braceExpand() {
- return (0, exports.braceExpand)(this.pattern, this.options);
- }
- parse(pattern) {
- (0, assert_valid_pattern_js_1.assertValidPattern)(pattern);
- const options = this.options;
- // shortcuts
- if (pattern === '**')
- return exports.GLOBSTAR;
- 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 ((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;
- }
- const re = ast_js_1.AST.fromGlob(pattern, this.options).toMMPattern();
- if (fastTest && typeof re === 'object') {
- // Avoids overriding in frozen environments
- Reflect.defineProperty(re, 'test', { value: fastTest });
- }
- return re;
- }
- 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 = new Set(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 => {
- if (p instanceof RegExp) {
- for (const f of p.flags.split(''))
- flags.add(f);
- }
- return 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('|');
- // need to wrap in parens if we had more than one thing with |,
- // otherwise only the first will be anchored to ^ and the last to $
- const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', ''];
- // must match entire pattern
- // ending in a * or ** will make it less strict.
- re = '^' + open + re + close + '$';
- // can match anything, as long as it's not this.
- if (this.negate)
- re = '^(?!' + re + ').+$';
- try {
- this.regexp = new RegExp(re, [...flags].join(''));
- /* 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 (this.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 (this.isWindows) {
- f = f.split('\\').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;
-/* c8 ignore start */
-var ast_js_2 = __nccwpck_require__(3238);
-Object.defineProperty(exports, "AST", ({ enumerable: true, get: function () { return ast_js_2.AST; } }));
-var escape_js_2 = __nccwpck_require__(6726);
-Object.defineProperty(exports, "escape", ({ enumerable: true, get: function () { return escape_js_2.escape; } }));
-var unescape_js_2 = __nccwpck_require__(9829);
-Object.defineProperty(exports, "unescape", ({ enumerable: true, get: function () { return unescape_js_2.unescape; } }));
-/* c8 ignore stop */
-exports.minimatch.AST = ast_js_1.AST;
-exports.minimatch.Minimatch = Minimatch;
-exports.minimatch.escape = escape_js_1.escape;
-exports.minimatch.unescape = unescape_js_1.unescape;
-//# sourceMappingURL=index.js.map
-
-/***/ }),
-
-/***/ 9829:
-/***/ ((__unused_webpack_module, exports) => {
-
-
-Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.unescape = void 0;
-/**
- * Un-escape a string that has been escaped with {@link escape}.
- *
- * If the {@link windowsPathsNoEscape} option is used, then square-brace
- * escapes are removed, but not backslash escapes. For example, it will turn
- * the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
- * becuase `\` is a path separator in `windowsPathsNoEscape` mode.
- *
- * When `windowsPathsNoEscape` is not set, then both brace escapes and
- * backslash escapes are removed.
- *
- * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
- * or unescaped.
- */
-const unescape = (s, { windowsPathsNoEscape = false, } = {}) => {
- return windowsPathsNoEscape
- ? s.replace(/\[([^\/\\])\]/g, '$1')
- : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, '$1$2').replace(/\\([^\/])/g, '$1');
-};
-exports.unescape = unescape;
-//# sourceMappingURL=unescape.js.map
-
-/***/ }),
-
-/***/ 8275:
-/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
-
-
-var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
-};
-Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.Minipass = exports.isWritable = exports.isReadable = exports.isStream = void 0;
-const proc = typeof process === 'object' && process
- ? process
- : {
- stdout: null,
- stderr: null,
- };
-const node_events_1 = __nccwpck_require__(8474);
-const node_stream_1 = __importDefault(__nccwpck_require__(7075));
-const node_string_decoder_1 = __nccwpck_require__(6193);
-/**
- * Return true if the argument is a Minipass stream, Node stream, or something
- * else that Minipass can interact with.
- */
-const isStream = (s) => !!s &&
- typeof s === 'object' &&
- (s instanceof Minipass ||
- s instanceof node_stream_1.default ||
- (0, exports.isReadable)(s) ||
- (0, exports.isWritable)(s))
-/**
- * Return true if the argument is a valid {@link Minipass.Readable}
- */
-;
-exports.isStream = isStream;
-/**
- * Return true if the argument is a valid {@link Minipass.Readable}
- */
-const isReadable = (s) => !!s &&
- typeof s === 'object' &&
- s instanceof node_events_1.EventEmitter &&
- typeof s.pipe === 'function' &&
- // node core Writable streams have a pipe() method, but it throws
- s.pipe !== node_stream_1.default.Writable.prototype.pipe
-/**
- * Return true if the argument is a valid {@link Minipass.Writable}
- */
-;
-exports.isReadable = isReadable;
-/**
- * Return true if the argument is a valid {@link Minipass.Writable}
- */
-const isWritable = (s) => !!s &&
- typeof s === 'object' &&
- s instanceof node_events_1.EventEmitter &&
- typeof s.write === 'function' &&
- typeof s.end === 'function';
-exports.isWritable = isWritable;
-const EOF = Symbol('EOF');
-const MAYBE_EMIT_END = Symbol('maybeEmitEnd');
-const EMITTED_END = Symbol('emittedEnd');
-const EMITTING_END = Symbol('emittingEnd');
-const EMITTED_ERROR = Symbol('emittedError');
-const CLOSED = Symbol('closed');
-const READ = Symbol('read');
-const FLUSH = Symbol('flush');
-const FLUSHCHUNK = Symbol('flushChunk');
-const ENCODING = Symbol('encoding');
-const DECODER = Symbol('decoder');
-const FLOWING = Symbol('flowing');
-const PAUSED = Symbol('paused');
-const RESUME = Symbol('resume');
-const BUFFER = Symbol('buffer');
-const PIPES = Symbol('pipes');
-const BUFFERLENGTH = Symbol('bufferLength');
-const BUFFERPUSH = Symbol('bufferPush');
-const BUFFERSHIFT = Symbol('bufferShift');
-const OBJECTMODE = Symbol('objectMode');
-// internal event when stream is destroyed
-const DESTROYED = Symbol('destroyed');
-// internal event when stream has an error
-const ERROR = Symbol('error');
-const EMITDATA = Symbol('emitData');
-const EMITEND = Symbol('emitEnd');
-const EMITEND2 = Symbol('emitEnd2');
-const ASYNC = Symbol('async');
-const ABORT = Symbol('abort');
-const ABORTED = Symbol('aborted');
-const SIGNAL = Symbol('signal');
-const DATALISTENERS = Symbol('dataListeners');
-const DISCARDED = Symbol('discarded');
-const defer = (fn) => Promise.resolve().then(fn);
-const nodefer = (fn) => fn();
-const isEndish = (ev) => ev === 'end' || ev === 'finish' || ev === 'prefinish';
-const isArrayBufferLike = (b) => b instanceof ArrayBuffer ||
- (!!b &&
- typeof b === 'object' &&
- b.constructor &&
- b.constructor.name === 'ArrayBuffer' &&
- b.byteLength >= 0);
-const isArrayBufferView = (b) => !Buffer.isBuffer(b) && ArrayBuffer.isView(b);
-/**
- * Internal class representing a pipe to a destination stream.
- *
- * @internal
- */
-class Pipe {
- src;
- dest;
- opts;
- ondrain;
- constructor(src, dest, opts) {
- this.src = src;
- this.dest = dest;
- this.opts = opts;
- this.ondrain = () => src[RESUME]();
- this.dest.on('drain', this.ondrain);
- }
- unpipe() {
- this.dest.removeListener('drain', this.ondrain);
- }
- // only here for the prototype
- /* c8 ignore start */
- proxyErrors(_er) { }
- /* c8 ignore stop */
- end() {
- this.unpipe();
- if (this.opts.end)
- this.dest.end();
- }
-}
-/**
- * Internal class representing a pipe to a destination stream where
- * errors are proxied.
- *
- * @internal
- */
-class PipeProxyErrors extends Pipe {
- unpipe() {
- this.src.removeListener('error', this.proxyErrors);
- super.unpipe();
- }
- constructor(src, dest, opts) {
- super(src, dest, opts);
- this.proxyErrors = (er) => this.dest.emit('error', er);
- src.on('error', this.proxyErrors);
- }
-}
-const isObjectModeOptions = (o) => !!o.objectMode;
-const isEncodingOptions = (o) => !o.objectMode && !!o.encoding && o.encoding !== 'buffer';
-/**
- * Main export, the Minipass class
- *
- * `RType` is the type of data emitted, defaults to Buffer
- *
- * `WType` is the type of data to be written, if RType is buffer or string,
- * then any {@link Minipass.ContiguousData} is allowed.
- *
- * `Events` is the set of event handler signatures that this object
- * will emit, see {@link Minipass.Events}
- */
-class Minipass extends node_events_1.EventEmitter {
- [FLOWING] = false;
- [PAUSED] = false;
- [PIPES] = [];
- [BUFFER] = [];
- [OBJECTMODE];
- [ENCODING];
- [ASYNC];
- [DECODER];
- [EOF] = false;
- [EMITTED_END] = false;
- [EMITTING_END] = false;
- [CLOSED] = false;
- [EMITTED_ERROR] = null;
- [BUFFERLENGTH] = 0;
- [DESTROYED] = false;
- [SIGNAL];
- [ABORTED] = false;
- [DATALISTENERS] = 0;
- [DISCARDED] = false;
- /**
- * true if the stream can be written
- */
- writable = true;
- /**
- * true if the stream can be read
- */
- readable = true;
- /**
- * If `RType` is Buffer, then options do not need to be provided.
- * Otherwise, an options object must be provided to specify either
- * {@link Minipass.SharedOptions.objectMode} or
- * {@link Minipass.SharedOptions.encoding}, as appropriate.
- */
- constructor(...args) {
- const options = (args[0] ||
- {});
- super();
- if (options.objectMode && typeof options.encoding === 'string') {
- throw new TypeError('Encoding and objectMode may not be used together');
- }
- if (isObjectModeOptions(options)) {
- this[OBJECTMODE] = true;
- this[ENCODING] = null;
- }
- else if (isEncodingOptions(options)) {
- this[ENCODING] = options.encoding;
- this[OBJECTMODE] = false;
- }
- else {
- this[OBJECTMODE] = false;
- this[ENCODING] = null;
- }
- this[ASYNC] = !!options.async;
- this[DECODER] = this[ENCODING]
- ? new node_string_decoder_1.StringDecoder(this[ENCODING])
- : null;
- //@ts-ignore - private option for debugging and testing
- if (options && options.debugExposeBuffer === true) {
- Object.defineProperty(this, 'buffer', { get: () => this[BUFFER] });
- }
- //@ts-ignore - private option for debugging and testing
- if (options && options.debugExposePipes === true) {
- Object.defineProperty(this, 'pipes', { get: () => this[PIPES] });
- }
- const { signal } = options;
- if (signal) {
- this[SIGNAL] = signal;
- if (signal.aborted) {
- this[ABORT]();
- }
- else {
- signal.addEventListener('abort', () => this[ABORT]());
- }
- }
- }
- /**
- * The amount of data stored in the buffer waiting to be read.
- *
- * For Buffer strings, this will be the total byte length.
- * For string encoding streams, this will be the string character length,
- * according to JavaScript's `string.length` logic.
- * For objectMode streams, this is a count of the items waiting to be
- * emitted.
- */
- get bufferLength() {
- return this[BUFFERLENGTH];
- }
- /**
- * The `BufferEncoding` currently in use, or `null`
- */
- get encoding() {
- return this[ENCODING];
- }
- /**
- * @deprecated - This is a read only property
- */
- set encoding(_enc) {
- throw new Error('Encoding must be set at instantiation time');
- }
- /**
- * @deprecated - Encoding may only be set at instantiation time
- */
- setEncoding(_enc) {
- throw new Error('Encoding must be set at instantiation time');
- }
- /**
- * True if this is an objectMode stream
- */
- get objectMode() {
- return this[OBJECTMODE];
- }
- /**
- * @deprecated - This is a read-only property
- */
- set objectMode(_om) {
- throw new Error('objectMode must be set at instantiation time');
- }
- /**
- * true if this is an async stream
- */
- get ['async']() {
- return this[ASYNC];
- }
- /**
- * Set to true to make this stream async.
- *
- * Once set, it cannot be unset, as this would potentially cause incorrect
- * behavior. Ie, a sync stream can be made async, but an async stream
- * cannot be safely made sync.
- */
- set ['async'](a) {
- this[ASYNC] = this[ASYNC] || !!a;
- }
- // drop everything and get out of the flow completely
- [ABORT]() {
- this[ABORTED] = true;
- this.emit('abort', this[SIGNAL]?.reason);
- this.destroy(this[SIGNAL]?.reason);
- }
- /**
- * True if the stream has been aborted.
- */
- get aborted() {
- return this[ABORTED];
- }
- /**
- * No-op setter. Stream aborted status is set via the AbortSignal provided
- * in the constructor options.
- */
- set aborted(_) { }
- write(chunk, encoding, cb) {
- if (this[ABORTED])
- return false;
- if (this[EOF])
- throw new Error('write after end');
- if (this[DESTROYED]) {
- this.emit('error', Object.assign(new Error('Cannot call write after a stream was destroyed'), { code: 'ERR_STREAM_DESTROYED' }));
- return true;
- }
- if (typeof encoding === 'function') {
- cb = encoding;
- encoding = 'utf8';
- }
- if (!encoding)
- encoding = 'utf8';
- const fn = this[ASYNC] ? defer : nodefer;
- // convert array buffers and typed array views into buffers
- // at some point in the future, we may want to do the opposite!
- // leave strings and buffers as-is
- // anything is only allowed if in object mode, so throw
- if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {
- if (isArrayBufferView(chunk)) {
- //@ts-ignore - sinful unsafe type changing
- chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
- }
- else if (isArrayBufferLike(chunk)) {
- //@ts-ignore - sinful unsafe type changing
- chunk = Buffer.from(chunk);
- }
- else if (typeof chunk !== 'string') {
- throw new Error('Non-contiguous data written to non-objectMode stream');
- }
- }
- // handle object mode up front, since it's simpler
- // this yields better performance, fewer checks later.
- if (this[OBJECTMODE]) {
- // maybe impossible?
- /* c8 ignore start */
- if (this[FLOWING] && this[BUFFERLENGTH] !== 0)
- this[FLUSH](true);
- /* c8 ignore stop */
- if (this[FLOWING])
- this.emit('data', chunk);
- else
- this[BUFFERPUSH](chunk);
- if (this[BUFFERLENGTH] !== 0)
- this.emit('readable');
- if (cb)
- fn(cb);
- return this[FLOWING];
- }
- // at this point the chunk is a buffer or string
- // don't buffer it up or send it to the decoder
- if (!chunk.length) {
- if (this[BUFFERLENGTH] !== 0)
- this.emit('readable');
- if (cb)
- fn(cb);
- return this[FLOWING];
- }
- // fast-path writing strings of same encoding to a stream with
- // an empty buffer, skipping the buffer/decoder dance
- if (typeof chunk === 'string' &&
- // unless it is a string already ready for us to use
- !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) {
- //@ts-ignore - sinful unsafe type change
- chunk = Buffer.from(chunk, encoding);
- }
- if (Buffer.isBuffer(chunk) && this[ENCODING]) {
- //@ts-ignore - sinful unsafe type change
- chunk = this[DECODER].write(chunk);
- }
- // Note: flushing CAN potentially switch us into not-flowing mode
- if (this[FLOWING] && this[BUFFERLENGTH] !== 0)
- this[FLUSH](true);
- if (this[FLOWING])
- this.emit('data', chunk);
- else
- this[BUFFERPUSH](chunk);
- if (this[BUFFERLENGTH] !== 0)
- this.emit('readable');
- if (cb)
- fn(cb);
- return this[FLOWING];
- }
- /**
- * Low-level explicit read method.
- *
- * In objectMode, the argument is ignored, and one item is returned if
- * available.
- *
- * `n` is the number of bytes (or in the case of encoding streams,
- * characters) to consume. If `n` is not provided, then the entire buffer
- * is returned, or `null` is returned if no data is available.
- *
- * If `n` is greater that the amount of data in the internal buffer,
- * then `null` is returned.
- */
- read(n) {
- if (this[DESTROYED])
- return null;
- this[DISCARDED] = false;
- if (this[BUFFERLENGTH] === 0 ||
- n === 0 ||
- (n && n > this[BUFFERLENGTH])) {
- this[MAYBE_EMIT_END]();
- return null;
- }
- if (this[OBJECTMODE])
- n = null;
- if (this[BUFFER].length > 1 && !this[OBJECTMODE]) {
- // not object mode, so if we have an encoding, then RType is string
- // otherwise, must be Buffer
- this[BUFFER] = [
- (this[ENCODING]
- ? this[BUFFER].join('')
- : Buffer.concat(this[BUFFER], this[BUFFERLENGTH])),
- ];
- }
- const ret = this[READ](n || null, this[BUFFER][0]);
- this[MAYBE_EMIT_END]();
- return ret;
- }
- [READ](n, chunk) {
- if (this[OBJECTMODE])
- this[BUFFERSHIFT]();
- else {
- const c = chunk;
- if (n === c.length || n === null)
- this[BUFFERSHIFT]();
- else if (typeof c === 'string') {
- this[BUFFER][0] = c.slice(n);
- chunk = c.slice(0, n);
- this[BUFFERLENGTH] -= n;
- }
- else {
- this[BUFFER][0] = c.subarray(n);
- chunk = c.subarray(0, n);
- this[BUFFERLENGTH] -= n;
- }
- }
- this.emit('data', chunk);
- if (!this[BUFFER].length && !this[EOF])
- this.emit('drain');
- return chunk;
- }
- end(chunk, encoding, cb) {
- if (typeof chunk === 'function') {
- cb = chunk;
- chunk = undefined;
- }
- if (typeof encoding === 'function') {
- cb = encoding;
- encoding = 'utf8';
- }
- if (chunk !== undefined)
- this.write(chunk, encoding);
- if (cb)
- this.once('end', cb);
- this[EOF] = true;
- this.writable = false;
- // if we haven't written anything, then go ahead and emit,
- // even if we're not reading.
- // we'll re-emit if a new 'end' listener is added anyway.
- // This makes MP more suitable to write-only use cases.
- if (this[FLOWING] || !this[PAUSED])
- this[MAYBE_EMIT_END]();
- return this;
- }
- // don't let the internal resume be overwritten
- [RESUME]() {
- if (this[DESTROYED])
- return;
- if (!this[DATALISTENERS] && !this[PIPES].length) {
- this[DISCARDED] = true;
- }
- this[PAUSED] = false;
- this[FLOWING] = true;
- this.emit('resume');
- if (this[BUFFER].length)
- this[FLUSH]();
- else if (this[EOF])
- this[MAYBE_EMIT_END]();
- else
- this.emit('drain');
- }
- /**
- * Resume the stream if it is currently in a paused state
- *
- * If called when there are no pipe destinations or `data` event listeners,
- * this will place the stream in a "discarded" state, where all data will
- * be thrown away. The discarded state is removed if a pipe destination or
- * data handler is added, if pause() is called, or if any synchronous or
- * asynchronous iteration is started.
- */
- resume() {
- return this[RESUME]();
- }
- /**
- * Pause the stream
- */
- pause() {
- this[FLOWING] = false;
- this[PAUSED] = true;
- this[DISCARDED] = false;
- }
- /**
- * true if the stream has been forcibly destroyed
- */
- get destroyed() {
- return this[DESTROYED];
- }
- /**
- * true if the stream is currently in a flowing state, meaning that
- * any writes will be immediately emitted.
- */
- get flowing() {
- return this[FLOWING];
- }
- /**
- * true if the stream is currently in a paused state
- */
- get paused() {
- return this[PAUSED];
- }
- [BUFFERPUSH](chunk) {
- if (this[OBJECTMODE])
- this[BUFFERLENGTH] += 1;
- else
- this[BUFFERLENGTH] += chunk.length;
- this[BUFFER].push(chunk);
- }
- [BUFFERSHIFT]() {
- if (this[OBJECTMODE])
- this[BUFFERLENGTH] -= 1;
- else
- this[BUFFERLENGTH] -= this[BUFFER][0].length;
- return this[BUFFER].shift();
- }
- [FLUSH](noDrain = false) {
- do { } while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) &&
- this[BUFFER].length);
- if (!noDrain && !this[BUFFER].length && !this[EOF])
- this.emit('drain');
- }
- [FLUSHCHUNK](chunk) {
- this.emit('data', chunk);
- return this[FLOWING];
- }
- /**
- * Pipe all data emitted by this stream into the destination provided.
- *
- * Triggers the flow of data.
- */
- pipe(dest, opts) {
- if (this[DESTROYED])
- return dest;
- this[DISCARDED] = false;
- const ended = this[EMITTED_END];
- opts = opts || {};
- if (dest === proc.stdout || dest === proc.stderr)
- opts.end = false;
- else
- opts.end = opts.end !== false;
- opts.proxyErrors = !!opts.proxyErrors;
- // piping an ended stream ends immediately
- if (ended) {
- if (opts.end)
- dest.end();
- }
- else {
- // "as" here just ignores the WType, which pipes don't care about,
- // since they're only consuming from us, and writing to the dest
- this[PIPES].push(!opts.proxyErrors
- ? new Pipe(this, dest, opts)
- : new PipeProxyErrors(this, dest, opts));
- if (this[ASYNC])
- defer(() => this[RESUME]());
- else
- this[RESUME]();
- }
- return dest;
- }
- /**
- * Fully unhook a piped destination stream.
- *
- * If the destination stream was the only consumer of this stream (ie,
- * there are no other piped destinations or `'data'` event listeners)
- * then the flow of data will stop until there is another consumer or
- * {@link Minipass#resume} is explicitly called.
- */
- unpipe(dest) {
- const p = this[PIPES].find(p => p.dest === dest);
- if (p) {
- if (this[PIPES].length === 1) {
- if (this[FLOWING] && this[DATALISTENERS] === 0) {
- this[FLOWING] = false;
- }
- this[PIPES] = [];
- }
- else
- this[PIPES].splice(this[PIPES].indexOf(p), 1);
- p.unpipe();
- }
- }
- /**
- * Alias for {@link Minipass#on}
- */
- addListener(ev, handler) {
- return this.on(ev, handler);
- }
- /**
- * Mostly identical to `EventEmitter.on`, with the following
- * behavior differences to prevent data loss and unnecessary hangs:
- *
- * - Adding a 'data' event handler will trigger the flow of data
- *
- * - Adding a 'readable' event handler when there is data waiting to be read
- * will cause 'readable' to be emitted immediately.
- *
- * - Adding an 'endish' event handler ('end', 'finish', etc.) which has
- * already passed will cause the event to be emitted immediately and all
- * handlers removed.
- *
- * - Adding an 'error' event handler after an error has been emitted will
- * cause the event to be re-emitted immediately with the error previously
- * raised.
- */
- on(ev, handler) {
- const ret = super.on(ev, handler);
- if (ev === 'data') {
- this[DISCARDED] = false;
- this[DATALISTENERS]++;
- if (!this[PIPES].length && !this[FLOWING]) {
- this[RESUME]();
- }
- }
- else if (ev === 'readable' && this[BUFFERLENGTH] !== 0) {
- super.emit('readable');
- }
- else if (isEndish(ev) && this[EMITTED_END]) {
- super.emit(ev);
- this.removeAllListeners(ev);
- }
- else if (ev === 'error' && this[EMITTED_ERROR]) {
- const h = handler;
- if (this[ASYNC])
- defer(() => h.call(this, this[EMITTED_ERROR]));
- else
- h.call(this, this[EMITTED_ERROR]);
- }
- return ret;
- }
- /**
- * Alias for {@link Minipass#off}
- */
- removeListener(ev, handler) {
- return this.off(ev, handler);
- }
- /**
- * Mostly identical to `EventEmitter.off`
- *
- * If a 'data' event handler is removed, and it was the last consumer
- * (ie, there are no pipe destinations or other 'data' event listeners),
- * then the flow of data will stop until there is another consumer or
- * {@link Minipass#resume} is explicitly called.
- */
- off(ev, handler) {
- const ret = super.off(ev, handler);
- // if we previously had listeners, and now we don't, and we don't
- // have any pipes, then stop the flow, unless it's been explicitly
- // put in a discarded flowing state via stream.resume().
- if (ev === 'data') {
- this[DATALISTENERS] = this.listeners('data').length;
- if (this[DATALISTENERS] === 0 &&
- !this[DISCARDED] &&
- !this[PIPES].length) {
- this[FLOWING] = false;
- }
- }
- return ret;
- }
- /**
- * Mostly identical to `EventEmitter.removeAllListeners`
- *
- * If all 'data' event handlers are removed, and they were the last consumer
- * (ie, there are no pipe destinations), then the flow of data will stop
- * until there is another consumer or {@link Minipass#resume} is explicitly
- * called.
- */
- removeAllListeners(ev) {
- const ret = super.removeAllListeners(ev);
- if (ev === 'data' || ev === undefined) {
- this[DATALISTENERS] = 0;
- if (!this[DISCARDED] && !this[PIPES].length) {
- this[FLOWING] = false;
- }
- }
- return ret;
- }
- /**
- * true if the 'end' event has been emitted
- */
- get emittedEnd() {
- return this[EMITTED_END];
- }
- [MAYBE_EMIT_END]() {
- if (!this[EMITTING_END] &&
- !this[EMITTED_END] &&
- !this[DESTROYED] &&
- this[BUFFER].length === 0 &&
- this[EOF]) {
- this[EMITTING_END] = true;
- this.emit('end');
- this.emit('prefinish');
- this.emit('finish');
- if (this[CLOSED])
- this.emit('close');
- this[EMITTING_END] = false;
- }
- }
- /**
- * Mostly identical to `EventEmitter.emit`, with the following
- * behavior differences to prevent data loss and unnecessary hangs:
- *
- * If the stream has been destroyed, and the event is something other
- * than 'close' or 'error', then `false` is returned and no handlers
- * are called.
- *
- * If the event is 'end', and has already been emitted, then the event
- * is ignored. If the stream is in a paused or non-flowing state, then
- * the event will be deferred until data flow resumes. If the stream is
- * async, then handlers will be called on the next tick rather than
- * immediately.
- *
- * If the event is 'close', and 'end' has not yet been emitted, then
- * the event will be deferred until after 'end' is emitted.
- *
- * If the event is 'error', and an AbortSignal was provided for the stream,
- * and there are no listeners, then the event is ignored, matching the
- * behavior of node core streams in the presense of an AbortSignal.
- *
- * If the event is 'finish' or 'prefinish', then all listeners will be
- * removed after emitting the event, to prevent double-firing.
- */
- emit(ev, ...args) {
- const data = args[0];
- // error and close are only events allowed after calling destroy()
- if (ev !== 'error' &&
- ev !== 'close' &&
- ev !== DESTROYED &&
- this[DESTROYED]) {
- return false;
- }
- else if (ev === 'data') {
- return !this[OBJECTMODE] && !data
- ? false
- : this[ASYNC]
- ? (defer(() => this[EMITDATA](data)), true)
- : this[EMITDATA](data);
- }
- else if (ev === 'end') {
- return this[EMITEND]();
- }
- else if (ev === 'close') {
- this[CLOSED] = true;
- // don't emit close before 'end' and 'finish'
- if (!this[EMITTED_END] && !this[DESTROYED])
- return false;
- const ret = super.emit('close');
- this.removeAllListeners('close');
- return ret;
- }
- else if (ev === 'error') {
- this[EMITTED_ERROR] = data;
- super.emit(ERROR, data);
- const ret = !this[SIGNAL] || this.listeners('error').length
- ? super.emit('error', data)
- : false;
- this[MAYBE_EMIT_END]();
- return ret;
- }
- else if (ev === 'resume') {
- const ret = super.emit('resume');
- this[MAYBE_EMIT_END]();
- return ret;
- }
- else if (ev === 'finish' || ev === 'prefinish') {
- const ret = super.emit(ev);
- this.removeAllListeners(ev);
- return ret;
- }
- // Some other unknown event
- const ret = super.emit(ev, ...args);
- this[MAYBE_EMIT_END]();
- return ret;
- }
- [EMITDATA](data) {
- for (const p of this[PIPES]) {
- if (p.dest.write(data) === false)
- this.pause();
- }
- const ret = this[DISCARDED] ? false : super.emit('data', data);
- this[MAYBE_EMIT_END]();
- return ret;
- }
- [EMITEND]() {
- if (this[EMITTED_END])
- return false;
- this[EMITTED_END] = true;
- this.readable = false;
- return this[ASYNC]
- ? (defer(() => this[EMITEND2]()), true)
- : this[EMITEND2]();
- }
- [EMITEND2]() {
- if (this[DECODER]) {
- const data = this[DECODER].end();
- if (data) {
- for (const p of this[PIPES]) {
- p.dest.write(data);
- }
- if (!this[DISCARDED])
- super.emit('data', data);
- }
- }
- for (const p of this[PIPES]) {
- p.end();
- }
- const ret = super.emit('end');
- this.removeAllListeners('end');
- return ret;
- }
- /**
- * Return a Promise that resolves to an array of all emitted data once
- * the stream ends.
- */
- async collect() {
- const buf = Object.assign([], {
- dataLength: 0,
- });
- if (!this[OBJECTMODE])
- buf.dataLength = 0;
- // set the promise first, in case an error is raised
- // by triggering the flow here.
- const p = this.promise();
- this.on('data', c => {
- buf.push(c);
- if (!this[OBJECTMODE])
- buf.dataLength += c.length;
- });
- await p;
- return buf;
- }
- /**
- * Return a Promise that resolves to the concatenation of all emitted data
- * once the stream ends.
- *
- * Not allowed on objectMode streams.
- */
- async concat() {
- if (this[OBJECTMODE]) {
- throw new Error('cannot concat in objectMode');
- }
- const buf = await this.collect();
- return (this[ENCODING]
- ? buf.join('')
- : Buffer.concat(buf, buf.dataLength));
- }
- /**
- * Return a void Promise that resolves once the stream ends.
- */
- async promise() {
- return new Promise((resolve, reject) => {
- this.on(DESTROYED, () => reject(new Error('stream destroyed')));
- this.on('error', er => reject(er));
- this.on('end', () => resolve());
- });
- }
- /**
- * Asynchronous `for await of` iteration.
- *
- * This will continue emitting all chunks until the stream terminates.
- */
- [Symbol.asyncIterator]() {
- // set this up front, in case the consumer doesn't call next()
- // right away.
- this[DISCARDED] = false;
- let stopped = false;
- const stop = async () => {
- this.pause();
- stopped = true;
- return { value: undefined, done: true };
- };
- const next = () => {
- if (stopped)
- return stop();
- const res = this.read();
- if (res !== null)
- return Promise.resolve({ done: false, value: res });
- if (this[EOF])
- return stop();
- let resolve;
- let reject;
- const onerr = (er) => {
- this.off('data', ondata);
- this.off('end', onend);
- this.off(DESTROYED, ondestroy);
- stop();
- reject(er);
- };
- const ondata = (value) => {
- this.off('error', onerr);
- this.off('end', onend);
- this.off(DESTROYED, ondestroy);
- this.pause();
- resolve({ value, done: !!this[EOF] });
- };
- const onend = () => {
- this.off('error', onerr);
- this.off('data', ondata);
- this.off(DESTROYED, ondestroy);
- stop();
- resolve({ done: true, value: undefined });
- };
- const ondestroy = () => onerr(new Error('stream destroyed'));
- return new Promise((res, rej) => {
- reject = rej;
- resolve = res;
- this.once(DESTROYED, ondestroy);
- this.once('error', onerr);
- this.once('end', onend);
- this.once('data', ondata);
- });
- };
- return {
- next,
- throw: stop,
- return: stop,
- [Symbol.asyncIterator]() {
- return this;
- },
- [Symbol.asyncDispose]: async () => { },
- };
- }
- /**
- * Synchronous `for of` iteration.
- *
- * The iteration will terminate when the internal buffer runs out, even
- * if the stream has not yet terminated.
- */
- [Symbol.iterator]() {
- // set this up front, in case the consumer doesn't call next()
- // right away.
- this[DISCARDED] = false;
- let stopped = false;
- const stop = () => {
- this.pause();
- this.off(ERROR, stop);
- this.off(DESTROYED, stop);
- this.off('end', stop);
- stopped = true;
- return { done: true, value: undefined };
- };
- const next = () => {
- if (stopped)
- return stop();
- const value = this.read();
- return value === null ? stop() : { done: false, value };
- };
- this.once('end', stop);
- this.once(ERROR, stop);
- this.once(DESTROYED, stop);
- return {
- next,
- throw: stop,
- return: stop,
- [Symbol.iterator]() {
- return this;
- },
- [Symbol.dispose]: () => { },
- };
- }
- /**
- * Destroy a stream, preventing it from being used for any further purpose.
- *
- * If the stream has a `close()` method, then it will be called on
- * destruction.
- *
- * After destruction, any attempt to write data, read data, or emit most
- * events will be ignored.
- *
- * If an error argument is provided, then it will be emitted in an
- * 'error' event.
- */
- destroy(er) {
- if (this[DESTROYED]) {
- if (er)
- this.emit('error', er);
- else
- this.emit(DESTROYED);
- return this;
- }
- this[DESTROYED] = true;
- this[DISCARDED] = true;
- // throw away all buffered data, it's never coming out
- this[BUFFER].length = 0;
- this[BUFFERLENGTH] = 0;
- const wc = this;
- if (typeof wc.close === 'function' && !this[CLOSED])
- wc.close();
- if (er)
- this.emit('error', er);
- // if no error to emit, still reject pending promises
- else
- this.emit(DESTROYED);
- return this;
- }
- /**
- * Alias for {@link isStream}
- *
- * Former export location, maintained for backwards compatibility.
- *
- * @deprecated
- */
- static get isStream() {
- return exports.isStream;
- }
-}
-exports.Minipass = Minipass;
-//# sourceMappingURL=index.js.map
-
-/***/ }),
-
-/***/ 8958:
-/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
-
-
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- var desc = Object.getOwnPropertyDescriptor(m, k);
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
- desc = { enumerable: true, get: function() { return m[k]; } };
- }
- Object.defineProperty(o, k2, desc);
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
- o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
-};
-Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.PathScurry = exports.Path = exports.PathScurryDarwin = exports.PathScurryPosix = exports.PathScurryWin32 = exports.PathScurryBase = exports.PathPosix = exports.PathWin32 = exports.PathBase = exports.ChildrenCache = exports.ResolveCache = void 0;
-const lru_cache_1 = __nccwpck_require__(3278);
-const node_path_1 = __nccwpck_require__(6760);
-const node_url_1 = __nccwpck_require__(3136);
-const fs_1 = __nccwpck_require__(9896);
-const actualFS = __importStar(__nccwpck_require__(3024));
-const realpathSync = fs_1.realpathSync.native;
-// TODO: test perf of fs/promises realpath vs realpathCB,
-// since the promises one uses realpath.native
-const promises_1 = __nccwpck_require__(1455);
-const minipass_1 = __nccwpck_require__(8275);
-const defaultFS = {
- lstatSync: fs_1.lstatSync,
- readdir: fs_1.readdir,
- readdirSync: fs_1.readdirSync,
- readlinkSync: fs_1.readlinkSync,
- realpathSync,
- promises: {
- lstat: promises_1.lstat,
- readdir: promises_1.readdir,
- readlink: promises_1.readlink,
- realpath: promises_1.realpath,
- },
-};
-// if they just gave us require('fs') then use our default
-const fsFromOption = (fsOption) => !fsOption || fsOption === defaultFS || fsOption === actualFS ?
- defaultFS
- : {
- ...defaultFS,
- ...fsOption,
- promises: {
- ...defaultFS.promises,
- ...(fsOption.promises || {}),
- },
- };
-// turn something like //?/c:/ into c:\
-const uncDriveRegexp = /^\\\\\?\\([a-z]:)\\?$/i;
-const uncToDrive = (rootPath) => rootPath.replace(/\//g, '\\').replace(uncDriveRegexp, '$1\\');
-// windows paths are separated by either / or \
-const eitherSep = /[\\\/]/;
-const UNKNOWN = 0; // may not even exist, for all we know
-const IFIFO = 0b0001;
-const IFCHR = 0b0010;
-const IFDIR = 0b0100;
-const IFBLK = 0b0110;
-const IFREG = 0b1000;
-const IFLNK = 0b1010;
-const IFSOCK = 0b1100;
-const IFMT = 0b1111;
-// mask to unset low 4 bits
-const IFMT_UNKNOWN = ~IFMT;
-// set after successfully calling readdir() and getting entries.
-const READDIR_CALLED = 0b0000_0001_0000;
-// set after a successful lstat()
-const LSTAT_CALLED = 0b0000_0010_0000;
-// set if an entry (or one of its parents) is definitely not a dir
-const ENOTDIR = 0b0000_0100_0000;
-// set if an entry (or one of its parents) does not exist
-// (can also be set on lstat errors like EACCES or ENAMETOOLONG)
-const ENOENT = 0b0000_1000_0000;
-// cannot have child entries -- also verify &IFMT is either IFDIR or IFLNK
-// set if we fail to readlink
-const ENOREADLINK = 0b0001_0000_0000;
-// set if we know realpath() will fail
-const ENOREALPATH = 0b0010_0000_0000;
-const ENOCHILD = ENOTDIR | ENOENT | ENOREALPATH;
-const TYPEMASK = 0b0011_1111_1111;
-const entToType = (s) => s.isFile() ? IFREG
- : s.isDirectory() ? IFDIR
- : s.isSymbolicLink() ? IFLNK
- : s.isCharacterDevice() ? IFCHR
- : s.isBlockDevice() ? IFBLK
- : s.isSocket() ? IFSOCK
- : s.isFIFO() ? IFIFO
- : UNKNOWN;
-// normalize unicode path names
-const normalizeCache = new Map();
-const normalize = (s) => {
- const c = normalizeCache.get(s);
- if (c)
- return c;
- const n = s.normalize('NFKD');
- normalizeCache.set(s, n);
- return n;
-};
-const normalizeNocaseCache = new Map();
-const normalizeNocase = (s) => {
- const c = normalizeNocaseCache.get(s);
- if (c)
- return c;
- const n = normalize(s.toLowerCase());
- normalizeNocaseCache.set(s, n);
- return n;
-};
-/**
- * An LRUCache for storing resolved path strings or Path objects.
- * @internal
- */
-class ResolveCache extends lru_cache_1.LRUCache {
- constructor() {
- super({ max: 256 });
- }
-}
-exports.ResolveCache = ResolveCache;
-// In order to prevent blowing out the js heap by allocating hundreds of
-// thousands of Path entries when walking extremely large trees, the "children"
-// in this tree are represented by storing an array of Path entries in an
-// LRUCache, indexed by the parent. At any time, Path.children() may return an
-// empty array, indicating that it doesn't know about any of its children, and
-// thus has to rebuild that cache. This is fine, it just means that we don't
-// benefit as much from having the cached entries, but huge directory walks
-// don't blow out the stack, and smaller ones are still as fast as possible.
-//
-//It does impose some complexity when building up the readdir data, because we
-//need to pass a reference to the children array that we started with.
-/**
- * an LRUCache for storing child entries.
- * @internal
- */
-class ChildrenCache extends lru_cache_1.LRUCache {
- constructor(maxSize = 16 * 1024) {
- super({
- maxSize,
- // parent + children
- sizeCalculation: a => a.length + 1,
- });
- }
-}
-exports.ChildrenCache = ChildrenCache;
-const setAsCwd = Symbol('PathScurry setAsCwd');
-/**
- * Path objects are sort of like a super-powered
- * {@link https://nodejs.org/docs/latest/api/fs.html#class-fsdirent fs.Dirent}
- *
- * Each one represents a single filesystem entry on disk, which may or may not
- * exist. It includes methods for reading various types of information via
- * lstat, readlink, and readdir, and caches all information to the greatest
- * degree possible.
- *
- * Note that fs operations that would normally throw will instead return an
- * "empty" value. This is in order to prevent excessive overhead from error
- * stack traces.
- */
-class PathBase {
- /**
- * the basename of this path
- *
- * **Important**: *always* test the path name against any test string
- * usingthe {@link isNamed} method, and not by directly comparing this
- * string. Otherwise, unicode path strings that the system sees as identical
- * will not be properly treated as the same path, leading to incorrect
- * behavior and possible security issues.
- */
- name;
- /**
- * the Path entry corresponding to the path root.
- *
- * @internal
- */
- root;
- /**
- * All roots found within the current PathScurry family
- *
- * @internal
- */
- roots;
- /**
- * a reference to the parent path, or undefined in the case of root entries
- *
- * @internal
- */
- parent;
- /**
- * boolean indicating whether paths are compared case-insensitively
- * @internal
- */
- nocase;
- /**
- * boolean indicating that this path is the current working directory
- * of the PathScurry collection that contains it.
- */
- isCWD = false;
- // potential default fs override
- #fs;
- // Stats fields
- #dev;
- get dev() {
- return this.#dev;
- }
- #mode;
- get mode() {
- return this.#mode;
- }
- #nlink;
- get nlink() {
- return this.#nlink;
- }
- #uid;
- get uid() {
- return this.#uid;
- }
- #gid;
- get gid() {
- return this.#gid;
- }
- #rdev;
- get rdev() {
- return this.#rdev;
- }
- #blksize;
- get blksize() {
- return this.#blksize;
- }
- #ino;
- get ino() {
- return this.#ino;
- }
- #size;
- get size() {
- return this.#size;
- }
- #blocks;
- get blocks() {
- return this.#blocks;
- }
- #atimeMs;
- get atimeMs() {
- return this.#atimeMs;
- }
- #mtimeMs;
- get mtimeMs() {
- return this.#mtimeMs;
- }
- #ctimeMs;
- get ctimeMs() {
- return this.#ctimeMs;
- }
- #birthtimeMs;
- get birthtimeMs() {
- return this.#birthtimeMs;
- }
- #atime;
- get atime() {
- return this.#atime;
- }
- #mtime;
- get mtime() {
- return this.#mtime;
- }
- #ctime;
- get ctime() {
- return this.#ctime;
- }
- #birthtime;
- get birthtime() {
- return this.#birthtime;
- }
- #matchName;
- #depth;
- #fullpath;
- #fullpathPosix;
- #relative;
- #relativePosix;
- #type;
- #children;
- #linkTarget;
- #realpath;
- /**
- * This property is for compatibility with the Dirent class as of
- * Node v20, where Dirent['parentPath'] refers to the path of the
- * directory that was passed to readdir. For root entries, it's the path
- * to the entry itself.
- */
- get parentPath() {
- return (this.parent || this).fullpath();
- }
- /**
- * Deprecated alias for Dirent['parentPath'] Somewhat counterintuitively,
- * this property refers to the *parent* path, not the path object itself.
- */
- get path() {
- return this.parentPath;
- }
- /**
- * Do not create new Path objects directly. They should always be accessed
- * via the PathScurry class or other methods on the Path class.
- *
- * @internal
- */
- constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) {
- this.name = name;
- this.#matchName = nocase ? normalizeNocase(name) : normalize(name);
- this.#type = type & TYPEMASK;
- this.nocase = nocase;
- this.roots = roots;
- this.root = root || this;
- this.#children = children;
- this.#fullpath = opts.fullpath;
- this.#relative = opts.relative;
- this.#relativePosix = opts.relativePosix;
- this.parent = opts.parent;
- if (this.parent) {
- this.#fs = this.parent.#fs;
- }
- else {
- this.#fs = fsFromOption(opts.fs);
- }
- }
- /**
- * Returns the depth of the Path object from its root.
- *
- * For example, a path at `/foo/bar` would have a depth of 2.
- */
- depth() {
- if (this.#depth !== undefined)
- return this.#depth;
- if (!this.parent)
- return (this.#depth = 0);
- return (this.#depth = this.parent.depth() + 1);
- }
- /**
- * @internal
- */
- childrenCache() {
- return this.#children;
- }
- /**
- * Get the Path object referenced by the string path, resolved from this Path
- */
- resolve(path) {
- if (!path) {
- return this;
- }
- const rootPath = this.getRootString(path);
- const dir = path.substring(rootPath.length);
- const dirParts = dir.split(this.splitSep);
- const result = rootPath ?
- this.getRoot(rootPath).#resolveParts(dirParts)
- : this.#resolveParts(dirParts);
- return result;
- }
- #resolveParts(dirParts) {
- let p = this;
- for (const part of dirParts) {
- p = p.child(part);
- }
- return p;
- }
- /**
- * Returns the cached children Path objects, if still available. If they
- * have fallen out of the cache, then returns an empty array, and resets the
- * READDIR_CALLED bit, so that future calls to readdir() will require an fs
- * lookup.
- *
- * @internal
- */
- children() {
- const cached = this.#children.get(this);
- if (cached) {
- return cached;
- }
- const children = Object.assign([], { provisional: 0 });
- this.#children.set(this, children);
- this.#type &= ~READDIR_CALLED;
- return children;
- }
- /**
- * Resolves a path portion and returns or creates the child Path.
- *
- * Returns `this` if pathPart is `''` or `'.'`, or `parent` if pathPart is
- * `'..'`.
- *
- * This should not be called directly. If `pathPart` contains any path
- * separators, it will lead to unsafe undefined behavior.
- *
- * Use `Path.resolve()` instead.
- *
- * @internal
- */
- child(pathPart, opts) {
- if (pathPart === '' || pathPart === '.') {
- return this;
- }
- if (pathPart === '..') {
- return this.parent || this;
- }
- // find the child
- const children = this.children();
- const name = this.nocase ? normalizeNocase(pathPart) : normalize(pathPart);
- for (const p of children) {
- if (p.#matchName === name) {
- return p;
- }
- }
- // didn't find it, create provisional child, since it might not
- // actually exist. If we know the parent isn't a dir, then
- // in fact it CAN'T exist.
- const s = this.parent ? this.sep : '';
- const fullpath = this.#fullpath ? this.#fullpath + s + pathPart : undefined;
- const pchild = this.newChild(pathPart, UNKNOWN, {
- ...opts,
- parent: this,
- fullpath,
- });
- if (!this.canReaddir()) {
- pchild.#type |= ENOENT;
- }
- // don't have to update provisional, because if we have real children,
- // then provisional is set to children.length, otherwise a lower number
- children.push(pchild);
- return pchild;
- }
- /**
- * The relative path from the cwd. If it does not share an ancestor with
- * the cwd, then this ends up being equivalent to the fullpath()
- */
- relative() {
- if (this.isCWD)
- return '';
- if (this.#relative !== undefined) {
- return this.#relative;
- }
- const name = this.name;
- const p = this.parent;
- if (!p) {
- return (this.#relative = this.name);
- }
- const pv = p.relative();
- return pv + (!pv || !p.parent ? '' : this.sep) + name;
- }
- /**
- * The relative path from the cwd, using / as the path separator.
- * If it does not share an ancestor with
- * the cwd, then this ends up being equivalent to the fullpathPosix()
- * On posix systems, this is identical to relative().
- */
- relativePosix() {
- if (this.sep === '/')
- return this.relative();
- if (this.isCWD)
- return '';
- if (this.#relativePosix !== undefined)
- return this.#relativePosix;
- const name = this.name;
- const p = this.parent;
- if (!p) {
- return (this.#relativePosix = this.fullpathPosix());
- }
- const pv = p.relativePosix();
- return pv + (!pv || !p.parent ? '' : '/') + name;
- }
- /**
- * The fully resolved path string for this Path entry
- */
- fullpath() {
- if (this.#fullpath !== undefined) {
- return this.#fullpath;
- }
- const name = this.name;
- const p = this.parent;
- if (!p) {
- return (this.#fullpath = this.name);
- }
- const pv = p.fullpath();
- const fp = pv + (!p.parent ? '' : this.sep) + name;
- return (this.#fullpath = fp);
- }
- /**
- * On platforms other than windows, this is identical to fullpath.
- *
- * On windows, this is overridden to return the forward-slash form of the
- * full UNC path.
- */
- fullpathPosix() {
- if (this.#fullpathPosix !== undefined)
- return this.#fullpathPosix;
- if (this.sep === '/')
- return (this.#fullpathPosix = this.fullpath());
- if (!this.parent) {
- const p = this.fullpath().replace(/\\/g, '/');
- if (/^[a-z]:\//i.test(p)) {
- return (this.#fullpathPosix = `//?/${p}`);
- }
- else {
- return (this.#fullpathPosix = p);
- }
- }
- const p = this.parent;
- const pfpp = p.fullpathPosix();
- const fpp = pfpp + (!pfpp || !p.parent ? '' : '/') + this.name;
- return (this.#fullpathPosix = fpp);
- }
- /**
- * Is the Path of an unknown type?
- *
- * Note that we might know *something* about it if there has been a previous
- * filesystem operation, for example that it does not exist, or is not a
- * link, or whether it has child entries.
- */
- isUnknown() {
- return (this.#type & IFMT) === UNKNOWN;
- }
- isType(type) {
- return this[`is${type}`]();
- }
- getType() {
- return (this.isUnknown() ? 'Unknown'
- : this.isDirectory() ? 'Directory'
- : this.isFile() ? 'File'
- : this.isSymbolicLink() ? 'SymbolicLink'
- : this.isFIFO() ? 'FIFO'
- : this.isCharacterDevice() ? 'CharacterDevice'
- : this.isBlockDevice() ? 'BlockDevice'
- : /* c8 ignore start */ this.isSocket() ? 'Socket'
- : 'Unknown');
- /* c8 ignore stop */
- }
- /**
- * Is the Path a regular file?
- */
- isFile() {
- return (this.#type & IFMT) === IFREG;
- }
- /**
- * Is the Path a directory?
- */
- isDirectory() {
- return (this.#type & IFMT) === IFDIR;
- }
- /**
- * Is the path a character device?
- */
- isCharacterDevice() {
- return (this.#type & IFMT) === IFCHR;
- }
- /**
- * Is the path a block device?
- */
- isBlockDevice() {
- return (this.#type & IFMT) === IFBLK;
- }
- /**
- * Is the path a FIFO pipe?
- */
- isFIFO() {
- return (this.#type & IFMT) === IFIFO;
- }
- /**
- * Is the path a socket?
- */
- isSocket() {
- return (this.#type & IFMT) === IFSOCK;
- }
- /**
- * Is the path a symbolic link?
- */
- isSymbolicLink() {
- return (this.#type & IFLNK) === IFLNK;
- }
- /**
- * Return the entry if it has been subject of a successful lstat, or
- * undefined otherwise.
- *
- * Does not read the filesystem, so an undefined result *could* simply
- * mean that we haven't called lstat on it.
- */
- lstatCached() {
- return this.#type & LSTAT_CALLED ? this : undefined;
- }
- /**
- * Return the cached link target if the entry has been the subject of a
- * successful readlink, or undefined otherwise.
- *
- * Does not read the filesystem, so an undefined result *could* just mean we
- * don't have any cached data. Only use it if you are very sure that a
- * readlink() has been called at some point.
- */
- readlinkCached() {
- return this.#linkTarget;
- }
- /**
- * Returns the cached realpath target if the entry has been the subject
- * of a successful realpath, or undefined otherwise.
- *
- * Does not read the filesystem, so an undefined result *could* just mean we
- * don't have any cached data. Only use it if you are very sure that a
- * realpath() has been called at some point.
- */
- realpathCached() {
- return this.#realpath;
- }
- /**
- * Returns the cached child Path entries array if the entry has been the
- * subject of a successful readdir(), or [] otherwise.
- *
- * Does not read the filesystem, so an empty array *could* just mean we
- * don't have any cached data. Only use it if you are very sure that a
- * readdir() has been called recently enough to still be valid.
- */
- readdirCached() {
- const children = this.children();
- return children.slice(0, children.provisional);
- }
- /**
- * Return true if it's worth trying to readlink. Ie, we don't (yet) have
- * any indication that readlink will definitely fail.
- *
- * Returns false if the path is known to not be a symlink, if a previous
- * readlink failed, or if the entry does not exist.
- */
- canReadlink() {
- if (this.#linkTarget)
- return true;
- if (!this.parent)
- return false;
- // cases where it cannot possibly succeed
- const ifmt = this.#type & IFMT;
- return !((ifmt !== UNKNOWN && ifmt !== IFLNK) ||
- this.#type & ENOREADLINK ||
- this.#type & ENOENT);
- }
- /**
- * Return true if readdir has previously been successfully called on this
- * path, indicating that cachedReaddir() is likely valid.
- */
- calledReaddir() {
- return !!(this.#type & READDIR_CALLED);
- }
- /**
- * Returns true if the path is known to not exist. That is, a previous lstat
- * or readdir failed to verify its existence when that would have been
- * expected, or a parent entry was marked either enoent or enotdir.
- */
- isENOENT() {
- return !!(this.#type & ENOENT);
- }
- /**
- * Return true if the path is a match for the given path name. This handles
- * case sensitivity and unicode normalization.
- *
- * Note: even on case-sensitive systems, it is **not** safe to test the
- * equality of the `.name` property to determine whether a given pathname
- * matches, due to unicode normalization mismatches.
- *
- * Always use this method instead of testing the `path.name` property
- * directly.
- */
- isNamed(n) {
- return !this.nocase ?
- this.#matchName === normalize(n)
- : this.#matchName === normalizeNocase(n);
- }
- /**
- * Return the Path object corresponding to the target of a symbolic link.
- *
- * If the Path is not a symbolic link, or if the readlink call fails for any
- * reason, `undefined` is returned.
- *
- * Result is cached, and thus may be outdated if the filesystem is mutated.
- */
- async readlink() {
- const target = this.#linkTarget;
- if (target) {
- return target;
- }
- if (!this.canReadlink()) {
- return undefined;
- }
- /* c8 ignore start */
- // already covered by the canReadlink test, here for ts grumples
- if (!this.parent) {
- return undefined;
- }
- /* c8 ignore stop */
- try {
- const read = await this.#fs.promises.readlink(this.fullpath());
- const linkTarget = (await this.parent.realpath())?.resolve(read);
- if (linkTarget) {
- return (this.#linkTarget = linkTarget);
- }
- }
- catch (er) {
- this.#readlinkFail(er.code);
- return undefined;
- }
- }
- /**
- * Synchronous {@link PathBase.readlink}
- */
- readlinkSync() {
- const target = this.#linkTarget;
- if (target) {
- return target;
- }
- if (!this.canReadlink()) {
- return undefined;
- }
- /* c8 ignore start */
- // already covered by the canReadlink test, here for ts grumples
- if (!this.parent) {
- return undefined;
- }
- /* c8 ignore stop */
- try {
- const read = this.#fs.readlinkSync(this.fullpath());
- const linkTarget = this.parent.realpathSync()?.resolve(read);
- if (linkTarget) {
- return (this.#linkTarget = linkTarget);
- }
- }
- catch (er) {
- this.#readlinkFail(er.code);
- return undefined;
- }
- }
- #readdirSuccess(children) {
- // succeeded, mark readdir called bit
- this.#type |= READDIR_CALLED;
- // mark all remaining provisional children as ENOENT
- for (let p = children.provisional; p < children.length; p++) {
- const c = children[p];
- if (c)
- c.#markENOENT();
- }
- }
- #markENOENT() {
- // mark as UNKNOWN and ENOENT
- if (this.#type & ENOENT)
- return;
- this.#type = (this.#type | ENOENT) & IFMT_UNKNOWN;
- this.#markChildrenENOENT();
- }
- #markChildrenENOENT() {
- // all children are provisional and do not exist
- const children = this.children();
- children.provisional = 0;
- for (const p of children) {
- p.#markENOENT();
- }
- }
- #markENOREALPATH() {
- this.#type |= ENOREALPATH;
- this.#markENOTDIR();
- }
- // save the information when we know the entry is not a dir
- #markENOTDIR() {
- // entry is not a directory, so any children can't exist.
- // this *should* be impossible, since any children created
- // after it's been marked ENOTDIR should be marked ENOENT,
- // so it won't even get to this point.
- /* c8 ignore start */
- if (this.#type & ENOTDIR)
- return;
- /* c8 ignore stop */
- let t = this.#type;
- // this could happen if we stat a dir, then delete it,
- // then try to read it or one of its children.
- if ((t & IFMT) === IFDIR)
- t &= IFMT_UNKNOWN;
- this.#type = t | ENOTDIR;
- this.#markChildrenENOENT();
- }
- #readdirFail(code = '') {
- // markENOTDIR and markENOENT also set provisional=0
- if (code === 'ENOTDIR' || code === 'EPERM') {
- this.#markENOTDIR();
- }
- else if (code === 'ENOENT') {
- this.#markENOENT();
- }
- else {
- this.children().provisional = 0;
- }
- }
- #lstatFail(code = '') {
- // Windows just raises ENOENT in this case, disable for win CI
- /* c8 ignore start */
- if (code === 'ENOTDIR') {
- // already know it has a parent by this point
- const p = this.parent;
- p.#markENOTDIR();
- }
- else if (code === 'ENOENT') {
- /* c8 ignore stop */
- this.#markENOENT();
- }
- }
- #readlinkFail(code = '') {
- let ter = this.#type;
- ter |= ENOREADLINK;
- if (code === 'ENOENT')
- ter |= ENOENT;
- // windows gets a weird error when you try to readlink a file
- if (code === 'EINVAL' || code === 'UNKNOWN') {
- // exists, but not a symlink, we don't know WHAT it is, so remove
- // all IFMT bits.
- ter &= IFMT_UNKNOWN;
- }
- this.#type = ter;
- // windows just gets ENOENT in this case. We do cover the case,
- // just disabled because it's impossible on Windows CI
- /* c8 ignore start */
- if (code === 'ENOTDIR' && this.parent) {
- this.parent.#markENOTDIR();
- }
- /* c8 ignore stop */
- }
- #readdirAddChild(e, c) {
- return (this.#readdirMaybePromoteChild(e, c) ||
- this.#readdirAddNewChild(e, c));
- }
- #readdirAddNewChild(e, c) {
- // alloc new entry at head, so it's never provisional
- const type = entToType(e);
- const child = this.newChild(e.name, type, { parent: this });
- const ifmt = child.#type & IFMT;
- if (ifmt !== IFDIR && ifmt !== IFLNK && ifmt !== UNKNOWN) {
- child.#type |= ENOTDIR;
- }
- c.unshift(child);
- c.provisional++;
- return child;
- }
- #readdirMaybePromoteChild(e, c) {
- for (let p = c.provisional; p < c.length; p++) {
- const pchild = c[p];
- const name = this.nocase ? normalizeNocase(e.name) : normalize(e.name);
- if (name !== pchild.#matchName) {
- continue;
- }
- return this.#readdirPromoteChild(e, pchild, p, c);
- }
- }
- #readdirPromoteChild(e, p, index, c) {
- const v = p.name;
- // retain any other flags, but set ifmt from dirent
- p.#type = (p.#type & IFMT_UNKNOWN) | entToType(e);
- // case sensitivity fixing when we learn the true name.
- if (v !== e.name)
- p.name = e.name;
- // just advance provisional index (potentially off the list),
- // otherwise we have to splice/pop it out and re-insert at head
- if (index !== c.provisional) {
- if (index === c.length - 1)
- c.pop();
- else
- c.splice(index, 1);
- c.unshift(p);
- }
- c.provisional++;
- return p;
- }
- /**
- * Call lstat() on this Path, and update all known information that can be
- * determined.
- *
- * Note that unlike `fs.lstat()`, the returned value does not contain some
- * information, such as `mode`, `dev`, `nlink`, and `ino`. If that
- * information is required, you will need to call `fs.lstat` yourself.
- *
- * If the Path refers to a nonexistent file, or if the lstat call fails for
- * any reason, `undefined` is returned. Otherwise the updated Path object is
- * returned.
- *
- * Results are cached, and thus may be out of date if the filesystem is
- * mutated.
- */
- async lstat() {
- if ((this.#type & ENOENT) === 0) {
- try {
- this.#applyStat(await this.#fs.promises.lstat(this.fullpath()));
- return this;
- }
- catch (er) {
- this.#lstatFail(er.code);
- }
- }
- }
- /**
- * synchronous {@link PathBase.lstat}
- */
- lstatSync() {
- if ((this.#type & ENOENT) === 0) {
- try {
- this.#applyStat(this.#fs.lstatSync(this.fullpath()));
- return this;
- }
- catch (er) {
- this.#lstatFail(er.code);
- }
- }
- }
- #applyStat(st) {
- const { atime, atimeMs, birthtime, birthtimeMs, blksize, blocks, ctime, ctimeMs, dev, gid, ino, mode, mtime, mtimeMs, nlink, rdev, size, uid, } = st;
- this.#atime = atime;
- this.#atimeMs = atimeMs;
- this.#birthtime = birthtime;
- this.#birthtimeMs = birthtimeMs;
- this.#blksize = blksize;
- this.#blocks = blocks;
- this.#ctime = ctime;
- this.#ctimeMs = ctimeMs;
- this.#dev = dev;
- this.#gid = gid;
- this.#ino = ino;
- this.#mode = mode;
- this.#mtime = mtime;
- this.#mtimeMs = mtimeMs;
- this.#nlink = nlink;
- this.#rdev = rdev;
- this.#size = size;
- this.#uid = uid;
- const ifmt = entToType(st);
- // retain any other flags, but set the ifmt
- this.#type = (this.#type & IFMT_UNKNOWN) | ifmt | LSTAT_CALLED;
- if (ifmt !== UNKNOWN && ifmt !== IFDIR && ifmt !== IFLNK) {
- this.#type |= ENOTDIR;
- }
- }
- #onReaddirCB = [];
- #readdirCBInFlight = false;
- #callOnReaddirCB(children) {
- this.#readdirCBInFlight = false;
- const cbs = this.#onReaddirCB.slice();
- this.#onReaddirCB.length = 0;
- cbs.forEach(cb => cb(null, children));
- }
- /**
- * Standard node-style callback interface to get list of directory entries.
- *
- * If the Path cannot or does not contain any children, then an empty array
- * is returned.
- *
- * Results are cached, and thus may be out of date if the filesystem is
- * mutated.
- *
- * @param cb The callback called with (er, entries). Note that the `er`
- * param is somewhat extraneous, as all readdir() errors are handled and
- * simply result in an empty set of entries being returned.
- * @param allowZalgo Boolean indicating that immediately known results should
- * *not* be deferred with `queueMicrotask`. Defaults to `false`. Release
- * zalgo at your peril, the dark pony lord is devious and unforgiving.
- */
- readdirCB(cb, allowZalgo = false) {
- if (!this.canReaddir()) {
- if (allowZalgo)
- cb(null, []);
- else
- queueMicrotask(() => cb(null, []));
- return;
- }
- const children = this.children();
- if (this.calledReaddir()) {
- const c = children.slice(0, children.provisional);
- if (allowZalgo)
- cb(null, c);
- else
- queueMicrotask(() => cb(null, c));
- return;
- }
- // don't have to worry about zalgo at this point.
- this.#onReaddirCB.push(cb);
- if (this.#readdirCBInFlight) {
- return;
- }
- this.#readdirCBInFlight = true;
- // else read the directory, fill up children
- // de-provisionalize any provisional children.
- const fullpath = this.fullpath();
- this.#fs.readdir(fullpath, { withFileTypes: true }, (er, entries) => {
- if (er) {
- this.#readdirFail(er.code);
- children.provisional = 0;
- }
- else {
- // if we didn't get an error, we always get entries.
- //@ts-ignore
- for (const e of entries) {
- this.#readdirAddChild(e, children);
- }
- this.#readdirSuccess(children);
- }
- this.#callOnReaddirCB(children.slice(0, children.provisional));
- return;
- });
- }
- #asyncReaddirInFlight;
- /**
- * Return an array of known child entries.
- *
- * If the Path cannot or does not contain any children, then an empty array
- * is returned.
- *
- * Results are cached, and thus may be out of date if the filesystem is
- * mutated.
- */
- async readdir() {
- if (!this.canReaddir()) {
- return [];
- }
- const children = this.children();
- if (this.calledReaddir()) {
- return children.slice(0, children.provisional);
- }
- // else read the directory, fill up children
- // de-provisionalize any provisional children.
- const fullpath = this.fullpath();
- if (this.#asyncReaddirInFlight) {
- await this.#asyncReaddirInFlight;
- }
- else {
- /* c8 ignore start */
- let resolve = () => { };
- /* c8 ignore stop */
- this.#asyncReaddirInFlight = new Promise(res => (resolve = res));
- try {
- for (const e of await this.#fs.promises.readdir(fullpath, {
- withFileTypes: true,
- })) {
- this.#readdirAddChild(e, children);
- }
- this.#readdirSuccess(children);
- }
- catch (er) {
- this.#readdirFail(er.code);
- children.provisional = 0;
- }
- this.#asyncReaddirInFlight = undefined;
- resolve();
- }
- return children.slice(0, children.provisional);
- }
- /**
- * synchronous {@link PathBase.readdir}
- */
- readdirSync() {
- if (!this.canReaddir()) {
- return [];
- }
- const children = this.children();
- if (this.calledReaddir()) {
- return children.slice(0, children.provisional);
- }
- // else read the directory, fill up children
- // de-provisionalize any provisional children.
- const fullpath = this.fullpath();
- try {
- for (const e of this.#fs.readdirSync(fullpath, {
- withFileTypes: true,
- })) {
- this.#readdirAddChild(e, children);
- }
- this.#readdirSuccess(children);
- }
- catch (er) {
- this.#readdirFail(er.code);
- children.provisional = 0;
- }
- return children.slice(0, children.provisional);
- }
- canReaddir() {
- if (this.#type & ENOCHILD)
- return false;
- const ifmt = IFMT & this.#type;
- // we always set ENOTDIR when setting IFMT, so should be impossible
- /* c8 ignore start */
- if (!(ifmt === UNKNOWN || ifmt === IFDIR || ifmt === IFLNK)) {
- return false;
- }
- /* c8 ignore stop */
- return true;
- }
- shouldWalk(dirs, walkFilter) {
- return ((this.#type & IFDIR) === IFDIR &&
- !(this.#type & ENOCHILD) &&
- !dirs.has(this) &&
- (!walkFilter || walkFilter(this)));
- }
- /**
- * Return the Path object corresponding to path as resolved
- * by realpath(3).
- *
- * If the realpath call fails for any reason, `undefined` is returned.
- *
- * Result is cached, and thus may be outdated if the filesystem is mutated.
- * On success, returns a Path object.
- */
- async realpath() {
- if (this.#realpath)
- return this.#realpath;
- if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type)
- return undefined;
- try {
- const rp = await this.#fs.promises.realpath(this.fullpath());
- return (this.#realpath = this.resolve(rp));
- }
- catch (_) {
- this.#markENOREALPATH();
- }
- }
- /**
- * Synchronous {@link realpath}
- */
- realpathSync() {
- if (this.#realpath)
- return this.#realpath;
- if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type)
- return undefined;
- try {
- const rp = this.#fs.realpathSync(this.fullpath());
- return (this.#realpath = this.resolve(rp));
- }
- catch (_) {
- this.#markENOREALPATH();
- }
- }
- /**
- * Internal method to mark this Path object as the scurry cwd,
- * called by {@link PathScurry#chdir}
- *
- * @internal
- */
- [setAsCwd](oldCwd) {
- if (oldCwd === this)
- return;
- oldCwd.isCWD = false;
- this.isCWD = true;
- const changed = new Set([]);
- let rp = [];
- let p = this;
- while (p && p.parent) {
- changed.add(p);
- p.#relative = rp.join(this.sep);
- p.#relativePosix = rp.join('/');
- p = p.parent;
- rp.push('..');
- }
- // now un-memoize parents of old cwd
- p = oldCwd;
- while (p && p.parent && !changed.has(p)) {
- p.#relative = undefined;
- p.#relativePosix = undefined;
- p = p.parent;
- }
- }
-}
-exports.PathBase = PathBase;
-/**
- * Path class used on win32 systems
- *
- * Uses `'\\'` as the path separator for returned paths, either `'\\'` or `'/'`
- * as the path separator for parsing paths.
- */
-class PathWin32 extends PathBase {
- /**
- * Separator for generating path strings.
- */
- sep = '\\';
- /**
- * Separator for parsing path strings.
- */
- splitSep = eitherSep;
- /**
- * Do not create new Path objects directly. They should always be accessed
- * via the PathScurry class or other methods on the Path class.
- *
- * @internal
- */
- constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) {
- super(name, type, root, roots, nocase, children, opts);
- }
- /**
- * @internal
- */
- newChild(name, type = UNKNOWN, opts = {}) {
- return new PathWin32(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts);
- }
- /**
- * @internal
- */
- getRootString(path) {
- return node_path_1.win32.parse(path).root;
- }
- /**
- * @internal
- */
- getRoot(rootPath) {
- rootPath = uncToDrive(rootPath.toUpperCase());
- if (rootPath === this.root.name) {
- return this.root;
- }
- // ok, not that one, check if it matches another we know about
- for (const [compare, root] of Object.entries(this.roots)) {
- if (this.sameRoot(rootPath, compare)) {
- return (this.roots[rootPath] = root);
- }
- }
- // otherwise, have to create a new one.
- return (this.roots[rootPath] = new PathScurryWin32(rootPath, this).root);
- }
- /**
- * @internal
- */
- sameRoot(rootPath, compare = this.root.name) {
- // windows can (rarely) have case-sensitive filesystem, but
- // UNC and drive letters are always case-insensitive, and canonically
- // represented uppercase.
- rootPath = rootPath
- .toUpperCase()
- .replace(/\//g, '\\')
- .replace(uncDriveRegexp, '$1\\');
- return rootPath === compare;
- }
-}
-exports.PathWin32 = PathWin32;
-/**
- * Path class used on all posix systems.
- *
- * Uses `'/'` as the path separator.
- */
-class PathPosix extends PathBase {
- /**
- * separator for parsing path strings
- */
- splitSep = '/';
- /**
- * separator for generating path strings
- */
- sep = '/';
- /**
- * Do not create new Path objects directly. They should always be accessed
- * via the PathScurry class or other methods on the Path class.
- *
- * @internal
- */
- constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) {
- super(name, type, root, roots, nocase, children, opts);
- }
- /**
- * @internal
- */
- getRootString(path) {
- return path.startsWith('/') ? '/' : '';
- }
- /**
- * @internal
- */
- getRoot(_rootPath) {
- return this.root;
- }
- /**
- * @internal
- */
- newChild(name, type = UNKNOWN, opts = {}) {
- return new PathPosix(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts);
- }
-}
-exports.PathPosix = PathPosix;
-/**
- * The base class for all PathScurry classes, providing the interface for path
- * resolution and filesystem operations.
- *
- * Typically, you should *not* instantiate this class directly, but rather one
- * of the platform-specific classes, or the exported {@link PathScurry} which
- * defaults to the current platform.
- */
-class PathScurryBase {
- /**
- * The root Path entry for the current working directory of this Scurry
- */
- root;
- /**
- * The string path for the root of this Scurry's current working directory
- */
- rootPath;
- /**
- * A collection of all roots encountered, referenced by rootPath
- */
- roots;
- /**
- * The Path entry corresponding to this PathScurry's current working directory.
- */
- cwd;
- #resolveCache;
- #resolvePosixCache;
- #children;
- /**
- * Perform path comparisons case-insensitively.
- *
- * Defaults true on Darwin and Windows systems, false elsewhere.
- */
- nocase;
- #fs;
- /**
- * This class should not be instantiated directly.
- *
- * Use PathScurryWin32, PathScurryDarwin, PathScurryPosix, or PathScurry
- *
- * @internal
- */
- constructor(cwd = process.cwd(), pathImpl, sep, { nocase, childrenCacheSize = 16 * 1024, fs = defaultFS, } = {}) {
- this.#fs = fsFromOption(fs);
- if (cwd instanceof URL || cwd.startsWith('file://')) {
- cwd = (0, node_url_1.fileURLToPath)(cwd);
- }
- // resolve and split root, and then add to the store.
- // this is the only time we call path.resolve()
- const cwdPath = pathImpl.resolve(cwd);
- this.roots = Object.create(null);
- this.rootPath = this.parseRootPath(cwdPath);
- this.#resolveCache = new ResolveCache();
- this.#resolvePosixCache = new ResolveCache();
- this.#children = new ChildrenCache(childrenCacheSize);
- const split = cwdPath.substring(this.rootPath.length).split(sep);
- // resolve('/') leaves '', splits to [''], we don't want that.
- if (split.length === 1 && !split[0]) {
- split.pop();
- }
- /* c8 ignore start */
- if (nocase === undefined) {
- throw new TypeError('must provide nocase setting to PathScurryBase ctor');
- }
- /* c8 ignore stop */
- this.nocase = nocase;
- this.root = this.newRoot(this.#fs);
- this.roots[this.rootPath] = this.root;
- let prev = this.root;
- let len = split.length - 1;
- const joinSep = pathImpl.sep;
- let abs = this.rootPath;
- let sawFirst = false;
- for (const part of split) {
- const l = len--;
- prev = prev.child(part, {
- relative: new Array(l).fill('..').join(joinSep),
- relativePosix: new Array(l).fill('..').join('/'),
- fullpath: (abs += (sawFirst ? '' : joinSep) + part),
- });
- sawFirst = true;
- }
- this.cwd = prev;
- }
- /**
- * Get the depth of a provided path, string, or the cwd
- */
- depth(path = this.cwd) {
- if (typeof path === 'string') {
- path = this.cwd.resolve(path);
- }
- return path.depth();
- }
- /**
- * Return the cache of child entries. Exposed so subclasses can create
- * child Path objects in a platform-specific way.
- *
- * @internal
- */
- childrenCache() {
- return this.#children;
- }
- /**
- * Resolve one or more path strings to a resolved string
- *
- * Same interface as require('path').resolve.
- *
- * Much faster than path.resolve() when called multiple times for the same
- * path, because the resolved Path objects are cached. Much slower
- * otherwise.
- */
- resolve(...paths) {
- // first figure out the minimum number of paths we have to test
- // we always start at cwd, but any absolutes will bump the start
- let r = '';
- for (let i = paths.length - 1; i >= 0; i--) {
- const p = paths[i];
- if (!p || p === '.')
- continue;
- r = r ? `${p}/${r}` : p;
- if (this.isAbsolute(p)) {
- break;
- }
- }
- const cached = this.#resolveCache.get(r);
- if (cached !== undefined) {
- return cached;
- }
- const result = this.cwd.resolve(r).fullpath();
- this.#resolveCache.set(r, result);
- return result;
- }
- /**
- * Resolve one or more path strings to a resolved string, returning
- * the posix path. Identical to .resolve() on posix systems, but on
- * windows will return a forward-slash separated UNC path.
- *
- * Same interface as require('path').resolve.
- *
- * Much faster than path.resolve() when called multiple times for the same
- * path, because the resolved Path objects are cached. Much slower
- * otherwise.
- */
- resolvePosix(...paths) {
- // first figure out the minimum number of paths we have to test
- // we always start at cwd, but any absolutes will bump the start
- let r = '';
- for (let i = paths.length - 1; i >= 0; i--) {
- const p = paths[i];
- if (!p || p === '.')
- continue;
- r = r ? `${p}/${r}` : p;
- if (this.isAbsolute(p)) {
- break;
- }
- }
- const cached = this.#resolvePosixCache.get(r);
- if (cached !== undefined) {
- return cached;
- }
- const result = this.cwd.resolve(r).fullpathPosix();
- this.#resolvePosixCache.set(r, result);
- return result;
- }
- /**
- * find the relative path from the cwd to the supplied path string or entry
- */
- relative(entry = this.cwd) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- return entry.relative();
- }
- /**
- * find the relative path from the cwd to the supplied path string or
- * entry, using / as the path delimiter, even on Windows.
- */
- relativePosix(entry = this.cwd) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- return entry.relativePosix();
- }
- /**
- * Return the basename for the provided string or Path object
- */
- basename(entry = this.cwd) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- return entry.name;
- }
- /**
- * Return the dirname for the provided string or Path object
- */
- dirname(entry = this.cwd) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- return (entry.parent || entry).fullpath();
- }
- async readdir(entry = this.cwd, opts = {
- withFileTypes: true,
- }) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- else if (!(entry instanceof PathBase)) {
- opts = entry;
- entry = this.cwd;
- }
- const { withFileTypes } = opts;
- if (!entry.canReaddir()) {
- return [];
- }
- else {
- const p = await entry.readdir();
- return withFileTypes ? p : p.map(e => e.name);
- }
- }
- readdirSync(entry = this.cwd, opts = {
- withFileTypes: true,
- }) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- else if (!(entry instanceof PathBase)) {
- opts = entry;
- entry = this.cwd;
- }
- const { withFileTypes = true } = opts;
- if (!entry.canReaddir()) {
- return [];
- }
- else if (withFileTypes) {
- return entry.readdirSync();
- }
- else {
- return entry.readdirSync().map(e => e.name);
- }
- }
- /**
- * Call lstat() on the string or Path object, and update all known
- * information that can be determined.
- *
- * Note that unlike `fs.lstat()`, the returned value does not contain some
- * information, such as `mode`, `dev`, `nlink`, and `ino`. If that
- * information is required, you will need to call `fs.lstat` yourself.
- *
- * If the Path refers to a nonexistent file, or if the lstat call fails for
- * any reason, `undefined` is returned. Otherwise the updated Path object is
- * returned.
- *
- * Results are cached, and thus may be out of date if the filesystem is
- * mutated.
- */
- async lstat(entry = this.cwd) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- return entry.lstat();
- }
- /**
- * synchronous {@link PathScurryBase.lstat}
- */
- lstatSync(entry = this.cwd) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- return entry.lstatSync();
- }
- async readlink(entry = this.cwd, { withFileTypes } = {
- withFileTypes: false,
- }) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- else if (!(entry instanceof PathBase)) {
- withFileTypes = entry.withFileTypes;
- entry = this.cwd;
- }
- const e = await entry.readlink();
- return withFileTypes ? e : e?.fullpath();
- }
- readlinkSync(entry = this.cwd, { withFileTypes } = {
- withFileTypes: false,
- }) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- else if (!(entry instanceof PathBase)) {
- withFileTypes = entry.withFileTypes;
- entry = this.cwd;
- }
- const e = entry.readlinkSync();
- return withFileTypes ? e : e?.fullpath();
- }
- async realpath(entry = this.cwd, { withFileTypes } = {
- withFileTypes: false,
- }) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- else if (!(entry instanceof PathBase)) {
- withFileTypes = entry.withFileTypes;
- entry = this.cwd;
- }
- const e = await entry.realpath();
- return withFileTypes ? e : e?.fullpath();
- }
- realpathSync(entry = this.cwd, { withFileTypes } = {
- withFileTypes: false,
- }) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- else if (!(entry instanceof PathBase)) {
- withFileTypes = entry.withFileTypes;
- entry = this.cwd;
- }
- const e = entry.realpathSync();
- return withFileTypes ? e : e?.fullpath();
- }
- async walk(entry = this.cwd, opts = {}) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- else if (!(entry instanceof PathBase)) {
- opts = entry;
- entry = this.cwd;
- }
- const { withFileTypes = true, follow = false, filter, walkFilter, } = opts;
- const results = [];
- if (!filter || filter(entry)) {
- results.push(withFileTypes ? entry : entry.fullpath());
- }
- const dirs = new Set();
- const walk = (dir, cb) => {
- dirs.add(dir);
- dir.readdirCB((er, entries) => {
- /* c8 ignore start */
- if (er) {
- return cb(er);
- }
- /* c8 ignore stop */
- let len = entries.length;
- if (!len)
- return cb();
- const next = () => {
- if (--len === 0) {
- cb();
- }
- };
- for (const e of entries) {
- if (!filter || filter(e)) {
- results.push(withFileTypes ? e : e.fullpath());
- }
- if (follow && e.isSymbolicLink()) {
- e.realpath()
- .then(r => (r?.isUnknown() ? r.lstat() : r))
- .then(r => r?.shouldWalk(dirs, walkFilter) ? walk(r, next) : next());
- }
- else {
- if (e.shouldWalk(dirs, walkFilter)) {
- walk(e, next);
- }
- else {
- next();
- }
- }
- }
- }, true); // zalgooooooo
- };
- const start = entry;
- return new Promise((res, rej) => {
- walk(start, er => {
- /* c8 ignore start */
- if (er)
- return rej(er);
- /* c8 ignore stop */
- res(results);
- });
- });
- }
- walkSync(entry = this.cwd, opts = {}) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- else if (!(entry instanceof PathBase)) {
- opts = entry;
- entry = this.cwd;
- }
- const { withFileTypes = true, follow = false, filter, walkFilter, } = opts;
- const results = [];
- if (!filter || filter(entry)) {
- results.push(withFileTypes ? entry : entry.fullpath());
- }
- const dirs = new Set([entry]);
- for (const dir of dirs) {
- const entries = dir.readdirSync();
- for (const e of entries) {
- if (!filter || filter(e)) {
- results.push(withFileTypes ? e : e.fullpath());
- }
- let r = e;
- if (e.isSymbolicLink()) {
- if (!(follow && (r = e.realpathSync())))
- continue;
- if (r.isUnknown())
- r.lstatSync();
- }
- if (r.shouldWalk(dirs, walkFilter)) {
- dirs.add(r);
- }
- }
- }
- return results;
- }
- /**
- * Support for `for await`
- *
- * Alias for {@link PathScurryBase.iterate}
- *
- * Note: As of Node 19, this is very slow, compared to other methods of
- * walking. Consider using {@link PathScurryBase.stream} if memory overhead
- * and backpressure are concerns, or {@link PathScurryBase.walk} if not.
- */
- [Symbol.asyncIterator]() {
- return this.iterate();
- }
- iterate(entry = this.cwd, options = {}) {
- // iterating async over the stream is significantly more performant,
- // especially in the warm-cache scenario, because it buffers up directory
- // entries in the background instead of waiting for a yield for each one.
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- else if (!(entry instanceof PathBase)) {
- options = entry;
- entry = this.cwd;
- }
- return this.stream(entry, options)[Symbol.asyncIterator]();
- }
- /**
- * Iterating over a PathScurry performs a synchronous walk.
- *
- * Alias for {@link PathScurryBase.iterateSync}
- */
- [Symbol.iterator]() {
- return this.iterateSync();
- }
- *iterateSync(entry = this.cwd, opts = {}) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- else if (!(entry instanceof PathBase)) {
- opts = entry;
- entry = this.cwd;
- }
- const { withFileTypes = true, follow = false, filter, walkFilter, } = opts;
- if (!filter || filter(entry)) {
- yield withFileTypes ? entry : entry.fullpath();
- }
- const dirs = new Set([entry]);
- for (const dir of dirs) {
- const entries = dir.readdirSync();
- for (const e of entries) {
- if (!filter || filter(e)) {
- yield withFileTypes ? e : e.fullpath();
- }
- let r = e;
- if (e.isSymbolicLink()) {
- if (!(follow && (r = e.realpathSync())))
- continue;
- if (r.isUnknown())
- r.lstatSync();
- }
- if (r.shouldWalk(dirs, walkFilter)) {
- dirs.add(r);
- }
- }
- }
- }
- stream(entry = this.cwd, opts = {}) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- else if (!(entry instanceof PathBase)) {
- opts = entry;
- entry = this.cwd;
- }
- const { withFileTypes = true, follow = false, filter, walkFilter, } = opts;
- const results = new minipass_1.Minipass({ objectMode: true });
- if (!filter || filter(entry)) {
- results.write(withFileTypes ? entry : entry.fullpath());
- }
- const dirs = new Set();
- const queue = [entry];
- let processing = 0;
- const process = () => {
- let paused = false;
- while (!paused) {
- const dir = queue.shift();
- if (!dir) {
- if (processing === 0)
- results.end();
- return;
- }
- processing++;
- dirs.add(dir);
- const onReaddir = (er, entries, didRealpaths = false) => {
- /* c8 ignore start */
- if (er)
- return results.emit('error', er);
- /* c8 ignore stop */
- if (follow && !didRealpaths) {
- const promises = [];
- for (const e of entries) {
- if (e.isSymbolicLink()) {
- promises.push(e
- .realpath()
- .then((r) => r?.isUnknown() ? r.lstat() : r));
- }
- }
- if (promises.length) {
- Promise.all(promises).then(() => onReaddir(null, entries, true));
- return;
- }
- }
- for (const e of entries) {
- if (e && (!filter || filter(e))) {
- if (!results.write(withFileTypes ? e : e.fullpath())) {
- paused = true;
- }
- }
- }
- processing--;
- for (const e of entries) {
- const r = e.realpathCached() || e;
- if (r.shouldWalk(dirs, walkFilter)) {
- queue.push(r);
- }
- }
- if (paused && !results.flowing) {
- results.once('drain', process);
- }
- else if (!sync) {
- process();
- }
- };
- // zalgo containment
- let sync = true;
- dir.readdirCB(onReaddir, true);
- sync = false;
- }
- };
- process();
- return results;
- }
- streamSync(entry = this.cwd, opts = {}) {
- if (typeof entry === 'string') {
- entry = this.cwd.resolve(entry);
- }
- else if (!(entry instanceof PathBase)) {
- opts = entry;
- entry = this.cwd;
- }
- const { withFileTypes = true, follow = false, filter, walkFilter, } = opts;
- const results = new minipass_1.Minipass({ objectMode: true });
- const dirs = new Set();
- if (!filter || filter(entry)) {
- results.write(withFileTypes ? entry : entry.fullpath());
- }
- const queue = [entry];
- let processing = 0;
- const process = () => {
- let paused = false;
- while (!paused) {
- const dir = queue.shift();
- if (!dir) {
- if (processing === 0)
- results.end();
- return;
- }
- processing++;
- dirs.add(dir);
- const entries = dir.readdirSync();
- for (const e of entries) {
- if (!filter || filter(e)) {
- if (!results.write(withFileTypes ? e : e.fullpath())) {
- paused = true;
- }
- }
- }
- processing--;
- for (const e of entries) {
- let r = e;
- if (e.isSymbolicLink()) {
- if (!(follow && (r = e.realpathSync())))
- continue;
- if (r.isUnknown())
- r.lstatSync();
- }
- if (r.shouldWalk(dirs, walkFilter)) {
- queue.push(r);
- }
- }
- }
- if (paused && !results.flowing)
- results.once('drain', process);
- };
- process();
- return results;
- }
- chdir(path = this.cwd) {
- const oldCwd = this.cwd;
- this.cwd = typeof path === 'string' ? this.cwd.resolve(path) : path;
- this.cwd[setAsCwd](oldCwd);
- }
-}
-exports.PathScurryBase = PathScurryBase;
-/**
- * Windows implementation of {@link PathScurryBase}
- *
- * Defaults to case insensitve, uses `'\\'` to generate path strings. Uses
- * {@link PathWin32} for Path objects.
- */
-class PathScurryWin32 extends PathScurryBase {
- /**
- * separator for generating path strings
- */
- sep = '\\';
- constructor(cwd = process.cwd(), opts = {}) {
- const { nocase = true } = opts;
- super(cwd, node_path_1.win32, '\\', { ...opts, nocase });
- this.nocase = nocase;
- for (let p = this.cwd; p; p = p.parent) {
- p.nocase = this.nocase;
- }
- }
- /**
- * @internal
- */
- parseRootPath(dir) {
- // if the path starts with a single separator, it's not a UNC, and we'll
- // just get separator as the root, and driveFromUNC will return \
- // In that case, mount \ on the root from the cwd.
- return node_path_1.win32.parse(dir).root.toUpperCase();
- }
- /**
- * @internal
- */
- newRoot(fs) {
- return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs });
- }
- /**
- * Return true if the provided path string is an absolute path
- */
- isAbsolute(p) {
- return (p.startsWith('/') || p.startsWith('\\') || /^[a-z]:(\/|\\)/i.test(p));
- }
-}
-exports.PathScurryWin32 = PathScurryWin32;
-/**
- * {@link PathScurryBase} implementation for all posix systems other than Darwin.
- *
- * Defaults to case-sensitive matching, uses `'/'` to generate path strings.
- *
- * Uses {@link PathPosix} for Path objects.
- */
-class PathScurryPosix extends PathScurryBase {
- /**
- * separator for generating path strings
- */
- sep = '/';
- constructor(cwd = process.cwd(), opts = {}) {
- const { nocase = false } = opts;
- super(cwd, node_path_1.posix, '/', { ...opts, nocase });
- this.nocase = nocase;
- }
- /**
- * @internal
- */
- parseRootPath(_dir) {
- return '/';
- }
- /**
- * @internal
- */
- newRoot(fs) {
- return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs });
- }
- /**
- * Return true if the provided path string is an absolute path
- */
- isAbsolute(p) {
- return p.startsWith('/');
- }
-}
-exports.PathScurryPosix = PathScurryPosix;
-/**
- * {@link PathScurryBase} implementation for Darwin (macOS) systems.
- *
- * Defaults to case-insensitive matching, uses `'/'` for generating path
- * strings.
- *
- * Uses {@link PathPosix} for Path objects.
- */
-class PathScurryDarwin extends PathScurryPosix {
- constructor(cwd = process.cwd(), opts = {}) {
- const { nocase = true } = opts;
- super(cwd, { ...opts, nocase });
- }
-}
-exports.PathScurryDarwin = PathScurryDarwin;
-/**
- * Default {@link PathBase} implementation for the current platform.
- *
- * {@link PathWin32} on Windows systems, {@link PathPosix} on all others.
- */
-exports.Path = process.platform === 'win32' ? PathWin32 : PathPosix;
-/**
- * Default {@link PathScurryBase} implementation for the current platform.
- *
- * {@link PathScurryWin32} on Windows systems, {@link PathScurryDarwin} on
- * Darwin (macOS) systems, {@link PathScurryPosix} on all others.
- */
-exports.PathScurry = process.platform === 'win32' ? PathScurryWin32
- : process.platform === 'darwin' ? PathScurryDarwin
- : PathScurryPosix;
-//# sourceMappingURL=index.js.map
-
-/***/ }),
-
-/***/ 3278:
-/***/ ((__unused_webpack_module, exports) => {
-
-
-/**
- * @module LRUCache
- */
-Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.LRUCache = void 0;
-const perf = typeof performance === 'object' &&
- performance &&
- typeof performance.now === 'function'
- ? performance
- : Date;
-const warned = new Set();
-/* c8 ignore start */
-const PROCESS = (typeof process === 'object' && !!process ? process : {});
-/* c8 ignore start */
-const emitWarning = (msg, type, code, fn) => {
- typeof PROCESS.emitWarning === 'function'
- ? PROCESS.emitWarning(msg, type, code, fn)
- : console.error(`[${code}] ${type}: ${msg}`);
-};
-let AC = globalThis.AbortController;
-let AS = globalThis.AbortSignal;
-/* c8 ignore start */
-if (typeof AC === 'undefined') {
- //@ts-ignore
- AS = class AbortSignal {
- onabort;
- _onabort = [];
- reason;
- aborted = false;
- addEventListener(_, fn) {
- this._onabort.push(fn);
- }
- };
- //@ts-ignore
- AC = class AbortController {
- constructor() {
- warnACPolyfill();
- }
- signal = new AS();
- abort(reason) {
- if (this.signal.aborted)
- return;
- //@ts-ignore
- this.signal.reason = reason;
- //@ts-ignore
- this.signal.aborted = true;
- //@ts-ignore
- for (const fn of this.signal._onabort) {
- fn(reason);
- }
- this.signal.onabort?.(reason);
- }
- };
- let printACPolyfillWarning = PROCESS.env?.LRU_CACHE_IGNORE_AC_WARNING !== '1';
- const warnACPolyfill = () => {
- if (!printACPolyfillWarning)
- return;
- printACPolyfillWarning = false;
- emitWarning('AbortController is not defined. If using lru-cache in ' +
- 'node 14, load an AbortController polyfill from the ' +
- '`node-abort-controller` package. A minimal polyfill is ' +
- 'provided for use by LRUCache.fetch(), but it should not be ' +
- 'relied upon in other contexts (eg, passing it to other APIs that ' +
- 'use AbortController/AbortSignal might have undesirable effects). ' +
- 'You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.', 'NO_ABORT_CONTROLLER', 'ENOTSUP', warnACPolyfill);
- };
-}
-/* c8 ignore stop */
-const shouldWarn = (code) => !warned.has(code);
-const TYPE = Symbol('type');
-const isPosInt = (n) => n && n === Math.floor(n) && n > 0 && isFinite(n);
-/* c8 ignore start */
-// This is a little bit ridiculous, tbh.
-// The maximum array length is 2^32-1 or thereabouts on most JS impls.
-// And well before that point, you're caching the entire world, I mean,
-// that's ~32GB of just integers for the next/prev links, plus whatever
-// else to hold that many keys and values. Just filling the memory with
-// zeroes at init time is brutal when you get that big.
-// But why not be complete?
-// Maybe in the future, these limits will have expanded.
-const getUintArray = (max) => !isPosInt(max)
- ? null
- : max <= Math.pow(2, 8)
- ? Uint8Array
- : max <= Math.pow(2, 16)
- ? Uint16Array
- : max <= Math.pow(2, 32)
- ? Uint32Array
- : max <= Number.MAX_SAFE_INTEGER
- ? ZeroArray
- : null;
-/* c8 ignore stop */
-class ZeroArray extends Array {
- constructor(size) {
- super(size);
- this.fill(0);
- }
-}
-class Stack {
- heap;
- length;
- // private constructor
- static #constructing = false;
- static create(max) {
- const HeapCls = getUintArray(max);
- if (!HeapCls)
- return [];
- Stack.#constructing = true;
- const s = new Stack(max, HeapCls);
- Stack.#constructing = false;
- return s;
- }
- constructor(max, HeapCls) {
- /* c8 ignore start */
- if (!Stack.#constructing) {
- throw new TypeError('instantiate Stack using Stack.create(n)');
- }
- /* c8 ignore stop */
- this.heap = new HeapCls(max);
- this.length = 0;
- }
- push(n) {
- this.heap[this.length++] = n;
- }
- pop() {
- return this.heap[--this.length];
- }
-}
-/**
- * Default export, the thing you're using this module to get.
- *
- * The `K` and `V` types define the key and value types, respectively. The
- * optional `FC` type defines the type of the `context` object passed to
- * `cache.fetch()` and `cache.memo()`.
- *
- * Keys and values **must not** be `null` or `undefined`.
- *
- * All properties from the options object (with the exception of `max`,
- * `maxSize`, `fetchMethod`, `memoMethod`, `dispose` and `disposeAfter`) are
- * added as normal public members. (The listed options are read-only getters.)
- *
- * Changing any of these will alter the defaults for subsequent method calls.
- */
-class LRUCache {
- // options that cannot be changed without disaster
- #max;
- #maxSize;
- #dispose;
- #disposeAfter;
- #fetchMethod;
- #memoMethod;
- /**
- * {@link LRUCache.OptionsBase.ttl}
- */
- ttl;
- /**
- * {@link LRUCache.OptionsBase.ttlResolution}
- */
- ttlResolution;
- /**
- * {@link LRUCache.OptionsBase.ttlAutopurge}
- */
- ttlAutopurge;
- /**
- * {@link LRUCache.OptionsBase.updateAgeOnGet}
- */
- updateAgeOnGet;
- /**
- * {@link LRUCache.OptionsBase.updateAgeOnHas}
- */
- updateAgeOnHas;
- /**
- * {@link LRUCache.OptionsBase.allowStale}
- */
- allowStale;
- /**
- * {@link LRUCache.OptionsBase.noDisposeOnSet}
- */
- noDisposeOnSet;
- /**
- * {@link LRUCache.OptionsBase.noUpdateTTL}
- */
- noUpdateTTL;
- /**
- * {@link LRUCache.OptionsBase.maxEntrySize}
- */
- maxEntrySize;
- /**
- * {@link LRUCache.OptionsBase.sizeCalculation}
- */
- sizeCalculation;
- /**
- * {@link LRUCache.OptionsBase.noDeleteOnFetchRejection}
- */
- noDeleteOnFetchRejection;
- /**
- * {@link LRUCache.OptionsBase.noDeleteOnStaleGet}
- */
- noDeleteOnStaleGet;
- /**
- * {@link LRUCache.OptionsBase.allowStaleOnFetchAbort}
- */
- allowStaleOnFetchAbort;
- /**
- * {@link LRUCache.OptionsBase.allowStaleOnFetchRejection}
- */
- allowStaleOnFetchRejection;
- /**
- * {@link LRUCache.OptionsBase.ignoreFetchAbort}
- */
- ignoreFetchAbort;
- // computed properties
- #size;
- #calculatedSize;
- #keyMap;
- #keyList;
- #valList;
- #next;
- #prev;
- #head;
- #tail;
- #free;
- #disposed;
- #sizes;
- #starts;
- #ttls;
- #hasDispose;
- #hasFetchMethod;
- #hasDisposeAfter;
- /**
- * Do not call this method unless you need to inspect the
- * inner workings of the cache. If anything returned by this
- * object is modified in any way, strange breakage may occur.
- *
- * These fields are private for a reason!
- *
- * @internal
- */
- static unsafeExposeInternals(c) {
- return {
- // properties
- starts: c.#starts,
- ttls: c.#ttls,
- sizes: c.#sizes,
- keyMap: c.#keyMap,
- keyList: c.#keyList,
- valList: c.#valList,
- next: c.#next,
- prev: c.#prev,
- get head() {
- return c.#head;
- },
- get tail() {
- return c.#tail;
- },
- free: c.#free,
- // methods
- isBackgroundFetch: (p) => c.#isBackgroundFetch(p),
- backgroundFetch: (k, index, options, context) => c.#backgroundFetch(k, index, options, context),
- moveToTail: (index) => c.#moveToTail(index),
- indexes: (options) => c.#indexes(options),
- rindexes: (options) => c.#rindexes(options),
- isStale: (index) => c.#isStale(index),
- };
- }
- // Protected read-only members
- /**
- * {@link LRUCache.OptionsBase.max} (read-only)
- */
- get max() {
- return this.#max;
- }
- /**
- * {@link LRUCache.OptionsBase.maxSize} (read-only)
- */
- get maxSize() {
- return this.#maxSize;
- }
- /**
- * The total computed size of items in the cache (read-only)
- */
- get calculatedSize() {
- return this.#calculatedSize;
- }
- /**
- * The number of items stored in the cache (read-only)
- */
- get size() {
- return this.#size;
- }
- /**
- * {@link LRUCache.OptionsBase.fetchMethod} (read-only)
- */
- get fetchMethod() {
- return this.#fetchMethod;
- }
- get memoMethod() {
- return this.#memoMethod;
- }
- /**
- * {@link LRUCache.OptionsBase.dispose} (read-only)
- */
- get dispose() {
- return this.#dispose;
- }
- /**
- * {@link LRUCache.OptionsBase.disposeAfter} (read-only)
- */
- get disposeAfter() {
- return this.#disposeAfter;
- }
- constructor(options) {
- const { max = 0, ttl, ttlResolution = 1, ttlAutopurge, updateAgeOnGet, updateAgeOnHas, allowStale, dispose, disposeAfter, noDisposeOnSet, noUpdateTTL, maxSize = 0, maxEntrySize = 0, sizeCalculation, fetchMethod, memoMethod, noDeleteOnFetchRejection, noDeleteOnStaleGet, allowStaleOnFetchRejection, allowStaleOnFetchAbort, ignoreFetchAbort, } = options;
- if (max !== 0 && !isPosInt(max)) {
- throw new TypeError('max option must be a nonnegative integer');
- }
- const UintArray = max ? getUintArray(max) : Array;
- if (!UintArray) {
- throw new Error('invalid max value: ' + max);
- }
- this.#max = max;
- this.#maxSize = maxSize;
- this.maxEntrySize = maxEntrySize || this.#maxSize;
- this.sizeCalculation = sizeCalculation;
- if (this.sizeCalculation) {
- if (!this.#maxSize && !this.maxEntrySize) {
- throw new TypeError('cannot set sizeCalculation without setting maxSize or maxEntrySize');
- }
- if (typeof this.sizeCalculation !== 'function') {
- throw new TypeError('sizeCalculation set to non-function');
- }
- }
- if (memoMethod !== undefined &&
- typeof memoMethod !== 'function') {
- throw new TypeError('memoMethod must be a function if defined');
- }
- this.#memoMethod = memoMethod;
- if (fetchMethod !== undefined &&
- typeof fetchMethod !== 'function') {
- throw new TypeError('fetchMethod must be a function if specified');
- }
- this.#fetchMethod = fetchMethod;
- this.#hasFetchMethod = !!fetchMethod;
- this.#keyMap = new Map();
- this.#keyList = new Array(max).fill(undefined);
- this.#valList = new Array(max).fill(undefined);
- this.#next = new UintArray(max);
- this.#prev = new UintArray(max);
- this.#head = 0;
- this.#tail = 0;
- this.#free = Stack.create(max);
- this.#size = 0;
- this.#calculatedSize = 0;
- if (typeof dispose === 'function') {
- this.#dispose = dispose;
- }
- if (typeof disposeAfter === 'function') {
- this.#disposeAfter = disposeAfter;
- this.#disposed = [];
- }
- else {
- this.#disposeAfter = undefined;
- this.#disposed = undefined;
- }
- this.#hasDispose = !!this.#dispose;
- this.#hasDisposeAfter = !!this.#disposeAfter;
- this.noDisposeOnSet = !!noDisposeOnSet;
- this.noUpdateTTL = !!noUpdateTTL;
- this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection;
- this.allowStaleOnFetchRejection = !!allowStaleOnFetchRejection;
- this.allowStaleOnFetchAbort = !!allowStaleOnFetchAbort;
- this.ignoreFetchAbort = !!ignoreFetchAbort;
- // NB: maxEntrySize is set to maxSize if it's set
- if (this.maxEntrySize !== 0) {
- if (this.#maxSize !== 0) {
- if (!isPosInt(this.#maxSize)) {
- throw new TypeError('maxSize must be a positive integer if specified');
- }
- }
- if (!isPosInt(this.maxEntrySize)) {
- throw new TypeError('maxEntrySize must be a positive integer if specified');
- }
- this.#initializeSizeTracking();
- }
- this.allowStale = !!allowStale;
- this.noDeleteOnStaleGet = !!noDeleteOnStaleGet;
- this.updateAgeOnGet = !!updateAgeOnGet;
- this.updateAgeOnHas = !!updateAgeOnHas;
- this.ttlResolution =
- isPosInt(ttlResolution) || ttlResolution === 0
- ? ttlResolution
- : 1;
- this.ttlAutopurge = !!ttlAutopurge;
- this.ttl = ttl || 0;
- if (this.ttl) {
- if (!isPosInt(this.ttl)) {
- throw new TypeError('ttl must be a positive integer if specified');
- }
- this.#initializeTTLTracking();
- }
- // do not allow completely unbounded caches
- if (this.#max === 0 && this.ttl === 0 && this.#maxSize === 0) {
- throw new TypeError('At least one of max, maxSize, or ttl is required');
- }
- if (!this.ttlAutopurge && !this.#max && !this.#maxSize) {
- const code = 'LRU_CACHE_UNBOUNDED';
- if (shouldWarn(code)) {
- warned.add(code);
- const msg = 'TTL caching without ttlAutopurge, max, or maxSize can ' +
- 'result in unbounded memory consumption.';
- emitWarning(msg, 'UnboundedCacheWarning', code, LRUCache);
- }
- }
- }
- /**
- * Return the number of ms left in the item's TTL. If item is not in cache,
- * returns `0`. Returns `Infinity` if item is in cache without a defined TTL.
- */
- getRemainingTTL(key) {
- return this.#keyMap.has(key) ? Infinity : 0;
- }
- #initializeTTLTracking() {
- const ttls = new ZeroArray(this.#max);
- const starts = new ZeroArray(this.#max);
- this.#ttls = ttls;
- this.#starts = starts;
- this.#setItemTTL = (index, ttl, start = perf.now()) => {
- starts[index] = ttl !== 0 ? start : 0;
- ttls[index] = ttl;
- if (ttl !== 0 && this.ttlAutopurge) {
- const t = setTimeout(() => {
- if (this.#isStale(index)) {
- this.#delete(this.#keyList[index], 'expire');
- }
- }, ttl + 1);
- // unref() not supported on all platforms
- /* c8 ignore start */
- if (t.unref) {
- t.unref();
- }
- /* c8 ignore stop */
- }
- };
- this.#updateItemAge = index => {
- starts[index] = ttls[index] !== 0 ? perf.now() : 0;
- };
- this.#statusTTL = (status, index) => {
- if (ttls[index]) {
- const ttl = ttls[index];
- const start = starts[index];
- /* c8 ignore next */
- if (!ttl || !start)
- return;
- status.ttl = ttl;
- status.start = start;
- status.now = cachedNow || getNow();
- const age = status.now - start;
- status.remainingTTL = ttl - age;
- }
- };
- // debounce calls to perf.now() to 1s so we're not hitting
- // that costly call repeatedly.
- let cachedNow = 0;
- const getNow = () => {
- const n = perf.now();
- if (this.ttlResolution > 0) {
- cachedNow = n;
- const t = setTimeout(() => (cachedNow = 0), this.ttlResolution);
- // not available on all platforms
- /* c8 ignore start */
- if (t.unref) {
- t.unref();
- }
- /* c8 ignore stop */
- }
- return n;
- };
- this.getRemainingTTL = key => {
- const index = this.#keyMap.get(key);
- if (index === undefined) {
- return 0;
- }
- const ttl = ttls[index];
- const start = starts[index];
- if (!ttl || !start) {
- return Infinity;
- }
- const age = (cachedNow || getNow()) - start;
- return ttl - age;
- };
- this.#isStale = index => {
- const s = starts[index];
- const t = ttls[index];
- return !!t && !!s && (cachedNow || getNow()) - s > t;
- };
- }
- // conditionally set private methods related to TTL
- #updateItemAge = () => { };
- #statusTTL = () => { };
- #setItemTTL = () => { };
- /* c8 ignore stop */
- #isStale = () => false;
- #initializeSizeTracking() {
- const sizes = new ZeroArray(this.#max);
- this.#calculatedSize = 0;
- this.#sizes = sizes;
- this.#removeItemSize = index => {
- this.#calculatedSize -= sizes[index];
- sizes[index] = 0;
- };
- this.#requireSize = (k, v, size, sizeCalculation) => {
- // provisionally accept background fetches.
- // actual value size will be checked when they return.
- if (this.#isBackgroundFetch(v)) {
- return 0;
- }
- if (!isPosInt(size)) {
- if (sizeCalculation) {
- if (typeof sizeCalculation !== 'function') {
- throw new TypeError('sizeCalculation must be a function');
- }
- size = sizeCalculation(v, k);
- if (!isPosInt(size)) {
- throw new TypeError('sizeCalculation return invalid (expect positive integer)');
- }
- }
- else {
- throw new TypeError('invalid size value (must be positive integer). ' +
- 'When maxSize or maxEntrySize is used, sizeCalculation ' +
- 'or size must be set.');
- }
- }
- return size;
- };
- this.#addItemSize = (index, size, status) => {
- sizes[index] = size;
- if (this.#maxSize) {
- const maxSize = this.#maxSize - sizes[index];
- while (this.#calculatedSize > maxSize) {
- this.#evict(true);
- }
- }
- this.#calculatedSize += sizes[index];
- if (status) {
- status.entrySize = size;
- status.totalCalculatedSize = this.#calculatedSize;
- }
- };
- }
- #removeItemSize = _i => { };
- #addItemSize = (_i, _s, _st) => { };
- #requireSize = (_k, _v, size, sizeCalculation) => {
- if (size || sizeCalculation) {
- throw new TypeError('cannot set size without setting maxSize or maxEntrySize on cache');
- }
- return 0;
- };
- *#indexes({ allowStale = this.allowStale } = {}) {
- if (this.#size) {
- for (let i = this.#tail; true;) {
- if (!this.#isValidIndex(i)) {
- break;
- }
- if (allowStale || !this.#isStale(i)) {
- yield i;
- }
- if (i === this.#head) {
- break;
- }
- else {
- i = this.#prev[i];
- }
- }
- }
- }
- *#rindexes({ allowStale = this.allowStale } = {}) {
- if (this.#size) {
- for (let i = this.#head; true;) {
- if (!this.#isValidIndex(i)) {
- break;
- }
- if (allowStale || !this.#isStale(i)) {
- yield i;
- }
- if (i === this.#tail) {
- break;
- }
- else {
- i = this.#next[i];
- }
- }
- }
- }
- #isValidIndex(index) {
- return (index !== undefined &&
- this.#keyMap.get(this.#keyList[index]) === index);
- }
- /**
- * Return a generator yielding `[key, value]` pairs,
- * in order from most recently used to least recently used.
- */
- *entries() {
- for (const i of this.#indexes()) {
- if (this.#valList[i] !== undefined &&
- this.#keyList[i] !== undefined &&
- !this.#isBackgroundFetch(this.#valList[i])) {
- yield [this.#keyList[i], this.#valList[i]];
- }
- }
- }
- /**
- * Inverse order version of {@link LRUCache.entries}
- *
- * Return a generator yielding `[key, value]` pairs,
- * in order from least recently used to most recently used.
- */
- *rentries() {
- for (const i of this.#rindexes()) {
- if (this.#valList[i] !== undefined &&
- this.#keyList[i] !== undefined &&
- !this.#isBackgroundFetch(this.#valList[i])) {
- yield [this.#keyList[i], this.#valList[i]];
- }
- }
- }
- /**
- * Return a generator yielding the keys in the cache,
- * in order from most recently used to least recently used.
- */
- *keys() {
- for (const i of this.#indexes()) {
- const k = this.#keyList[i];
- if (k !== undefined &&
- !this.#isBackgroundFetch(this.#valList[i])) {
- yield k;
- }
- }
- }
- /**
- * Inverse order version of {@link LRUCache.keys}
- *
- * Return a generator yielding the keys in the cache,
- * in order from least recently used to most recently used.
- */
- *rkeys() {
- for (const i of this.#rindexes()) {
- const k = this.#keyList[i];
- if (k !== undefined &&
- !this.#isBackgroundFetch(this.#valList[i])) {
- yield k;
- }
- }
- }
- /**
- * Return a generator yielding the values in the cache,
- * in order from most recently used to least recently used.
- */
- *values() {
- for (const i of this.#indexes()) {
- const v = this.#valList[i];
- if (v !== undefined &&
- !this.#isBackgroundFetch(this.#valList[i])) {
- yield this.#valList[i];
- }
- }
- }
- /**
- * Inverse order version of {@link LRUCache.values}
- *
- * Return a generator yielding the values in the cache,
- * in order from least recently used to most recently used.
- */
- *rvalues() {
- for (const i of this.#rindexes()) {
- const v = this.#valList[i];
- if (v !== undefined &&
- !this.#isBackgroundFetch(this.#valList[i])) {
- yield this.#valList[i];
- }
- }
- }
- /**
- * Iterating over the cache itself yields the same results as
- * {@link LRUCache.entries}
- */
- [Symbol.iterator]() {
- return this.entries();
- }
- /**
- * A String value that is used in the creation of the default string
- * description of an object. Called by the built-in method
- * `Object.prototype.toString`.
- */
- [Symbol.toStringTag] = 'LRUCache';
- /**
- * Find a value for which the supplied fn method returns a truthy value,
- * similar to `Array.find()`. fn is called as `fn(value, key, cache)`.
- */
- find(fn, getOptions = {}) {
- for (const i of this.#indexes()) {
- const v = this.#valList[i];
- const value = this.#isBackgroundFetch(v)
- ? v.__staleWhileFetching
- : v;
- if (value === undefined)
- continue;
- if (fn(value, this.#keyList[i], this)) {
- return this.get(this.#keyList[i], getOptions);
- }
- }
- }
- /**
- * Call the supplied function on each item in the cache, in order from most
- * recently used to least recently used.
- *
- * `fn` is called as `fn(value, key, cache)`.
- *
- * If `thisp` is provided, function will be called in the `this`-context of
- * the provided object, or the cache if no `thisp` object is provided.
- *
- * Does not update age or recenty of use, or iterate over stale values.
- */
- forEach(fn, thisp = this) {
- for (const i of this.#indexes()) {
- const v = this.#valList[i];
- const value = this.#isBackgroundFetch(v)
- ? v.__staleWhileFetching
- : v;
- if (value === undefined)
- continue;
- fn.call(thisp, value, this.#keyList[i], this);
- }
- }
- /**
- * The same as {@link LRUCache.forEach} but items are iterated over in
- * reverse order. (ie, less recently used items are iterated over first.)
- */
- rforEach(fn, thisp = this) {
- for (const i of this.#rindexes()) {
- const v = this.#valList[i];
- const value = this.#isBackgroundFetch(v)
- ? v.__staleWhileFetching
- : v;
- if (value === undefined)
- continue;
- fn.call(thisp, value, this.#keyList[i], this);
- }
- }
- /**
- * Delete any stale entries. Returns true if anything was removed,
- * false otherwise.
- */
- purgeStale() {
- let deleted = false;
- for (const i of this.#rindexes({ allowStale: true })) {
- if (this.#isStale(i)) {
- this.#delete(this.#keyList[i], 'expire');
- deleted = true;
- }
- }
- return deleted;
- }
- /**
- * Get the extended info about a given entry, to get its value, size, and
- * TTL info simultaneously. Returns `undefined` if the key is not present.
- *
- * Unlike {@link LRUCache#dump}, which is designed to be portable and survive
- * serialization, the `start` value is always the current timestamp, and the
- * `ttl` is a calculated remaining time to live (negative if expired).
- *
- * Always returns stale values, if their info is found in the cache, so be
- * sure to check for expirations (ie, a negative {@link LRUCache.Entry#ttl})
- * if relevant.
- */
- info(key) {
- const i = this.#keyMap.get(key);
- if (i === undefined)
- return undefined;
- const v = this.#valList[i];
- const value = this.#isBackgroundFetch(v)
- ? v.__staleWhileFetching
- : v;
- if (value === undefined)
- return undefined;
- const entry = { value };
- if (this.#ttls && this.#starts) {
- const ttl = this.#ttls[i];
- const start = this.#starts[i];
- if (ttl && start) {
- const remain = ttl - (perf.now() - start);
- entry.ttl = remain;
- entry.start = Date.now();
- }
- }
- if (this.#sizes) {
- entry.size = this.#sizes[i];
- }
- return entry;
- }
- /**
- * Return an array of [key, {@link LRUCache.Entry}] tuples which can be
- * passed to {@link LRLUCache#load}.
- *
- * The `start` fields are calculated relative to a portable `Date.now()`
- * timestamp, even if `performance.now()` is available.
- *
- * Stale entries are always included in the `dump`, even if
- * {@link LRUCache.OptionsBase.allowStale} is false.
- *
- * Note: this returns an actual array, not a generator, so it can be more
- * easily passed around.
- */
- dump() {
- const arr = [];
- for (const i of this.#indexes({ allowStale: true })) {
- const key = this.#keyList[i];
- const v = this.#valList[i];
- const value = this.#isBackgroundFetch(v)
- ? v.__staleWhileFetching
- : v;
- if (value === undefined || key === undefined)
- continue;
- const entry = { value };
- if (this.#ttls && this.#starts) {
- entry.ttl = this.#ttls[i];
- // always dump the start relative to a portable timestamp
- // it's ok for this to be a bit slow, it's a rare operation.
- const age = perf.now() - this.#starts[i];
- entry.start = Math.floor(Date.now() - age);
- }
- if (this.#sizes) {
- entry.size = this.#sizes[i];
- }
- arr.unshift([key, entry]);
- }
- return arr;
- }
- /**
- * Reset the cache and load in the items in entries in the order listed.
- *
- * The shape of the resulting cache may be different if the same options are
- * not used in both caches.
- *
- * The `start` fields are assumed to be calculated relative to a portable
- * `Date.now()` timestamp, even if `performance.now()` is available.
- */
- load(arr) {
- this.clear();
- for (const [key, entry] of arr) {
- if (entry.start) {
- // entry.start is a portable timestamp, but we may be using
- // node's performance.now(), so calculate the offset, so that
- // we get the intended remaining TTL, no matter how long it's
- // been on ice.
- //
- // it's ok for this to be a bit slow, it's a rare operation.
- const age = Date.now() - entry.start;
- entry.start = perf.now() - age;
- }
- this.set(key, entry.value, entry);
- }
- }
- /**
- * Add a value to the cache.
- *
- * Note: if `undefined` is specified as a value, this is an alias for
- * {@link LRUCache#delete}
- *
- * Fields on the {@link LRUCache.SetOptions} options param will override
- * their corresponding values in the constructor options for the scope
- * of this single `set()` operation.
- *
- * If `start` is provided, then that will set the effective start
- * time for the TTL calculation. Note that this must be a previous
- * value of `performance.now()` if supported, or a previous value of
- * `Date.now()` if not.
- *
- * Options object may also include `size`, which will prevent
- * calling the `sizeCalculation` function and just use the specified
- * number if it is a positive integer, and `noDisposeOnSet` which
- * will prevent calling a `dispose` function in the case of
- * overwrites.
- *
- * If the `size` (or return value of `sizeCalculation`) for a given
- * entry is greater than `maxEntrySize`, then the item will not be
- * added to the cache.
- *
- * Will update the recency of the entry.
- *
- * If the value is `undefined`, then this is an alias for
- * `cache.delete(key)`. `undefined` is never stored in the cache.
- */
- set(k, v, setOptions = {}) {
- if (v === undefined) {
- this.delete(k);
- return this;
- }
- const { ttl = this.ttl, start, noDisposeOnSet = this.noDisposeOnSet, sizeCalculation = this.sizeCalculation, status, } = setOptions;
- let { noUpdateTTL = this.noUpdateTTL } = setOptions;
- const size = this.#requireSize(k, v, setOptions.size || 0, sizeCalculation);
- // if the item doesn't fit, don't do anything
- // NB: maxEntrySize set to maxSize by default
- if (this.maxEntrySize && size > this.maxEntrySize) {
- if (status) {
- status.set = 'miss';
- status.maxEntrySizeExceeded = true;
- }
- // have to delete, in case something is there already.
- this.#delete(k, 'set');
- return this;
- }
- let index = this.#size === 0 ? undefined : this.#keyMap.get(k);
- if (index === undefined) {
- // addition
- index = (this.#size === 0
- ? this.#tail
- : this.#free.length !== 0
- ? this.#free.pop()
- : this.#size === this.#max
- ? this.#evict(false)
- : this.#size);
- this.#keyList[index] = k;
- this.#valList[index] = v;
- this.#keyMap.set(k, index);
- this.#next[this.#tail] = index;
- this.#prev[index] = this.#tail;
- this.#tail = index;
- this.#size++;
- this.#addItemSize(index, size, status);
- if (status)
- status.set = 'add';
- noUpdateTTL = false;
- }
- else {
- // update
- this.#moveToTail(index);
- const oldVal = this.#valList[index];
- if (v !== oldVal) {
- if (this.#hasFetchMethod && this.#isBackgroundFetch(oldVal)) {
- oldVal.__abortController.abort(new Error('replaced'));
- const { __staleWhileFetching: s } = oldVal;
- if (s !== undefined && !noDisposeOnSet) {
- if (this.#hasDispose) {
- this.#dispose?.(s, k, 'set');
- }
- if (this.#hasDisposeAfter) {
- this.#disposed?.push([s, k, 'set']);
- }
- }
- }
- else if (!noDisposeOnSet) {
- if (this.#hasDispose) {
- this.#dispose?.(oldVal, k, 'set');
- }
- if (this.#hasDisposeAfter) {
- this.#disposed?.push([oldVal, k, 'set']);
- }
- }
- this.#removeItemSize(index);
- this.#addItemSize(index, size, status);
- this.#valList[index] = v;
- if (status) {
- status.set = 'replace';
- const oldValue = oldVal && this.#isBackgroundFetch(oldVal)
- ? oldVal.__staleWhileFetching
- : oldVal;
- if (oldValue !== undefined)
- status.oldValue = oldValue;
- }
- }
- else if (status) {
- status.set = 'update';
- }
- }
- if (ttl !== 0 && !this.#ttls) {
- this.#initializeTTLTracking();
- }
- if (this.#ttls) {
- if (!noUpdateTTL) {
- this.#setItemTTL(index, ttl, start);
- }
- if (status)
- this.#statusTTL(status, index);
- }
- if (!noDisposeOnSet && this.#hasDisposeAfter && this.#disposed) {
- const dt = this.#disposed;
- let task;
- while ((task = dt?.shift())) {
- this.#disposeAfter?.(...task);
- }
- }
- return this;
- }
- /**
- * Evict the least recently used item, returning its value or
- * `undefined` if cache is empty.
- */
- pop() {
- try {
- while (this.#size) {
- const val = this.#valList[this.#head];
- this.#evict(true);
- if (this.#isBackgroundFetch(val)) {
- if (val.__staleWhileFetching) {
- return val.__staleWhileFetching;
- }
- }
- else if (val !== undefined) {
- return val;
- }
- }
- }
- finally {
- if (this.#hasDisposeAfter && this.#disposed) {
- const dt = this.#disposed;
- let task;
- while ((task = dt?.shift())) {
- this.#disposeAfter?.(...task);
- }
- }
- }
- }
- #evict(free) {
- const head = this.#head;
- const k = this.#keyList[head];
- const v = this.#valList[head];
- if (this.#hasFetchMethod && this.#isBackgroundFetch(v)) {
- v.__abortController.abort(new Error('evicted'));
- }
- else if (this.#hasDispose || this.#hasDisposeAfter) {
- if (this.#hasDispose) {
- this.#dispose?.(v, k, 'evict');
- }
- if (this.#hasDisposeAfter) {
- this.#disposed?.push([v, k, 'evict']);
- }
- }
- this.#removeItemSize(head);
- // if we aren't about to use the index, then null these out
- if (free) {
- this.#keyList[head] = undefined;
- this.#valList[head] = undefined;
- this.#free.push(head);
- }
- if (this.#size === 1) {
- this.#head = this.#tail = 0;
- this.#free.length = 0;
- }
- else {
- this.#head = this.#next[head];
- }
- this.#keyMap.delete(k);
- this.#size--;
- return head;
- }
- /**
- * Check if a key is in the cache, without updating the recency of use.
- * Will return false if the item is stale, even though it is technically
- * in the cache.
- *
- * Check if a key is in the cache, without updating the recency of
- * use. Age is updated if {@link LRUCache.OptionsBase.updateAgeOnHas} is set
- * to `true` in either the options or the constructor.
- *
- * Will return `false` if the item is stale, even though it is technically in
- * the cache. The difference can be determined (if it matters) by using a
- * `status` argument, and inspecting the `has` field.
- *
- * Will not update item age unless
- * {@link LRUCache.OptionsBase.updateAgeOnHas} is set.
- */
- has(k, hasOptions = {}) {
- const { updateAgeOnHas = this.updateAgeOnHas, status } = hasOptions;
- const index = this.#keyMap.get(k);
- if (index !== undefined) {
- const v = this.#valList[index];
- if (this.#isBackgroundFetch(v) &&
- v.__staleWhileFetching === undefined) {
- return false;
- }
- if (!this.#isStale(index)) {
- if (updateAgeOnHas) {
- this.#updateItemAge(index);
- }
- if (status) {
- status.has = 'hit';
- this.#statusTTL(status, index);
- }
- return true;
- }
- else if (status) {
- status.has = 'stale';
- this.#statusTTL(status, index);
- }
- }
- else if (status) {
- status.has = 'miss';
- }
- return false;
- }
- /**
- * Like {@link LRUCache#get} but doesn't update recency or delete stale
- * items.
- *
- * Returns `undefined` if the item is stale, unless
- * {@link LRUCache.OptionsBase.allowStale} is set.
- */
- peek(k, peekOptions = {}) {
- const { allowStale = this.allowStale } = peekOptions;
- const index = this.#keyMap.get(k);
- if (index === undefined ||
- (!allowStale && this.#isStale(index))) {
- return;
- }
- const v = this.#valList[index];
- // either stale and allowed, or forcing a refresh of non-stale value
- return this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
- }
- #backgroundFetch(k, index, options, context) {
- const v = index === undefined ? undefined : this.#valList[index];
- if (this.#isBackgroundFetch(v)) {
- return v;
- }
- const ac = new AC();
- const { signal } = options;
- // when/if our AC signals, then stop listening to theirs.
- signal?.addEventListener('abort', () => ac.abort(signal.reason), {
- signal: ac.signal,
- });
- const fetchOpts = {
- signal: ac.signal,
- options,
- context,
- };
- const cb = (v, updateCache = false) => {
- const { aborted } = ac.signal;
- const ignoreAbort = options.ignoreFetchAbort && v !== undefined;
- if (options.status) {
- if (aborted && !updateCache) {
- options.status.fetchAborted = true;
- options.status.fetchError = ac.signal.reason;
- if (ignoreAbort)
- options.status.fetchAbortIgnored = true;
- }
- else {
- options.status.fetchResolved = true;
- }
- }
- if (aborted && !ignoreAbort && !updateCache) {
- return fetchFail(ac.signal.reason);
- }
- // either we didn't abort, and are still here, or we did, and ignored
- const bf = p;
- if (this.#valList[index] === p) {
- if (v === undefined) {
- if (bf.__staleWhileFetching) {
- this.#valList[index] = bf.__staleWhileFetching;
- }
- else {
- this.#delete(k, 'fetch');
- }
- }
- else {
- if (options.status)
- options.status.fetchUpdated = true;
- this.set(k, v, fetchOpts.options);
- }
- }
- return v;
- };
- const eb = (er) => {
- if (options.status) {
- options.status.fetchRejected = true;
- options.status.fetchError = er;
- }
- return fetchFail(er);
- };
- const fetchFail = (er) => {
- const { aborted } = ac.signal;
- const allowStaleAborted = aborted && options.allowStaleOnFetchAbort;
- const allowStale = allowStaleAborted || options.allowStaleOnFetchRejection;
- const noDelete = allowStale || options.noDeleteOnFetchRejection;
- const bf = p;
- if (this.#valList[index] === p) {
- // if we allow stale on fetch rejections, then we need to ensure that
- // the stale value is not removed from the cache when the fetch fails.
- const del = !noDelete || bf.__staleWhileFetching === undefined;
- if (del) {
- this.#delete(k, 'fetch');
- }
- else if (!allowStaleAborted) {
- // still replace the *promise* with the stale value,
- // since we are done with the promise at this point.
- // leave it untouched if we're still waiting for an
- // aborted background fetch that hasn't yet returned.
- this.#valList[index] = bf.__staleWhileFetching;
- }
- }
- if (allowStale) {
- if (options.status && bf.__staleWhileFetching !== undefined) {
- options.status.returnedStale = true;
- }
- return bf.__staleWhileFetching;
- }
- else if (bf.__returned === bf) {
- throw er;
- }
- };
- const pcall = (res, rej) => {
- const fmp = this.#fetchMethod?.(k, v, fetchOpts);
- if (fmp && fmp instanceof Promise) {
- fmp.then(v => res(v === undefined ? undefined : v), rej);
- }
- // ignored, we go until we finish, regardless.
- // defer check until we are actually aborting,
- // so fetchMethod can override.
- ac.signal.addEventListener('abort', () => {
- if (!options.ignoreFetchAbort ||
- options.allowStaleOnFetchAbort) {
- res(undefined);
- // when it eventually resolves, update the cache.
- if (options.allowStaleOnFetchAbort) {
- res = v => cb(v, true);
- }
- }
- });
- };
- if (options.status)
- options.status.fetchDispatched = true;
- const p = new Promise(pcall).then(cb, eb);
- const bf = Object.assign(p, {
- __abortController: ac,
- __staleWhileFetching: v,
- __returned: undefined,
- });
- if (index === undefined) {
- // internal, don't expose status.
- this.set(k, bf, { ...fetchOpts.options, status: undefined });
- index = this.#keyMap.get(k);
- }
- else {
- this.#valList[index] = bf;
- }
- return bf;
- }
- #isBackgroundFetch(p) {
- if (!this.#hasFetchMethod)
- return false;
- const b = p;
- return (!!b &&
- b instanceof Promise &&
- b.hasOwnProperty('__staleWhileFetching') &&
- b.__abortController instanceof AC);
- }
- async fetch(k, fetchOptions = {}) {
- const {
- // get options
- allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet,
- // set options
- ttl = this.ttl, noDisposeOnSet = this.noDisposeOnSet, size = 0, sizeCalculation = this.sizeCalculation, noUpdateTTL = this.noUpdateTTL,
- // fetch exclusive options
- noDeleteOnFetchRejection = this.noDeleteOnFetchRejection, allowStaleOnFetchRejection = this.allowStaleOnFetchRejection, ignoreFetchAbort = this.ignoreFetchAbort, allowStaleOnFetchAbort = this.allowStaleOnFetchAbort, context, forceRefresh = false, status, signal, } = fetchOptions;
- if (!this.#hasFetchMethod) {
- if (status)
- status.fetch = 'get';
- return this.get(k, {
- allowStale,
- updateAgeOnGet,
- noDeleteOnStaleGet,
- status,
- });
- }
- const options = {
- allowStale,
- updateAgeOnGet,
- noDeleteOnStaleGet,
- ttl,
- noDisposeOnSet,
- size,
- sizeCalculation,
- noUpdateTTL,
- noDeleteOnFetchRejection,
- allowStaleOnFetchRejection,
- allowStaleOnFetchAbort,
- ignoreFetchAbort,
- status,
- signal,
- };
- let index = this.#keyMap.get(k);
- if (index === undefined) {
- if (status)
- status.fetch = 'miss';
- const p = this.#backgroundFetch(k, index, options, context);
- return (p.__returned = p);
- }
- else {
- // in cache, maybe already fetching
- const v = this.#valList[index];
- if (this.#isBackgroundFetch(v)) {
- const stale = allowStale && v.__staleWhileFetching !== undefined;
- if (status) {
- status.fetch = 'inflight';
- if (stale)
- status.returnedStale = true;
- }
- return stale ? v.__staleWhileFetching : (v.__returned = v);
- }
- // if we force a refresh, that means do NOT serve the cached value,
- // unless we are already in the process of refreshing the cache.
- const isStale = this.#isStale(index);
- if (!forceRefresh && !isStale) {
- if (status)
- status.fetch = 'hit';
- this.#moveToTail(index);
- if (updateAgeOnGet) {
- this.#updateItemAge(index);
- }
- if (status)
- this.#statusTTL(status, index);
- return v;
- }
- // ok, it is stale or a forced refresh, and not already fetching.
- // refresh the cache.
- const p = this.#backgroundFetch(k, index, options, context);
- const hasStale = p.__staleWhileFetching !== undefined;
- const staleVal = hasStale && allowStale;
- if (status) {
- status.fetch = isStale ? 'stale' : 'refresh';
- if (staleVal && isStale)
- status.returnedStale = true;
- }
- return staleVal ? p.__staleWhileFetching : (p.__returned = p);
- }
- }
- async forceFetch(k, fetchOptions = {}) {
- const v = await this.fetch(k, fetchOptions);
- if (v === undefined)
- throw new Error('fetch() returned undefined');
- return v;
- }
- memo(k, memoOptions = {}) {
- const memoMethod = this.#memoMethod;
- if (!memoMethod) {
- throw new Error('no memoMethod provided to constructor');
- }
- const { context, forceRefresh, ...options } = memoOptions;
- const v = this.get(k, options);
- if (!forceRefresh && v !== undefined)
- return v;
- const vv = memoMethod(k, v, {
- options,
- context,
- });
- this.set(k, vv, options);
- return vv;
- }
- /**
- * Return a value from the cache. Will update the recency of the cache
- * entry found.
- *
- * If the key is not found, get() will return `undefined`.
- */
- get(k, getOptions = {}) {
- const { allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet, status, } = getOptions;
- const index = this.#keyMap.get(k);
- if (index !== undefined) {
- const value = this.#valList[index];
- const fetching = this.#isBackgroundFetch(value);
- if (status)
- this.#statusTTL(status, index);
- if (this.#isStale(index)) {
- if (status)
- status.get = 'stale';
- // delete only if not an in-flight background fetch
- if (!fetching) {
- if (!noDeleteOnStaleGet) {
- this.#delete(k, 'expire');
- }
- if (status && allowStale)
- status.returnedStale = true;
- return allowStale ? value : undefined;
- }
- else {
- if (status &&
- allowStale &&
- value.__staleWhileFetching !== undefined) {
- status.returnedStale = true;
- }
- return allowStale ? value.__staleWhileFetching : undefined;
- }
- }
- else {
- if (status)
- status.get = 'hit';
- // if we're currently fetching it, we don't actually have it yet
- // it's not stale, which means this isn't a staleWhileRefetching.
- // If it's not stale, and fetching, AND has a __staleWhileFetching
- // value, then that means the user fetched with {forceRefresh:true},
- // so it's safe to return that value.
- if (fetching) {
- return value.__staleWhileFetching;
- }
- this.#moveToTail(index);
- if (updateAgeOnGet) {
- this.#updateItemAge(index);
- }
- return value;
- }
- }
- else if (status) {
- status.get = 'miss';
- }
- }
- #connect(p, n) {
- this.#prev[n] = p;
- this.#next[p] = n;
- }
- #moveToTail(index) {
- // if tail already, nothing to do
- // if head, move head to next[index]
- // else
- // move next[prev[index]] to next[index] (head has no prev)
- // move prev[next[index]] to prev[index]
- // prev[index] = tail
- // next[tail] = index
- // tail = index
- if (index !== this.#tail) {
- if (index === this.#head) {
- this.#head = this.#next[index];
- }
- else {
- this.#connect(this.#prev[index], this.#next[index]);
- }
- this.#connect(this.#tail, index);
- this.#tail = index;
- }
- }
- /**
- * Deletes a key out of the cache.
- *
- * Returns true if the key was deleted, false otherwise.
- */
- delete(k) {
- return this.#delete(k, 'delete');
- }
- #delete(k, reason) {
- let deleted = false;
- if (this.#size !== 0) {
- const index = this.#keyMap.get(k);
- if (index !== undefined) {
- deleted = true;
- if (this.#size === 1) {
- this.#clear(reason);
- }
- else {
- this.#removeItemSize(index);
- const v = this.#valList[index];
- if (this.#isBackgroundFetch(v)) {
- v.__abortController.abort(new Error('deleted'));
- }
- else if (this.#hasDispose || this.#hasDisposeAfter) {
- if (this.#hasDispose) {
- this.#dispose?.(v, k, reason);
- }
- if (this.#hasDisposeAfter) {
- this.#disposed?.push([v, k, reason]);
- }
- }
- this.#keyMap.delete(k);
- this.#keyList[index] = undefined;
- this.#valList[index] = undefined;
- if (index === this.#tail) {
- this.#tail = this.#prev[index];
- }
- else if (index === this.#head) {
- this.#head = this.#next[index];
- }
- else {
- const pi = this.#prev[index];
- this.#next[pi] = this.#next[index];
- const ni = this.#next[index];
- this.#prev[ni] = this.#prev[index];
- }
- this.#size--;
- this.#free.push(index);
- }
- }
- }
- if (this.#hasDisposeAfter && this.#disposed?.length) {
- const dt = this.#disposed;
- let task;
- while ((task = dt?.shift())) {
- this.#disposeAfter?.(...task);
- }
- }
- return deleted;
- }
- /**
- * Clear the cache entirely, throwing away all values.
- */
- clear() {
- return this.#clear('delete');
- }
- #clear(reason) {
- for (const index of this.#rindexes({ allowStale: true })) {
- const v = this.#valList[index];
- if (this.#isBackgroundFetch(v)) {
- v.__abortController.abort(new Error('deleted'));
- }
- else {
- const k = this.#keyList[index];
- if (this.#hasDispose) {
- this.#dispose?.(v, k, reason);
- }
- if (this.#hasDisposeAfter) {
- this.#disposed?.push([v, k, reason]);
- }
- }
- }
- this.#keyMap.clear();
- this.#valList.fill(undefined);
- this.#keyList.fill(undefined);
- if (this.#ttls && this.#starts) {
- this.#ttls.fill(0);
- this.#starts.fill(0);
- }
- if (this.#sizes) {
- this.#sizes.fill(0);
- }
- this.#head = 0;
- this.#tail = 0;
- this.#free.length = 0;
- this.#calculatedSize = 0;
- this.#size = 0;
- if (this.#hasDisposeAfter && this.#disposed) {
- const dt = this.#disposed;
- let task;
- while ((task = dt?.shift())) {
- this.#disposeAfter?.(...task);
- }
- }
- }
-}
-exports.LRUCache = LRUCache;
-//# sourceMappingURL=index.js.map
-
-/***/ }),
-
-/***/ 9002:
-/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
-
-// This file exists as a CommonJS module to read the version from package.json.
-// In an ESM package, using `require()` directly in .ts files requires disabling
-// ESLint rules and doesn't work reliably across all Node.js versions.
-// By keeping this as a .cjs file, we can use require() naturally and export
-// the version for the ESM modules to import.
-const packageJson = __nccwpck_require__(2822)
-module.exports = { version: packageJson.version }
-
-
-/***/ }),
-
-/***/ 4928:
-/***/ ((module) => {
-
-
-
-function getDefaultExportFromCjs (x) {
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
-}
-
-const CRC_TABLE = new Int32Array([
- 0,
- 1996959894,
- 3993919788,
- 2567524794,
- 124634137,
- 1886057615,
- 3915621685,
- 2657392035,
- 249268274,
- 2044508324,
- 3772115230,
- 2547177864,
- 162941995,
- 2125561021,
- 3887607047,
- 2428444049,
- 498536548,
- 1789927666,
- 4089016648,
- 2227061214,
- 450548861,
- 1843258603,
- 4107580753,
- 2211677639,
- 325883990,
- 1684777152,
- 4251122042,
- 2321926636,
- 335633487,
- 1661365465,
- 4195302755,
- 2366115317,
- 997073096,
- 1281953886,
- 3579855332,
- 2724688242,
- 1006888145,
- 1258607687,
- 3524101629,
- 2768942443,
- 901097722,
- 1119000684,
- 3686517206,
- 2898065728,
- 853044451,
- 1172266101,
- 3705015759,
- 2882616665,
- 651767980,
- 1373503546,
- 3369554304,
- 3218104598,
- 565507253,
- 1454621731,
- 3485111705,
- 3099436303,
- 671266974,
- 1594198024,
- 3322730930,
- 2970347812,
- 795835527,
- 1483230225,
- 3244367275,
- 3060149565,
- 1994146192,
- 31158534,
- 2563907772,
- 4023717930,
- 1907459465,
- 112637215,
- 2680153253,
- 3904427059,
- 2013776290,
- 251722036,
- 2517215374,
- 3775830040,
- 2137656763,
- 141376813,
- 2439277719,
- 3865271297,
- 1802195444,
- 476864866,
- 2238001368,
- 4066508878,
- 1812370925,
- 453092731,
- 2181625025,
- 4111451223,
- 1706088902,
- 314042704,
- 2344532202,
- 4240017532,
- 1658658271,
- 366619977,
- 2362670323,
- 4224994405,
- 1303535960,
- 984961486,
- 2747007092,
- 3569037538,
- 1256170817,
- 1037604311,
- 2765210733,
- 3554079995,
- 1131014506,
- 879679996,
- 2909243462,
- 3663771856,
- 1141124467,
- 855842277,
- 2852801631,
- 3708648649,
- 1342533948,
- 654459306,
- 3188396048,
- 3373015174,
- 1466479909,
- 544179635,
- 3110523913,
- 3462522015,
- 1591671054,
- 702138776,
- 2966460450,
- 3352799412,
- 1504918807,
- 783551873,
- 3082640443,
- 3233442989,
- 3988292384,
- 2596254646,
- 62317068,
- 1957810842,
- 3939845945,
- 2647816111,
- 81470997,
- 1943803523,
- 3814918930,
- 2489596804,
- 225274430,
- 2053790376,
- 3826175755,
- 2466906013,
- 167816743,
- 2097651377,
- 4027552580,
- 2265490386,
- 503444072,
- 1762050814,
- 4150417245,
- 2154129355,
- 426522225,
- 1852507879,
- 4275313526,
- 2312317920,
- 282753626,
- 1742555852,
- 4189708143,
- 2394877945,
- 397917763,
- 1622183637,
- 3604390888,
- 2714866558,
- 953729732,
- 1340076626,
- 3518719985,
- 2797360999,
- 1068828381,
- 1219638859,
- 3624741850,
- 2936675148,
- 906185462,
- 1090812512,
- 3747672003,
- 2825379669,
- 829329135,
- 1181335161,
- 3412177804,
- 3160834842,
- 628085408,
- 1382605366,
- 3423369109,
- 3138078467,
- 570562233,
- 1426400815,
- 3317316542,
- 2998733608,
- 733239954,
- 1555261956,
- 3268935591,
- 3050360625,
- 752459403,
- 1541320221,
- 2607071920,
- 3965973030,
- 1969922972,
- 40735498,
- 2617837225,
- 3943577151,
- 1913087877,
- 83908371,
- 2512341634,
- 3803740692,
- 2075208622,
- 213261112,
- 2463272603,
- 3855990285,
- 2094854071,
- 198958881,
- 2262029012,
- 4057260610,
- 1759359992,
- 534414190,
- 2176718541,
- 4139329115,
- 1873836001,
- 414664567,
- 2282248934,
- 4279200368,
- 1711684554,
- 285281116,
- 2405801727,
- 4167216745,
- 1634467795,
- 376229701,
- 2685067896,
- 3608007406,
- 1308918612,
- 956543938,
- 2808555105,
- 3495958263,
- 1231636301,
- 1047427035,
- 2932959818,
- 3654703836,
- 1088359270,
- 936918e3,
- 2847714899,
- 3736837829,
- 1202900863,
- 817233897,
- 3183342108,
- 3401237130,
- 1404277552,
- 615818150,
- 3134207493,
- 3453421203,
- 1423857449,
- 601450431,
- 3009837614,
- 3294710456,
- 1567103746,
- 711928724,
- 3020668471,
- 3272380065,
- 1510334235,
- 755167117
-]);
-function ensureBuffer(input) {
- if (Buffer.isBuffer(input)) {
- return input;
- }
- if (typeof input === "number") {
- return Buffer.alloc(input);
- } else if (typeof input === "string") {
- return Buffer.from(input);
- } else {
- throw new Error("input must be buffer, number, or string, received " + typeof input);
- }
-}
-function bufferizeInt(num) {
- const tmp = ensureBuffer(4);
- tmp.writeInt32BE(num, 0);
- return tmp;
-}
-function _crc32(buf, previous) {
- buf = ensureBuffer(buf);
- if (Buffer.isBuffer(previous)) {
- previous = previous.readUInt32BE(0);
- }
- let crc = ~~previous ^ -1;
- for (var n = 0; n < buf.length; n++) {
- crc = CRC_TABLE[(crc ^ buf[n]) & 255] ^ crc >>> 8;
- }
- return crc ^ -1;
-}
-function crc32() {
- return bufferizeInt(_crc32.apply(null, arguments));
-}
-crc32.signed = function() {
- return _crc32.apply(null, arguments);
-};
-crc32.unsigned = function() {
- return _crc32.apply(null, arguments) >>> 0;
-};
-var bufferCrc32 = crc32;
-
-const index = /*@__PURE__*/getDefaultExportFromCjs(bufferCrc32);
-
-module.exports = index;
-
-
-/***/ }),
-
-/***/ 2822:
-/***/ ((module) => {
-
-module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/artifact","version":"6.2.0","preview":true,"description":"Actions artifact lib","keywords":["github","actions","artifact"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/artifact","license":"MIT","type":"module","main":"lib/artifact.js","types":"lib/artifact.d.ts","exports":{".":{"types":"./lib/artifact.d.ts","import":"./lib/artifact.js"}},"directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/artifact"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"cd ../../ && npm run test ./packages/artifact","bootstrap":"cd ../../ && npm run bootstrap","tsc-run":"tsc && cp src/internal/shared/package-version.cjs lib/internal/shared/","tsc":"npm run bootstrap && npm run tsc-run","gen:docs":"typedoc --plugin typedoc-plugin-markdown --out docs/generated src/artifact.ts --githubPages false --readme none"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^3.0.0","@actions/github":"^9.0.0","@actions/http-client":"^4.0.0","@azure/storage-blob":"^12.30.0","@octokit/core":"^7.0.6","@octokit/plugin-request-log":"^6.0.0","@octokit/plugin-retry":"^8.0.0","@octokit/request":"^10.0.7","@octokit/request-error":"^7.1.0","@protobuf-ts/plugin":"^2.2.3-alpha.1","@protobuf-ts/runtime":"^2.9.4","archiver":"^7.0.1","jwt-decode":"^4.0.0","unzip-stream":"^0.3.1"},"devDependencies":{"@types/archiver":"^7.0.0","@types/unzip-stream":"^0.3.4","typedoc":"^0.28.16","typedoc-plugin-markdown":"^4.9.0","typescript":"^5.9.3"},"overrides":{"uri-js":"npm:uri-js-replace@^1.0.1","node-fetch":"^3.3.2"}}');
-
-/***/ })
-
-/******/ });
-/************************************************************************/
-/******/ // The module cache
-/******/ var __webpack_module_cache__ = {};
-/******/
-/******/ // The require function
-/******/ function __nccwpck_require__(moduleId) {
-/******/ // Check if module is in cache
-/******/ var cachedModule = __webpack_module_cache__[moduleId];
-/******/ if (cachedModule !== undefined) {
-/******/ return cachedModule.exports;
-/******/ }
-/******/ // Create a new module (and put it into the cache)
-/******/ var module = __webpack_module_cache__[moduleId] = {
-/******/ id: moduleId,
-/******/ loaded: false,
-/******/ exports: {}
-/******/ };
-/******/
-/******/ // Execute the module function
-/******/ var threw = true;
-/******/ try {
-/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __nccwpck_require__);
-/******/ threw = false;
-/******/ } finally {
-/******/ if(threw) delete __webpack_module_cache__[moduleId];
-/******/ }
-/******/
-/******/ // Flag the module as loaded
-/******/ module.loaded = true;
-/******/
-/******/ // Return the exports of the module
-/******/ return module.exports;
-/******/ }
-/******/
-/************************************************************************/
-/******/ /* webpack/runtime/create fake namespace object */
-/******/ (() => {
-/******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__);
-/******/ var leafPrototypes;
-/******/ // create a fake namespace object
-/******/ // mode & 1: value is a module id, require it
-/******/ // mode & 2: merge all properties of value into the ns
-/******/ // mode & 4: return value when already ns object
-/******/ // mode & 16: return value when it's Promise-like
-/******/ // mode & 8|1: behave like require
-/******/ __nccwpck_require__.t = function(value, mode) {
-/******/ if(mode & 1) value = this(value);
-/******/ if(mode & 8) return value;
-/******/ if(typeof value === 'object' && value) {
-/******/ if((mode & 4) && value.__esModule) return value;
-/******/ if((mode & 16) && typeof value.then === 'function') return value;
-/******/ }
-/******/ var ns = Object.create(null);
-/******/ __nccwpck_require__.r(ns);
-/******/ var def = {};
-/******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];
-/******/ for(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) {
-/******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key])));
-/******/ }
-/******/ def['default'] = () => (value);
-/******/ __nccwpck_require__.d(ns, def);
-/******/ return ns;
-/******/ };
-/******/ })();
-/******/
-/******/ /* webpack/runtime/define property getters */
-/******/ (() => {
-/******/ // define getter functions for harmony exports
-/******/ __nccwpck_require__.d = (exports, definition) => {
-/******/ for(var key in definition) {
-/******/ if(__nccwpck_require__.o(definition, key) && !__nccwpck_require__.o(exports, key)) {
-/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
-/******/ }
-/******/ }
-/******/ };
-/******/ })();
-/******/
-/******/ /* webpack/runtime/hasOwnProperty shorthand */
-/******/ (() => {
-/******/ __nccwpck_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
-/******/ })();
-/******/
-/******/ /* webpack/runtime/make namespace object */
-/******/ (() => {
-/******/ // define __esModule on exports
-/******/ __nccwpck_require__.r = (exports) => {
-/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
-/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
-/******/ }
-/******/ Object.defineProperty(exports, '__esModule', { value: true });
-/******/ };
-/******/ })();
-/******/
-/******/ /* webpack/runtime/node module decorator */
-/******/ (() => {
-/******/ __nccwpck_require__.nmd = (module) => {
-/******/ module.paths = [];
-/******/ if (!module.children) module.children = [];
-/******/ return module;
-/******/ };
-/******/ })();
-/******/
-/******/ /* webpack/runtime/compat */
-/******/
-/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = new URL('.', import.meta.url).pathname.slice(import.meta.url.match(/^file:\/\/\/\w:/) ? 1 : 0, -1) + "/";
-/******/
-/************************************************************************/
-var __webpack_exports__ = {};
-
-// NAMESPACE OBJECT: ./node_modules/@azure/storage-blob/dist/esm/generated/src/models/mappers.js
-var mappers_namespaceObject = {};
-__nccwpck_require__.r(mappers_namespaceObject);
-__nccwpck_require__.d(mappers_namespaceObject, {
- AccessPolicy: () => (AccessPolicy),
- AppendBlobAppendBlockExceptionHeaders: () => (AppendBlobAppendBlockExceptionHeaders),
- AppendBlobAppendBlockFromUrlExceptionHeaders: () => (AppendBlobAppendBlockFromUrlExceptionHeaders),
- AppendBlobAppendBlockFromUrlHeaders: () => (AppendBlobAppendBlockFromUrlHeaders),
- AppendBlobAppendBlockHeaders: () => (AppendBlobAppendBlockHeaders),
- AppendBlobCreateExceptionHeaders: () => (AppendBlobCreateExceptionHeaders),
- AppendBlobCreateHeaders: () => (AppendBlobCreateHeaders),
- AppendBlobSealExceptionHeaders: () => (AppendBlobSealExceptionHeaders),
- AppendBlobSealHeaders: () => (AppendBlobSealHeaders),
- ArrowConfiguration: () => (ArrowConfiguration),
- ArrowField: () => (ArrowField),
- BlobAbortCopyFromURLExceptionHeaders: () => (BlobAbortCopyFromURLExceptionHeaders),
- BlobAbortCopyFromURLHeaders: () => (BlobAbortCopyFromURLHeaders),
- BlobAcquireLeaseExceptionHeaders: () => (BlobAcquireLeaseExceptionHeaders),
- BlobAcquireLeaseHeaders: () => (BlobAcquireLeaseHeaders),
- BlobBreakLeaseExceptionHeaders: () => (BlobBreakLeaseExceptionHeaders),
- BlobBreakLeaseHeaders: () => (BlobBreakLeaseHeaders),
- BlobChangeLeaseExceptionHeaders: () => (BlobChangeLeaseExceptionHeaders),
- BlobChangeLeaseHeaders: () => (BlobChangeLeaseHeaders),
- BlobCopyFromURLExceptionHeaders: () => (BlobCopyFromURLExceptionHeaders),
- BlobCopyFromURLHeaders: () => (BlobCopyFromURLHeaders),
- BlobCreateSnapshotExceptionHeaders: () => (BlobCreateSnapshotExceptionHeaders),
- BlobCreateSnapshotHeaders: () => (BlobCreateSnapshotHeaders),
- BlobDeleteExceptionHeaders: () => (BlobDeleteExceptionHeaders),
- BlobDeleteHeaders: () => (BlobDeleteHeaders),
- BlobDeleteImmutabilityPolicyExceptionHeaders: () => (BlobDeleteImmutabilityPolicyExceptionHeaders),
- BlobDeleteImmutabilityPolicyHeaders: () => (BlobDeleteImmutabilityPolicyHeaders),
- BlobDownloadExceptionHeaders: () => (BlobDownloadExceptionHeaders),
- BlobDownloadHeaders: () => (BlobDownloadHeaders),
- BlobFlatListSegment: () => (BlobFlatListSegment),
- BlobGetAccountInfoExceptionHeaders: () => (BlobGetAccountInfoExceptionHeaders),
- BlobGetAccountInfoHeaders: () => (BlobGetAccountInfoHeaders),
- BlobGetPropertiesExceptionHeaders: () => (BlobGetPropertiesExceptionHeaders),
- BlobGetPropertiesHeaders: () => (BlobGetPropertiesHeaders),
- BlobGetTagsExceptionHeaders: () => (BlobGetTagsExceptionHeaders),
- BlobGetTagsHeaders: () => (BlobGetTagsHeaders),
- BlobHierarchyListSegment: () => (BlobHierarchyListSegment),
- BlobItemInternal: () => (BlobItemInternal),
- BlobName: () => (BlobName),
- BlobPrefix: () => (BlobPrefix),
- BlobPropertiesInternal: () => (BlobPropertiesInternal),
- BlobQueryExceptionHeaders: () => (BlobQueryExceptionHeaders),
- BlobQueryHeaders: () => (BlobQueryHeaders),
- BlobReleaseLeaseExceptionHeaders: () => (BlobReleaseLeaseExceptionHeaders),
- BlobReleaseLeaseHeaders: () => (BlobReleaseLeaseHeaders),
- BlobRenewLeaseExceptionHeaders: () => (BlobRenewLeaseExceptionHeaders),
- BlobRenewLeaseHeaders: () => (BlobRenewLeaseHeaders),
- BlobServiceProperties: () => (BlobServiceProperties),
- BlobServiceStatistics: () => (BlobServiceStatistics),
- BlobSetExpiryExceptionHeaders: () => (BlobSetExpiryExceptionHeaders),
- BlobSetExpiryHeaders: () => (BlobSetExpiryHeaders),
- BlobSetHttpHeadersExceptionHeaders: () => (BlobSetHttpHeadersExceptionHeaders),
- BlobSetHttpHeadersHeaders: () => (BlobSetHttpHeadersHeaders),
- BlobSetImmutabilityPolicyExceptionHeaders: () => (BlobSetImmutabilityPolicyExceptionHeaders),
- BlobSetImmutabilityPolicyHeaders: () => (BlobSetImmutabilityPolicyHeaders),
- BlobSetLegalHoldExceptionHeaders: () => (BlobSetLegalHoldExceptionHeaders),
- BlobSetLegalHoldHeaders: () => (BlobSetLegalHoldHeaders),
- BlobSetMetadataExceptionHeaders: () => (BlobSetMetadataExceptionHeaders),
- BlobSetMetadataHeaders: () => (BlobSetMetadataHeaders),
- BlobSetTagsExceptionHeaders: () => (BlobSetTagsExceptionHeaders),
- BlobSetTagsHeaders: () => (BlobSetTagsHeaders),
- BlobSetTierExceptionHeaders: () => (BlobSetTierExceptionHeaders),
- BlobSetTierHeaders: () => (BlobSetTierHeaders),
- BlobStartCopyFromURLExceptionHeaders: () => (BlobStartCopyFromURLExceptionHeaders),
- BlobStartCopyFromURLHeaders: () => (BlobStartCopyFromURLHeaders),
- BlobTag: () => (BlobTag),
- BlobTags: () => (BlobTags),
- BlobUndeleteExceptionHeaders: () => (BlobUndeleteExceptionHeaders),
- BlobUndeleteHeaders: () => (BlobUndeleteHeaders),
- Block: () => (Block),
- BlockBlobCommitBlockListExceptionHeaders: () => (BlockBlobCommitBlockListExceptionHeaders),
- BlockBlobCommitBlockListHeaders: () => (BlockBlobCommitBlockListHeaders),
- BlockBlobGetBlockListExceptionHeaders: () => (BlockBlobGetBlockListExceptionHeaders),
- BlockBlobGetBlockListHeaders: () => (BlockBlobGetBlockListHeaders),
- BlockBlobPutBlobFromUrlExceptionHeaders: () => (BlockBlobPutBlobFromUrlExceptionHeaders),
- BlockBlobPutBlobFromUrlHeaders: () => (BlockBlobPutBlobFromUrlHeaders),
- BlockBlobStageBlockExceptionHeaders: () => (BlockBlobStageBlockExceptionHeaders),
- BlockBlobStageBlockFromURLExceptionHeaders: () => (BlockBlobStageBlockFromURLExceptionHeaders),
- BlockBlobStageBlockFromURLHeaders: () => (BlockBlobStageBlockFromURLHeaders),
- BlockBlobStageBlockHeaders: () => (BlockBlobStageBlockHeaders),
- BlockBlobUploadExceptionHeaders: () => (BlockBlobUploadExceptionHeaders),
- BlockBlobUploadHeaders: () => (BlockBlobUploadHeaders),
- BlockList: () => (BlockList),
- BlockLookupList: () => (BlockLookupList),
- ClearRange: () => (ClearRange),
- ContainerAcquireLeaseExceptionHeaders: () => (ContainerAcquireLeaseExceptionHeaders),
- ContainerAcquireLeaseHeaders: () => (ContainerAcquireLeaseHeaders),
- ContainerBreakLeaseExceptionHeaders: () => (ContainerBreakLeaseExceptionHeaders),
- ContainerBreakLeaseHeaders: () => (ContainerBreakLeaseHeaders),
- ContainerChangeLeaseExceptionHeaders: () => (ContainerChangeLeaseExceptionHeaders),
- ContainerChangeLeaseHeaders: () => (ContainerChangeLeaseHeaders),
- ContainerCreateExceptionHeaders: () => (ContainerCreateExceptionHeaders),
- ContainerCreateHeaders: () => (ContainerCreateHeaders),
- ContainerDeleteExceptionHeaders: () => (ContainerDeleteExceptionHeaders),
- ContainerDeleteHeaders: () => (ContainerDeleteHeaders),
- ContainerFilterBlobsExceptionHeaders: () => (ContainerFilterBlobsExceptionHeaders),
- ContainerFilterBlobsHeaders: () => (ContainerFilterBlobsHeaders),
- ContainerGetAccessPolicyExceptionHeaders: () => (ContainerGetAccessPolicyExceptionHeaders),
- ContainerGetAccessPolicyHeaders: () => (ContainerGetAccessPolicyHeaders),
- ContainerGetAccountInfoExceptionHeaders: () => (ContainerGetAccountInfoExceptionHeaders),
- ContainerGetAccountInfoHeaders: () => (ContainerGetAccountInfoHeaders),
- ContainerGetPropertiesExceptionHeaders: () => (ContainerGetPropertiesExceptionHeaders),
- ContainerGetPropertiesHeaders: () => (ContainerGetPropertiesHeaders),
- ContainerItem: () => (ContainerItem),
- ContainerListBlobFlatSegmentExceptionHeaders: () => (ContainerListBlobFlatSegmentExceptionHeaders),
- ContainerListBlobFlatSegmentHeaders: () => (ContainerListBlobFlatSegmentHeaders),
- ContainerListBlobHierarchySegmentExceptionHeaders: () => (ContainerListBlobHierarchySegmentExceptionHeaders),
- ContainerListBlobHierarchySegmentHeaders: () => (ContainerListBlobHierarchySegmentHeaders),
- ContainerProperties: () => (ContainerProperties),
- ContainerReleaseLeaseExceptionHeaders: () => (ContainerReleaseLeaseExceptionHeaders),
- ContainerReleaseLeaseHeaders: () => (ContainerReleaseLeaseHeaders),
- ContainerRenameExceptionHeaders: () => (ContainerRenameExceptionHeaders),
- ContainerRenameHeaders: () => (ContainerRenameHeaders),
- ContainerRenewLeaseExceptionHeaders: () => (ContainerRenewLeaseExceptionHeaders),
- ContainerRenewLeaseHeaders: () => (ContainerRenewLeaseHeaders),
- ContainerRestoreExceptionHeaders: () => (ContainerRestoreExceptionHeaders),
- ContainerRestoreHeaders: () => (ContainerRestoreHeaders),
- ContainerSetAccessPolicyExceptionHeaders: () => (ContainerSetAccessPolicyExceptionHeaders),
- ContainerSetAccessPolicyHeaders: () => (ContainerSetAccessPolicyHeaders),
- ContainerSetMetadataExceptionHeaders: () => (ContainerSetMetadataExceptionHeaders),
- ContainerSetMetadataHeaders: () => (ContainerSetMetadataHeaders),
- ContainerSubmitBatchExceptionHeaders: () => (ContainerSubmitBatchExceptionHeaders),
- ContainerSubmitBatchHeaders: () => (ContainerSubmitBatchHeaders),
- CorsRule: () => (CorsRule),
- DelimitedTextConfiguration: () => (DelimitedTextConfiguration),
- FilterBlobItem: () => (FilterBlobItem),
- FilterBlobSegment: () => (FilterBlobSegment),
- GeoReplication: () => (GeoReplication),
- JsonTextConfiguration: () => (JsonTextConfiguration),
- KeyInfo: () => (KeyInfo),
- ListBlobsFlatSegmentResponse: () => (ListBlobsFlatSegmentResponse),
- ListBlobsHierarchySegmentResponse: () => (ListBlobsHierarchySegmentResponse),
- ListContainersSegmentResponse: () => (ListContainersSegmentResponse),
- Logging: () => (Logging),
- Metrics: () => (Metrics),
- PageBlobClearPagesExceptionHeaders: () => (PageBlobClearPagesExceptionHeaders),
- PageBlobClearPagesHeaders: () => (PageBlobClearPagesHeaders),
- PageBlobCopyIncrementalExceptionHeaders: () => (PageBlobCopyIncrementalExceptionHeaders),
- PageBlobCopyIncrementalHeaders: () => (PageBlobCopyIncrementalHeaders),
- PageBlobCreateExceptionHeaders: () => (PageBlobCreateExceptionHeaders),
- PageBlobCreateHeaders: () => (PageBlobCreateHeaders),
- PageBlobGetPageRangesDiffExceptionHeaders: () => (PageBlobGetPageRangesDiffExceptionHeaders),
- PageBlobGetPageRangesDiffHeaders: () => (PageBlobGetPageRangesDiffHeaders),
- PageBlobGetPageRangesExceptionHeaders: () => (PageBlobGetPageRangesExceptionHeaders),
- PageBlobGetPageRangesHeaders: () => (PageBlobGetPageRangesHeaders),
- PageBlobResizeExceptionHeaders: () => (PageBlobResizeExceptionHeaders),
- PageBlobResizeHeaders: () => (PageBlobResizeHeaders),
- PageBlobUpdateSequenceNumberExceptionHeaders: () => (PageBlobUpdateSequenceNumberExceptionHeaders),
- PageBlobUpdateSequenceNumberHeaders: () => (PageBlobUpdateSequenceNumberHeaders),
- PageBlobUploadPagesExceptionHeaders: () => (PageBlobUploadPagesExceptionHeaders),
- PageBlobUploadPagesFromURLExceptionHeaders: () => (PageBlobUploadPagesFromURLExceptionHeaders),
- PageBlobUploadPagesFromURLHeaders: () => (PageBlobUploadPagesFromURLHeaders),
- PageBlobUploadPagesHeaders: () => (PageBlobUploadPagesHeaders),
- PageList: () => (PageList),
- PageRange: () => (PageRange),
- QueryFormat: () => (QueryFormat),
- QueryRequest: () => (QueryRequest),
- QuerySerialization: () => (QuerySerialization),
- RetentionPolicy: () => (RetentionPolicy),
- ServiceFilterBlobsExceptionHeaders: () => (ServiceFilterBlobsExceptionHeaders),
- ServiceFilterBlobsHeaders: () => (ServiceFilterBlobsHeaders),
- ServiceGetAccountInfoExceptionHeaders: () => (ServiceGetAccountInfoExceptionHeaders),
- ServiceGetAccountInfoHeaders: () => (ServiceGetAccountInfoHeaders),
- ServiceGetPropertiesExceptionHeaders: () => (ServiceGetPropertiesExceptionHeaders),
- ServiceGetPropertiesHeaders: () => (ServiceGetPropertiesHeaders),
- ServiceGetStatisticsExceptionHeaders: () => (ServiceGetStatisticsExceptionHeaders),
- ServiceGetStatisticsHeaders: () => (ServiceGetStatisticsHeaders),
- ServiceGetUserDelegationKeyExceptionHeaders: () => (ServiceGetUserDelegationKeyExceptionHeaders),
- ServiceGetUserDelegationKeyHeaders: () => (ServiceGetUserDelegationKeyHeaders),
- ServiceListContainersSegmentExceptionHeaders: () => (ServiceListContainersSegmentExceptionHeaders),
- ServiceListContainersSegmentHeaders: () => (ServiceListContainersSegmentHeaders),
- ServiceSetPropertiesExceptionHeaders: () => (ServiceSetPropertiesExceptionHeaders),
- ServiceSetPropertiesHeaders: () => (ServiceSetPropertiesHeaders),
- ServiceSubmitBatchExceptionHeaders: () => (ServiceSubmitBatchExceptionHeaders),
- ServiceSubmitBatchHeaders: () => (ServiceSubmitBatchHeaders),
- SignedIdentifier: () => (SignedIdentifier),
- StaticWebsite: () => (StaticWebsite),
- StorageError: () => (StorageError),
- UserDelegationKey: () => (UserDelegationKey)
-});
-
-// EXTERNAL MODULE: external "os"
-var external_os_ = __nccwpck_require__(857);
-;// CONCATENATED MODULE: ./node_modules/@actions/core/lib/utils.js
-// We use any as a valid input type
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/**
- * Sanitizes an input into a string so it can be passed into issueCommand safely
- * @param input input to sanitize into a string
- */
-function utils_toCommandValue(input) {
- if (input === null || input === undefined) {
- return '';
- }
- else if (typeof input === 'string' || input instanceof String) {
- return input;
- }
- return JSON.stringify(input);
-}
-/**
- *
- * @param annotationProperties
- * @returns The command properties to send with the actual annotation command
- * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646
- */
-function utils_toCommandProperties(annotationProperties) {
- if (!Object.keys(annotationProperties).length) {
- return {};
- }
- return {
- title: annotationProperties.title,
- file: annotationProperties.file,
- line: annotationProperties.startLine,
- endLine: annotationProperties.endLine,
- col: annotationProperties.startColumn,
- endColumn: annotationProperties.endColumn
- };
-}
-//# sourceMappingURL=utils.js.map
-;// CONCATENATED MODULE: ./node_modules/@actions/core/lib/command.js
-
-
-/**
- * Issues a command to the GitHub Actions runner
- *
- * @param command - The command name to issue
- * @param properties - Additional properties for the command (key-value pairs)
- * @param message - The message to include with the command
- * @remarks
- * This function outputs a specially formatted string to stdout that the Actions
- * runner interprets as a command. These commands can control workflow behavior,
- * set outputs, create annotations, mask values, and more.
- *
- * Command Format:
- * ::name key=value,key=value::message
- *
- * @example
- * ```typescript
- * // Issue a warning annotation
- * issueCommand('warning', {}, 'This is a warning message');
- * // Output: ::warning::This is a warning message
- *
- * // Set an environment variable
- * issueCommand('set-env', { name: 'MY_VAR' }, 'some value');
- * // Output: ::set-env name=MY_VAR::some value
- *
- * // Add a secret mask
- * issueCommand('add-mask', {}, 'secretValue123');
- * // Output: ::add-mask::secretValue123
- * ```
- *
- * @internal
- * This is an internal utility function that powers the public API functions
- * such as setSecret, warning, error, and exportVariable.
- */
-function command_issueCommand(command, properties, message) {
- const cmd = new Command(command, properties, message);
- process.stdout.write(cmd.toString() + external_os_.EOL);
-}
-function command_issue(name, message = '') {
- command_issueCommand(name, {}, message);
-}
-const CMD_STRING = '::';
-class Command {
- constructor(command, properties, message) {
- if (!command) {
- command = 'missing.command';
- }
- this.command = command;
- this.properties = properties;
- this.message = message;
- }
- toString() {
- let cmdStr = CMD_STRING + this.command;
- if (this.properties && Object.keys(this.properties).length > 0) {
- cmdStr += ' ';
- let first = true;
- for (const key in this.properties) {
- if (this.properties.hasOwnProperty(key)) {
- const val = this.properties[key];
- if (val) {
- if (first) {
- first = false;
- }
- else {
- cmdStr += ',';
- }
- cmdStr += `${key}=${escapeProperty(val)}`;
- }
- }
- }
- }
- cmdStr += `${CMD_STRING}${escapeData(this.message)}`;
- return cmdStr;
- }
-}
-function escapeData(s) {
- return utils_toCommandValue(s)
- .replace(/%/g, '%25')
- .replace(/\r/g, '%0D')
- .replace(/\n/g, '%0A');
-}
-function escapeProperty(s) {
- return utils_toCommandValue(s)
- .replace(/%/g, '%25')
- .replace(/\r/g, '%0D')
- .replace(/\n/g, '%0A')
- .replace(/:/g, '%3A')
- .replace(/,/g, '%2C');
-}
-//# sourceMappingURL=command.js.map
-;// CONCATENATED MODULE: external "crypto"
-const external_crypto_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("crypto");
-// EXTERNAL MODULE: external "fs"
-var external_fs_ = __nccwpck_require__(9896);
-;// CONCATENATED MODULE: ./node_modules/@actions/core/lib/file-command.js
-// For internal use, subject to change.
-// We use any as a valid input type
-/* eslint-disable @typescript-eslint/no-explicit-any */
-
-
-
-
-function file_command_issueFileCommand(command, message) {
- const filePath = process.env[`GITHUB_${command}`];
- if (!filePath) {
- throw new Error(`Unable to find environment variable for file command ${command}`);
- }
- if (!external_fs_.existsSync(filePath)) {
- throw new Error(`Missing file at path: ${filePath}`);
- }
- external_fs_.appendFileSync(filePath, `${utils_toCommandValue(message)}${external_os_.EOL}`, {
- encoding: 'utf8'
- });
-}
-function file_command_prepareKeyValueMessage(key, value) {
- const delimiter = `ghadelimiter_${external_crypto_namespaceObject.randomUUID()}`;
- const convertedValue = utils_toCommandValue(value);
- // These should realistically never happen, but just in case someone finds a
- // way to exploit uuid generation let's not allow keys or values that contain
- // the delimiter.
- if (key.includes(delimiter)) {
- throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`);
- }
- if (convertedValue.includes(delimiter)) {
- throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`);
- }
- return `${key}<<${delimiter}${external_os_.EOL}${convertedValue}${external_os_.EOL}${delimiter}`;
-}
-//# sourceMappingURL=file-command.js.map
-// EXTERNAL MODULE: external "path"
-var external_path_ = __nccwpck_require__(6928);
-// EXTERNAL MODULE: external "http"
-var external_http_ = __nccwpck_require__(8611);
-var external_http_namespaceObject = /*#__PURE__*/__nccwpck_require__.t(external_http_, 2);
-// EXTERNAL MODULE: external "https"
-var external_https_ = __nccwpck_require__(5692);
-var external_https_namespaceObject = /*#__PURE__*/__nccwpck_require__.t(external_https_, 2);
-;// CONCATENATED MODULE: ./node_modules/@actions/http-client/lib/proxy.js
-function getProxyUrl(reqUrl) {
- const usingSsl = reqUrl.protocol === 'https:';
- if (checkBypass(reqUrl)) {
- return undefined;
- }
- const proxyVar = (() => {
- if (usingSsl) {
- return process.env['https_proxy'] || process.env['HTTPS_PROXY'];
- }
- else {
- return process.env['http_proxy'] || process.env['HTTP_PROXY'];
- }
- })();
- if (proxyVar) {
- try {
- return new DecodedURL(proxyVar);
- }
- catch (_a) {
- if (!proxyVar.startsWith('http://') && !proxyVar.startsWith('https://'))
- return new DecodedURL(`http://${proxyVar}`);
- }
- }
- else {
- return undefined;
- }
-}
-function checkBypass(reqUrl) {
- if (!reqUrl.hostname) {
- return false;
- }
- const reqHost = reqUrl.hostname;
- if (isLoopbackAddress(reqHost)) {
- return true;
- }
- const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';
- if (!noProxy) {
- return false;
- }
- // Determine the request port
- let reqPort;
- if (reqUrl.port) {
- reqPort = Number(reqUrl.port);
- }
- else if (reqUrl.protocol === 'http:') {
- reqPort = 80;
- }
- else if (reqUrl.protocol === 'https:') {
- reqPort = 443;
- }
- // Format the request hostname and hostname with port
- const upperReqHosts = [reqUrl.hostname.toUpperCase()];
- if (typeof reqPort === 'number') {
- upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);
- }
- // Compare request host against noproxy
- for (const upperNoProxyItem of noProxy
- .split(',')
- .map(x => x.trim().toUpperCase())
- .filter(x => x)) {
- if (upperNoProxyItem === '*' ||
- upperReqHosts.some(x => x === upperNoProxyItem ||
- x.endsWith(`.${upperNoProxyItem}`) ||
- (upperNoProxyItem.startsWith('.') &&
- x.endsWith(`${upperNoProxyItem}`)))) {
- return true;
- }
- }
- return false;
-}
-function isLoopbackAddress(host) {
- const hostLower = host.toLowerCase();
- return (hostLower === 'localhost' ||
- hostLower.startsWith('127.') ||
- hostLower.startsWith('[::1]') ||
- hostLower.startsWith('[0:0:0:0:0:0:0:1]'));
-}
-class DecodedURL extends URL {
- constructor(url, base) {
- super(url, base);
- this._decodedUsername = decodeURIComponent(super.username);
- this._decodedPassword = decodeURIComponent(super.password);
- }
- get username() {
- return this._decodedUsername;
- }
- get password() {
- return this._decodedPassword;
- }
-}
-//# sourceMappingURL=proxy.js.map
-// EXTERNAL MODULE: ./node_modules/tunnel/index.js
-var tunnel = __nccwpck_require__(770);
-// EXTERNAL MODULE: ./node_modules/undici/index.js
-var undici = __nccwpck_require__(6752);
-;// CONCATENATED MODULE: ./node_modules/@actions/http-client/lib/index.js
-/* eslint-disable @typescript-eslint/no-explicit-any */
-var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
-
-
-
-
-
-var HttpCodes;
-(function (HttpCodes) {
- HttpCodes[HttpCodes["OK"] = 200] = "OK";
- HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices";
- HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently";
- HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved";
- HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther";
- HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified";
- HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy";
- HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy";
- HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect";
- HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect";
- HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest";
- HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized";
- HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired";
- HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden";
- HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound";
- HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed";
- HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable";
- HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
- HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout";
- HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict";
- HttpCodes[HttpCodes["Gone"] = 410] = "Gone";
- HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests";
- HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError";
- HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented";
- HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway";
- HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable";
- HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout";
-})(HttpCodes || (HttpCodes = {}));
-var Headers;
-(function (Headers) {
- Headers["Accept"] = "accept";
- Headers["ContentType"] = "content-type";
-})(Headers || (Headers = {}));
-var MediaTypes;
-(function (MediaTypes) {
- MediaTypes["ApplicationJson"] = "application/json";
-})(MediaTypes || (MediaTypes = {}));
-/**
- * Returns the proxy URL, depending upon the supplied url and proxy environment variables.
- * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com
- */
-function lib_getProxyUrl(serverUrl) {
- const proxyUrl = pm.getProxyUrl(new URL(serverUrl));
- return proxyUrl ? proxyUrl.href : '';
-}
-const HttpRedirectCodes = [
- HttpCodes.MovedPermanently,
- HttpCodes.ResourceMoved,
- HttpCodes.SeeOther,
- HttpCodes.TemporaryRedirect,
- HttpCodes.PermanentRedirect
-];
-const HttpResponseRetryCodes = [
- HttpCodes.BadGateway,
- HttpCodes.ServiceUnavailable,
- HttpCodes.GatewayTimeout
-];
-const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];
-const ExponentialBackoffCeiling = 10;
-const ExponentialBackoffTimeSlice = 5;
-class HttpClientError extends Error {
- constructor(message, statusCode) {
- super(message);
- this.name = 'HttpClientError';
- this.statusCode = statusCode;
- Object.setPrototypeOf(this, HttpClientError.prototype);
- }
-}
-class HttpClientResponse {
- constructor(message) {
- this.message = message;
- }
- readBody() {
- return __awaiter(this, void 0, void 0, function* () {
- return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
- let output = Buffer.alloc(0);
- this.message.on('data', (chunk) => {
- output = Buffer.concat([output, chunk]);
- });
- this.message.on('end', () => {
- resolve(output.toString());
- });
- }));
- });
- }
- readBodyBuffer() {
- return __awaiter(this, void 0, void 0, function* () {
- return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
- const chunks = [];
- this.message.on('data', (chunk) => {
- chunks.push(chunk);
- });
- this.message.on('end', () => {
- resolve(Buffer.concat(chunks));
- });
- }));
- });
- }
-}
-function isHttps(requestUrl) {
- const parsedUrl = new URL(requestUrl);
- return parsedUrl.protocol === 'https:';
-}
-class lib_HttpClient {
- constructor(userAgent, handlers, requestOptions) {
- this._ignoreSslError = false;
- this._allowRedirects = true;
- this._allowRedirectDowngrade = false;
- this._maxRedirects = 50;
- this._allowRetries = false;
- this._maxRetries = 1;
- this._keepAlive = false;
- this._disposed = false;
- this.userAgent = this._getUserAgentWithOrchestrationId(userAgent);
- this.handlers = handlers || [];
- this.requestOptions = requestOptions;
- if (requestOptions) {
- if (requestOptions.ignoreSslError != null) {
- this._ignoreSslError = requestOptions.ignoreSslError;
- }
- this._socketTimeout = requestOptions.socketTimeout;
- if (requestOptions.allowRedirects != null) {
- this._allowRedirects = requestOptions.allowRedirects;
- }
- if (requestOptions.allowRedirectDowngrade != null) {
- this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade;
- }
- if (requestOptions.maxRedirects != null) {
- this._maxRedirects = Math.max(requestOptions.maxRedirects, 0);
- }
- if (requestOptions.keepAlive != null) {
- this._keepAlive = requestOptions.keepAlive;
- }
- if (requestOptions.allowRetries != null) {
- this._allowRetries = requestOptions.allowRetries;
- }
- if (requestOptions.maxRetries != null) {
- this._maxRetries = requestOptions.maxRetries;
- }
- }
- }
- options(requestUrl, additionalHeaders) {
- return __awaiter(this, void 0, void 0, function* () {
- return this.request('OPTIONS', requestUrl, null, additionalHeaders || {});
- });
- }
- get(requestUrl, additionalHeaders) {
- return __awaiter(this, void 0, void 0, function* () {
- return this.request('GET', requestUrl, null, additionalHeaders || {});
- });
- }
- del(requestUrl, additionalHeaders) {
- return __awaiter(this, void 0, void 0, function* () {
- return this.request('DELETE', requestUrl, null, additionalHeaders || {});
- });
- }
- post(requestUrl, data, additionalHeaders) {
- return __awaiter(this, void 0, void 0, function* () {
- return this.request('POST', requestUrl, data, additionalHeaders || {});
- });
- }
- patch(requestUrl, data, additionalHeaders) {
- return __awaiter(this, void 0, void 0, function* () {
- return this.request('PATCH', requestUrl, data, additionalHeaders || {});
- });
- }
- put(requestUrl, data, additionalHeaders) {
- return __awaiter(this, void 0, void 0, function* () {
- return this.request('PUT', requestUrl, data, additionalHeaders || {});
- });
- }
- head(requestUrl, additionalHeaders) {
- return __awaiter(this, void 0, void 0, function* () {
- return this.request('HEAD', requestUrl, null, additionalHeaders || {});
- });
- }
- sendStream(verb, requestUrl, stream, additionalHeaders) {
- return __awaiter(this, void 0, void 0, function* () {
- return this.request(verb, requestUrl, stream, additionalHeaders);
- });
- }
- /**
- * Gets a typed object from an endpoint
- * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise
- */
- getJson(requestUrl_1) {
- return __awaiter(this, arguments, void 0, function* (requestUrl, additionalHeaders = {}) {
- additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
- const res = yield this.get(requestUrl, additionalHeaders);
- return this._processResponse(res, this.requestOptions);
- });
- }
- postJson(requestUrl_1, obj_1) {
- return __awaiter(this, arguments, void 0, function* (requestUrl, obj, additionalHeaders = {}) {
- const data = JSON.stringify(obj, null, 2);
- additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
- additionalHeaders[Headers.ContentType] =
- this._getExistingOrDefaultContentTypeHeader(additionalHeaders, MediaTypes.ApplicationJson);
- const res = yield this.post(requestUrl, data, additionalHeaders);
- return this._processResponse(res, this.requestOptions);
- });
- }
- putJson(requestUrl_1, obj_1) {
- return __awaiter(this, arguments, void 0, function* (requestUrl, obj, additionalHeaders = {}) {
- const data = JSON.stringify(obj, null, 2);
- additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
- additionalHeaders[Headers.ContentType] =
- this._getExistingOrDefaultContentTypeHeader(additionalHeaders, MediaTypes.ApplicationJson);
- const res = yield this.put(requestUrl, data, additionalHeaders);
- return this._processResponse(res, this.requestOptions);
- });
- }
- patchJson(requestUrl_1, obj_1) {
- return __awaiter(this, arguments, void 0, function* (requestUrl, obj, additionalHeaders = {}) {
- const data = JSON.stringify(obj, null, 2);
- additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
- additionalHeaders[Headers.ContentType] =
- this._getExistingOrDefaultContentTypeHeader(additionalHeaders, MediaTypes.ApplicationJson);
- const res = yield this.patch(requestUrl, data, additionalHeaders);
- return this._processResponse(res, this.requestOptions);
- });
- }
- /**
- * Makes a raw http request.
- * All other methods such as get, post, patch, and request ultimately call this.
- * Prefer get, del, post and patch
- */
- request(verb, requestUrl, data, headers) {
- return __awaiter(this, void 0, void 0, function* () {
- if (this._disposed) {
- throw new Error('Client has already been disposed.');
- }
- const parsedUrl = new URL(requestUrl);
- let info = this._prepareRequest(verb, parsedUrl, headers);
- // Only perform retries on reads since writes may not be idempotent.
- const maxTries = this._allowRetries && RetryableHttpVerbs.includes(verb)
- ? this._maxRetries + 1
- : 1;
- let numTries = 0;
- let response;
- do {
- response = yield this.requestRaw(info, data);
- // Check if it's an authentication challenge
- if (response &&
- response.message &&
- response.message.statusCode === HttpCodes.Unauthorized) {
- let authenticationHandler;
- for (const handler of this.handlers) {
- if (handler.canHandleAuthentication(response)) {
- authenticationHandler = handler;
- break;
- }
- }
- if (authenticationHandler) {
- return authenticationHandler.handleAuthentication(this, info, data);
- }
- else {
- // We have received an unauthorized response but have no handlers to handle it.
- // Let the response return to the caller.
- return response;
- }
- }
- let redirectsRemaining = this._maxRedirects;
- while (response.message.statusCode &&
- HttpRedirectCodes.includes(response.message.statusCode) &&
- this._allowRedirects &&
- redirectsRemaining > 0) {
- const redirectUrl = response.message.headers['location'];
- if (!redirectUrl) {
- // if there's no location to redirect to, we won't
- break;
- }
- const parsedRedirectUrl = new URL(redirectUrl);
- if (parsedUrl.protocol === 'https:' &&
- parsedUrl.protocol !== parsedRedirectUrl.protocol &&
- !this._allowRedirectDowngrade) {
- throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.');
- }
- // we need to finish reading the response before reassigning response
- // which will leak the open socket.
- yield response.readBody();
- // strip authorization header if redirected to a different hostname
- if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {
- for (const header in headers) {
- // header names are case insensitive
- if (header.toLowerCase() === 'authorization') {
- delete headers[header];
- }
- }
- }
- // let's make the request with the new redirectUrl
- info = this._prepareRequest(verb, parsedRedirectUrl, headers);
- response = yield this.requestRaw(info, data);
- redirectsRemaining--;
- }
- if (!response.message.statusCode ||
- !HttpResponseRetryCodes.includes(response.message.statusCode)) {
- // If not a retry code, return immediately instead of retrying
- return response;
- }
- numTries += 1;
- if (numTries < maxTries) {
- yield response.readBody();
- yield this._performExponentialBackoff(numTries);
- }
- } while (numTries < maxTries);
- return response;
- });
- }
- /**
- * Needs to be called if keepAlive is set to true in request options.
- */
- dispose() {
- if (this._agent) {
- this._agent.destroy();
- }
- this._disposed = true;
- }
- /**
- * Raw request.
- * @param info
- * @param data
- */
- requestRaw(info, data) {
- return __awaiter(this, void 0, void 0, function* () {
- return new Promise((resolve, reject) => {
- function callbackForResult(err, res) {
- if (err) {
- reject(err);
- }
- else if (!res) {
- // If `err` is not passed, then `res` must be passed.
- reject(new Error('Unknown error'));
- }
- else {
- resolve(res);
- }
- }
- this.requestRawWithCallback(info, data, callbackForResult);
- });
- });
- }
- /**
- * Raw request with callback.
- * @param info
- * @param data
- * @param onResult
- */
- requestRawWithCallback(info, data, onResult) {
- if (typeof data === 'string') {
- if (!info.options.headers) {
- info.options.headers = {};
- }
- info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');
- }
- let callbackCalled = false;
- function handleResult(err, res) {
- if (!callbackCalled) {
- callbackCalled = true;
- onResult(err, res);
- }
- }
- const req = info.httpModule.request(info.options, (msg) => {
- const res = new HttpClientResponse(msg);
- handleResult(undefined, res);
- });
- let socket;
- req.on('socket', sock => {
- socket = sock;
- });
- // If we ever get disconnected, we want the socket to timeout eventually
- req.setTimeout(this._socketTimeout || 3 * 60000, () => {
- if (socket) {
- socket.end();
- }
- handleResult(new Error(`Request timeout: ${info.options.path}`));
- });
- req.on('error', function (err) {
- // err has statusCode property
- // res should have headers
- handleResult(err);
- });
- if (data && typeof data === 'string') {
- req.write(data, 'utf8');
- }
- if (data && typeof data !== 'string') {
- data.on('close', function () {
- req.end();
- });
- data.pipe(req);
- }
- else {
- req.end();
- }
- }
- /**
- * Gets an http agent. This function is useful when you need an http agent that handles
- * routing through a proxy server - depending upon the url and proxy environment variables.
- * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com
- */
- getAgent(serverUrl) {
- const parsedUrl = new URL(serverUrl);
- return this._getAgent(parsedUrl);
- }
- getAgentDispatcher(serverUrl) {
- const parsedUrl = new URL(serverUrl);
- const proxyUrl = getProxyUrl(parsedUrl);
- const useProxy = proxyUrl && proxyUrl.hostname;
- if (!useProxy) {
- return;
- }
- return this._getProxyAgentDispatcher(parsedUrl, proxyUrl);
- }
- _prepareRequest(method, requestUrl, headers) {
- const info = {};
- info.parsedUrl = requestUrl;
- const usingSsl = info.parsedUrl.protocol === 'https:';
- info.httpModule = usingSsl ? external_https_namespaceObject : external_http_namespaceObject;
- const defaultPort = usingSsl ? 443 : 80;
- info.options = {};
- info.options.host = info.parsedUrl.hostname;
- info.options.port = info.parsedUrl.port
- ? parseInt(info.parsedUrl.port)
- : defaultPort;
- info.options.path =
- (info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');
- info.options.method = method;
- info.options.headers = this._mergeHeaders(headers);
- if (this.userAgent != null) {
- info.options.headers['user-agent'] = this.userAgent;
- }
- info.options.agent = this._getAgent(info.parsedUrl);
- // gives handlers an opportunity to participate
- if (this.handlers) {
- for (const handler of this.handlers) {
- handler.prepareRequest(info.options);
- }
- }
- return info;
- }
- _mergeHeaders(headers) {
- if (this.requestOptions && this.requestOptions.headers) {
- return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers || {}));
- }
- return lowercaseKeys(headers || {});
- }
- /**
- * Gets an existing header value or returns a default.
- * Handles converting number header values to strings since HTTP headers must be strings.
- * Note: This returns string | string[] since some headers can have multiple values.
- * For headers that must always be a single string (like Content-Type), use the
- * specialized _getExistingOrDefaultContentTypeHeader method instead.
- */
- _getExistingOrDefaultHeader(additionalHeaders, header, _default) {
- let clientHeader;
- if (this.requestOptions && this.requestOptions.headers) {
- const headerValue = lowercaseKeys(this.requestOptions.headers)[header];
- if (headerValue) {
- clientHeader =
- typeof headerValue === 'number' ? headerValue.toString() : headerValue;
- }
- }
- const additionalValue = additionalHeaders[header];
- if (additionalValue !== undefined) {
- return typeof additionalValue === 'number'
- ? additionalValue.toString()
- : additionalValue;
- }
- if (clientHeader !== undefined) {
- return clientHeader;
- }
- return _default;
- }
- /**
- * Specialized version of _getExistingOrDefaultHeader for Content-Type header.
- * Always returns a single string (not an array) since Content-Type should be a single value.
- * Converts arrays to comma-separated strings and numbers to strings to ensure type safety.
- * This was split from _getExistingOrDefaultHeader to provide stricter typing for callers
- * that assign the result to places expecting a string (e.g., additionalHeaders[Headers.ContentType]).
- */
- _getExistingOrDefaultContentTypeHeader(additionalHeaders, _default) {
- let clientHeader;
- if (this.requestOptions && this.requestOptions.headers) {
- const headerValue = lowercaseKeys(this.requestOptions.headers)[Headers.ContentType];
- if (headerValue) {
- if (typeof headerValue === 'number') {
- clientHeader = String(headerValue);
- }
- else if (Array.isArray(headerValue)) {
- clientHeader = headerValue.join(', ');
- }
- else {
- clientHeader = headerValue;
- }
- }
- }
- const additionalValue = additionalHeaders[Headers.ContentType];
- // Return the first non-undefined value, converting numbers or arrays to strings if necessary
- if (additionalValue !== undefined) {
- if (typeof additionalValue === 'number') {
- return String(additionalValue);
- }
- else if (Array.isArray(additionalValue)) {
- return additionalValue.join(', ');
- }
- else {
- return additionalValue;
- }
- }
- if (clientHeader !== undefined) {
- return clientHeader;
- }
- return _default;
- }
- _getAgent(parsedUrl) {
- let agent;
- const proxyUrl = getProxyUrl(parsedUrl);
- const useProxy = proxyUrl && proxyUrl.hostname;
- if (this._keepAlive && useProxy) {
- agent = this._proxyAgent;
- }
- if (!useProxy) {
- agent = this._agent;
- }
- // if agent is already assigned use that agent.
- if (agent) {
- return agent;
- }
- const usingSsl = parsedUrl.protocol === 'https:';
- let maxSockets = 100;
- if (this.requestOptions) {
- maxSockets = this.requestOptions.maxSockets || external_http_.globalAgent.maxSockets;
- }
- // This is `useProxy` again, but we need to check `proxyURl` directly for TypeScripts's flow analysis.
- if (proxyUrl && proxyUrl.hostname) {
- const agentOptions = {
- maxSockets,
- keepAlive: this._keepAlive,
- proxy: Object.assign(Object.assign({}, ((proxyUrl.username || proxyUrl.password) && {
- proxyAuth: `${proxyUrl.username}:${proxyUrl.password}`
- })), { host: proxyUrl.hostname, port: proxyUrl.port })
- };
- let tunnelAgent;
- const overHttps = proxyUrl.protocol === 'https:';
- if (usingSsl) {
- tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp;
- }
- else {
- tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp;
- }
- agent = tunnelAgent(agentOptions);
- this._proxyAgent = agent;
- }
- // if tunneling agent isn't assigned create a new agent
- if (!agent) {
- const options = { keepAlive: this._keepAlive, maxSockets };
- agent = usingSsl ? new external_https_.Agent(options) : new external_http_.Agent(options);
- this._agent = agent;
- }
- if (usingSsl && this._ignoreSslError) {
- // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process
- // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options
- // we have to cast it to any and change it directly
- agent.options = Object.assign(agent.options || {}, {
- rejectUnauthorized: false
- });
- }
- return agent;
- }
- _getProxyAgentDispatcher(parsedUrl, proxyUrl) {
- let proxyAgent;
- if (this._keepAlive) {
- proxyAgent = this._proxyAgentDispatcher;
- }
- // if agent is already assigned use that agent.
- if (proxyAgent) {
- return proxyAgent;
- }
- const usingSsl = parsedUrl.protocol === 'https:';
- proxyAgent = new undici.ProxyAgent(Object.assign({ uri: proxyUrl.href, pipelining: !this._keepAlive ? 0 : 1 }, ((proxyUrl.username || proxyUrl.password) && {
- token: `Basic ${Buffer.from(`${proxyUrl.username}:${proxyUrl.password}`).toString('base64')}`
- })));
- this._proxyAgentDispatcher = proxyAgent;
- if (usingSsl && this._ignoreSslError) {
- // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process
- // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options
- // we have to cast it to any and change it directly
- proxyAgent.options = Object.assign(proxyAgent.options.requestTls || {}, {
- rejectUnauthorized: false
- });
- }
- return proxyAgent;
- }
- _getUserAgentWithOrchestrationId(userAgent) {
- const baseUserAgent = userAgent || 'actions/http-client';
- const orchId = process.env['ACTIONS_ORCHESTRATION_ID'];
- if (orchId) {
- // Sanitize the orchestration ID to ensure it contains only valid characters
- // Valid characters: 0-9, a-z, _, -, .
- const sanitizedId = orchId.replace(/[^a-z0-9_.-]/gi, '_');
- return `${baseUserAgent} actions_orchestration_id/${sanitizedId}`;
- }
- return baseUserAgent;
- }
- _performExponentialBackoff(retryNumber) {
- return __awaiter(this, void 0, void 0, function* () {
- retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber);
- const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber);
- return new Promise(resolve => setTimeout(() => resolve(), ms));
- });
- }
- _processResponse(res, options) {
- return __awaiter(this, void 0, void 0, function* () {
- return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
- const statusCode = res.message.statusCode || 0;
- const response = {
- statusCode,
- result: null,
- headers: {}
- };
- // not found leads to null obj returned
- if (statusCode === HttpCodes.NotFound) {
- resolve(response);
- }
- // get the result from the body
- function dateTimeDeserializer(key, value) {
- if (typeof value === 'string') {
- const a = new Date(value);
- if (!isNaN(a.valueOf())) {
- return a;
- }
- }
- return value;
- }
- let obj;
- let contents;
- try {
- contents = yield res.readBody();
- if (contents && contents.length > 0) {
- if (options && options.deserializeDates) {
- obj = JSON.parse(contents, dateTimeDeserializer);
- }
- else {
- obj = JSON.parse(contents);
- }
- response.result = obj;
- }
- response.headers = res.message.headers;
- }
- catch (err) {
- // Invalid resource (contents not json); leaving result obj null
- }
- // note that 3xx redirects are handled by the http layer.
- if (statusCode > 299) {
- let msg;
- // if exception/error in body, attempt to get better error
- if (obj && obj.message) {
- msg = obj.message;
- }
- else if (contents && contents.length > 0) {
- // it may be the case that the exception is in the body message as string
- msg = contents;
- }
- else {
- msg = `Failed request: (${statusCode})`;
- }
- const err = new HttpClientError(msg, statusCode);
- err.result = response.result;
- reject(err);
- }
- else {
- resolve(response);
- }
- }));
- });
- }
-}
-const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
-//# sourceMappingURL=index.js.map
-;// CONCATENATED MODULE: ./node_modules/@actions/http-client/lib/auth.js
-var auth_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
-class BasicCredentialHandler {
- constructor(username, password) {
- this.username = username;
- this.password = password;
- }
- prepareRequest(options) {
- if (!options.headers) {
- throw Error('The request has no headers');
- }
- options.headers['Authorization'] = `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`;
- }
- // This handler cannot handle 401
- canHandleAuthentication() {
- return false;
- }
- handleAuthentication() {
- return auth_awaiter(this, void 0, void 0, function* () {
- throw new Error('not implemented');
- });
- }
-}
-class auth_BearerCredentialHandler {
- constructor(token) {
- this.token = token;
- }
- // currently implements pre-authorization
- // TODO: support preAuth = false where it hooks on 401
- prepareRequest(options) {
- if (!options.headers) {
- throw Error('The request has no headers');
- }
- options.headers['Authorization'] = `Bearer ${this.token}`;
- }
- // This handler cannot handle 401
- canHandleAuthentication() {
- return false;
- }
- handleAuthentication() {
- return auth_awaiter(this, void 0, void 0, function* () {
- throw new Error('not implemented');
- });
- }
-}
-class PersonalAccessTokenCredentialHandler {
- constructor(token) {
- this.token = token;
- }
- // currently implements pre-authorization
- // TODO: support preAuth = false where it hooks on 401
- prepareRequest(options) {
- if (!options.headers) {
- throw Error('The request has no headers');
- }
- options.headers['Authorization'] = `Basic ${Buffer.from(`PAT:${this.token}`).toString('base64')}`;
- }
- // This handler cannot handle 401
- canHandleAuthentication() {
- return false;
- }
- handleAuthentication() {
- return auth_awaiter(this, void 0, void 0, function* () {
- throw new Error('not implemented');
- });
- }
-}
-//# sourceMappingURL=auth.js.map
-;// CONCATENATED MODULE: ./node_modules/@actions/core/lib/oidc-utils.js
-var oidc_utils_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
-
-
-
-class oidc_utils_OidcClient {
- static createHttpClient(allowRetry = true, maxRetry = 10) {
- const requestOptions = {
- allowRetries: allowRetry,
- maxRetries: maxRetry
- };
- return new HttpClient('actions/oidc-client', [new BearerCredentialHandler(oidc_utils_OidcClient.getRequestToken())], requestOptions);
- }
- static getRequestToken() {
- const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'];
- if (!token) {
- throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable');
- }
- return token;
- }
- static getIDTokenUrl() {
- const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL'];
- if (!runtimeUrl) {
- throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable');
- }
- return runtimeUrl;
- }
- static getCall(id_token_url) {
- return oidc_utils_awaiter(this, void 0, void 0, function* () {
- var _a;
- const httpclient = oidc_utils_OidcClient.createHttpClient();
- const res = yield httpclient
- .getJson(id_token_url)
- .catch(error => {
- throw new Error(`Failed to get ID Token. \n
- Error Code : ${error.statusCode}\n
- Error Message: ${error.message}`);
- });
- const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value;
- if (!id_token) {
- throw new Error('Response json body do not have ID Token field');
- }
- return id_token;
- });
- }
- static getIDToken(audience) {
- return oidc_utils_awaiter(this, void 0, void 0, function* () {
- try {
- // New ID Token is requested from action service
- let id_token_url = oidc_utils_OidcClient.getIDTokenUrl();
- if (audience) {
- const encodedAudience = encodeURIComponent(audience);
- id_token_url = `${id_token_url}&audience=${encodedAudience}`;
- }
- debug(`ID token url is ${id_token_url}`);
- const id_token = yield oidc_utils_OidcClient.getCall(id_token_url);
- setSecret(id_token);
- return id_token;
- }
- catch (error) {
- throw new Error(`Error message: ${error.message}`);
- }
- });
- }
-}
-//# sourceMappingURL=oidc-utils.js.map
-;// CONCATENATED MODULE: ./node_modules/@actions/core/lib/summary.js
-var summary_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
-
-
-const { access, appendFile, writeFile } = external_fs_.promises;
-const SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY';
-const SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary';
-class Summary {
- constructor() {
- this._buffer = '';
- }
- /**
- * Finds the summary file path from the environment, rejects if env var is not found or file does not exist
- * Also checks r/w permissions.
- *
- * @returns step summary file path
- */
- filePath() {
- return summary_awaiter(this, void 0, void 0, function* () {
- if (this._filePath) {
- return this._filePath;
- }
- const pathFromEnv = process.env[SUMMARY_ENV_VAR];
- if (!pathFromEnv) {
- throw new Error(`Unable to find environment variable for $${SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`);
- }
- try {
- yield access(pathFromEnv, external_fs_.constants.R_OK | external_fs_.constants.W_OK);
- }
- catch (_a) {
- throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`);
- }
- this._filePath = pathFromEnv;
- return this._filePath;
- });
- }
- /**
- * Wraps content in an HTML tag, adding any HTML attributes
- *
- * @param {string} tag HTML tag to wrap
- * @param {string | null} content content within the tag
- * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add
- *
- * @returns {string} content wrapped in HTML element
- */
- wrap(tag, content, attrs = {}) {
- const htmlAttrs = Object.entries(attrs)
- .map(([key, value]) => ` ${key}="${value}"`)
- .join('');
- if (!content) {
- return `<${tag}${htmlAttrs}>`;
- }
- return `<${tag}${htmlAttrs}>${content}${tag}>`;
- }
- /**
- * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default.
- *
- * @param {SummaryWriteOptions} [options] (optional) options for write operation
- *
- * @returns {Promise} summary instance
- */
- write(options) {
- return summary_awaiter(this, void 0, void 0, function* () {
- const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite);
- const filePath = yield this.filePath();
- const writeFunc = overwrite ? writeFile : appendFile;
- yield writeFunc(filePath, this._buffer, { encoding: 'utf8' });
- return this.emptyBuffer();
- });
- }
- /**
- * Clears the summary buffer and wipes the summary file
- *
- * @returns {Summary} summary instance
- */
- clear() {
- return summary_awaiter(this, void 0, void 0, function* () {
- return this.emptyBuffer().write({ overwrite: true });
- });
- }
- /**
- * Returns the current summary buffer as a string
- *
- * @returns {string} string of summary buffer
- */
- stringify() {
- return this._buffer;
- }
- /**
- * If the summary buffer is empty
- *
- * @returns {boolen} true if the buffer is empty
- */
- isEmptyBuffer() {
- return this._buffer.length === 0;
- }
- /**
- * Resets the summary buffer without writing to summary file
- *
- * @returns {Summary} summary instance
- */
- emptyBuffer() {
- this._buffer = '';
- return this;
- }
- /**
- * Adds raw text to the summary buffer
- *
- * @param {string} text content to add
- * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false)
- *
- * @returns {Summary} summary instance
- */
- addRaw(text, addEOL = false) {
- this._buffer += text;
- return addEOL ? this.addEOL() : this;
- }
- /**
- * Adds the operating system-specific end-of-line marker to the buffer
- *
- * @returns {Summary} summary instance
- */
- addEOL() {
- return this.addRaw(external_os_.EOL);
- }
- /**
- * Adds an HTML codeblock to the summary buffer
- *
- * @param {string} code content to render within fenced code block
- * @param {string} lang (optional) language to syntax highlight code
- *
- * @returns {Summary} summary instance
- */
- addCodeBlock(code, lang) {
- const attrs = Object.assign({}, (lang && { lang }));
- const element = this.wrap('pre', this.wrap('code', code), attrs);
- return this.addRaw(element).addEOL();
- }
- /**
- * Adds an HTML list to the summary buffer
- *
- * @param {string[]} items list of items to render
- * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false)
- *
- * @returns {Summary} summary instance
- */
- addList(items, ordered = false) {
- const tag = ordered ? 'ol' : 'ul';
- const listItems = items.map(item => this.wrap('li', item)).join('');
- const element = this.wrap(tag, listItems);
- return this.addRaw(element).addEOL();
- }
- /**
- * Adds an HTML table to the summary buffer
- *
- * @param {SummaryTableCell[]} rows table rows
- *
- * @returns {Summary} summary instance
- */
- addTable(rows) {
- const tableBody = rows
- .map(row => {
- const cells = row
- .map(cell => {
- if (typeof cell === 'string') {
- return this.wrap('td', cell);
- }
- const { header, data, colspan, rowspan } = cell;
- const tag = header ? 'th' : 'td';
- const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan }));
- return this.wrap(tag, data, attrs);
- })
- .join('');
- return this.wrap('tr', cells);
- })
- .join('');
- const element = this.wrap('table', tableBody);
- return this.addRaw(element).addEOL();
- }
- /**
- * Adds a collapsable HTML details element to the summary buffer
- *
- * @param {string} label text for the closed state
- * @param {string} content collapsable content
- *
- * @returns {Summary} summary instance
- */
- addDetails(label, content) {
- const element = this.wrap('details', this.wrap('summary', label) + content);
- return this.addRaw(element).addEOL();
- }
- /**
- * Adds an HTML image tag to the summary buffer
- *
- * @param {string} src path to the image you to embed
- * @param {string} alt text description of the image
- * @param {SummaryImageOptions} options (optional) addition image attributes
- *
- * @returns {Summary} summary instance
- */
- addImage(src, alt, options) {
- const { width, height } = options || {};
- const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height }));
- const element = this.wrap('img', null, Object.assign({ src, alt }, attrs));
- return this.addRaw(element).addEOL();
- }
- /**
- * Adds an HTML section heading element
- *
- * @param {string} text heading text
- * @param {number | string} [level=1] (optional) the heading level, default: 1
- *
- * @returns {Summary} summary instance
- */
- addHeading(text, level) {
- const tag = `h${level}`;
- const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag)
- ? tag
- : 'h1';
- const element = this.wrap(allowedTag, text);
- return this.addRaw(element).addEOL();
- }
- /**
- * Adds an HTML thematic break (
) to the summary buffer
- *
- * @returns {Summary} summary instance
- */
- addSeparator() {
- const element = this.wrap('hr', null);
- return this.addRaw(element).addEOL();
- }
- /**
- * Adds an HTML line break (
) to the summary buffer
- *
- * @returns {Summary} summary instance
- */
- addBreak() {
- const element = this.wrap('br', null);
- return this.addRaw(element).addEOL();
- }
- /**
- * Adds an HTML blockquote to the summary buffer
- *
- * @param {string} text quote text
- * @param {string} cite (optional) citation url
- *
- * @returns {Summary} summary instance
- */
- addQuote(text, cite) {
- const attrs = Object.assign({}, (cite && { cite }));
- const element = this.wrap('blockquote', text, attrs);
- return this.addRaw(element).addEOL();
- }
- /**
- * Adds an HTML anchor tag to the summary buffer
- *
- * @param {string} text link text/content
- * @param {string} href hyperlink
- *
- * @returns {Summary} summary instance
- */
- addLink(text, href) {
- const element = this.wrap('a', text, { href });
- return this.addRaw(element).addEOL();
- }
-}
-const _summary = new Summary();
-/**
- * @deprecated use `core.summary`
- */
-const markdownSummary = (/* unused pure expression or super */ null && (_summary));
-const summary = (/* unused pure expression or super */ null && (_summary));
-//# sourceMappingURL=summary.js.map
-;// CONCATENATED MODULE: ./node_modules/@actions/core/lib/path-utils.js
-
-/**
- * toPosixPath converts the given path to the posix form. On Windows, \\ will be
- * replaced with /.
- *
- * @param pth. Path to transform.
- * @return string Posix path.
- */
-function toPosixPath(pth) {
- return pth.replace(/[\\]/g, '/');
-}
-/**
- * toWin32Path converts the given path to the win32 form. On Linux, / will be
- * replaced with \\.
- *
- * @param pth. Path to transform.
- * @return string Win32 path.
- */
-function toWin32Path(pth) {
- return pth.replace(/[/]/g, '\\');
-}
-/**
- * toPlatformPath converts the given path to a platform-specific path. It does
- * this by replacing instances of / and \ with the platform-specific path
- * separator.
- *
- * @param pth The path to platformize.
- * @return string The platform-specific path.
- */
-function toPlatformPath(pth) {
- return pth.replace(/[/\\]/g, path.sep);
-}
-//# sourceMappingURL=path-utils.js.map
-// EXTERNAL MODULE: external "string_decoder"
-var external_string_decoder_ = __nccwpck_require__(3193);
-// EXTERNAL MODULE: external "events"
-var external_events_ = __nccwpck_require__(4434);
-;// CONCATENATED MODULE: external "child_process"
-const external_child_process_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("child_process");
-// EXTERNAL MODULE: external "assert"
-var external_assert_ = __nccwpck_require__(2613);
-;// CONCATENATED MODULE: ./node_modules/@actions/io/lib/io-util.js
-var io_util_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
-
-
-const { chmod, copyFile, lstat, mkdir, open: io_util_open, readdir, rename, rm, rmdir, stat, symlink, unlink } = external_fs_.promises;
-// export const {open} = 'fs'
-const IS_WINDOWS = process.platform === 'win32';
-/**
- * Custom implementation of readlink to ensure Windows junctions
- * maintain trailing backslash for backward compatibility with Node.js < 24
- *
- * In Node.js 20, Windows junctions (directory symlinks) always returned paths
- * with trailing backslashes. Node.js 24 removed this behavior, which breaks
- * code that relied on this format for path operations.
- *
- * This implementation restores the Node 20 behavior by adding a trailing
- * backslash to all junction results on Windows.
- */
-function readlink(fsPath) {
- return io_util_awaiter(this, void 0, void 0, function* () {
- const result = yield fs.promises.readlink(fsPath);
- // On Windows, restore Node 20 behavior: add trailing backslash to all results
- // since junctions on Windows are always directory links
- if (IS_WINDOWS && !result.endsWith('\\')) {
- return `${result}\\`;
- }
- return result;
- });
-}
-// See https://github.com/nodejs/node/blob/d0153aee367422d0858105abec186da4dff0a0c5/deps/uv/include/uv/win.h#L691
-const UV_FS_O_EXLOCK = 0x10000000;
-const READONLY = external_fs_.constants.O_RDONLY;
-function exists(fsPath) {
- return io_util_awaiter(this, void 0, void 0, function* () {
- try {
- yield stat(fsPath);
- }
- catch (err) {
- if (err.code === 'ENOENT') {
- return false;
- }
- throw err;
- }
- return true;
- });
-}
-function isDirectory(fsPath_1) {
- return io_util_awaiter(this, arguments, void 0, function* (fsPath, useStat = false) {
- const stats = useStat ? yield stat(fsPath) : yield lstat(fsPath);
- return stats.isDirectory();
- });
-}
-/**
- * On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
- * \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
- */
-function isRooted(p) {
- p = normalizeSeparators(p);
- if (!p) {
- throw new Error('isRooted() parameter "p" cannot be empty');
- }
- if (IS_WINDOWS) {
- return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
- ); // e.g. C: or C:\hello
- }
- return p.startsWith('/');
-}
-/**
- * Best effort attempt to determine whether a file exists and is executable.
- * @param filePath file path to check
- * @param extensions additional file extensions to try
- * @return if file exists and is executable, returns the file path. otherwise empty string.
- */
-function tryGetExecutablePath(filePath, extensions) {
- return io_util_awaiter(this, void 0, void 0, function* () {
- let stats = undefined;
- try {
- // test file exists
- stats = yield stat(filePath);
- }
- catch (err) {
- if (err.code !== 'ENOENT') {
- // eslint-disable-next-line no-console
- console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
- }
- }
- if (stats && stats.isFile()) {
- if (IS_WINDOWS) {
- // on Windows, test for valid extension
- const upperExt = external_path_.extname(filePath).toUpperCase();
- if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {
- return filePath;
- }
- }
- else {
- if (isUnixExecutable(stats)) {
- return filePath;
- }
- }
- }
- // try each extension
- const originalFilePath = filePath;
- for (const extension of extensions) {
- filePath = originalFilePath + extension;
- stats = undefined;
- try {
- stats = yield stat(filePath);
- }
- catch (err) {
- if (err.code !== 'ENOENT') {
- // eslint-disable-next-line no-console
- console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
- }
- }
- if (stats && stats.isFile()) {
- if (IS_WINDOWS) {
- // preserve the case of the actual file (since an extension was appended)
- try {
- const directory = external_path_.dirname(filePath);
- const upperName = external_path_.basename(filePath).toUpperCase();
- for (const actualName of yield readdir(directory)) {
- if (upperName === actualName.toUpperCase()) {
- filePath = external_path_.join(directory, actualName);
- break;
- }
- }
- }
- catch (err) {
- // eslint-disable-next-line no-console
- console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`);
- }
- return filePath;
- }
- else {
- if (isUnixExecutable(stats)) {
- return filePath;
- }
- }
- }
- }
- return '';
- });
-}
-function normalizeSeparators(p) {
- p = p || '';
- if (IS_WINDOWS) {
- // convert slashes on Windows
- p = p.replace(/\//g, '\\');
- // remove redundant slashes
- return p.replace(/\\\\+/g, '\\');
- }
- // remove redundant slashes
- return p.replace(/\/\/+/g, '/');
-}
-// on Mac/Linux, test the execute bit
-// R W X R W X R W X
-// 256 128 64 32 16 8 4 2 1
-function isUnixExecutable(stats) {
- return ((stats.mode & 1) > 0 ||
- ((stats.mode & 8) > 0 &&
- process.getgid !== undefined &&
- stats.gid === process.getgid()) ||
- ((stats.mode & 64) > 0 &&
- process.getuid !== undefined &&
- stats.uid === process.getuid()));
-}
-// Get the path of cmd.exe in windows
-function getCmdPath() {
- var _a;
- return (_a = process.env['COMSPEC']) !== null && _a !== void 0 ? _a : `cmd.exe`;
-}
-//# sourceMappingURL=io-util.js.map
-;// CONCATENATED MODULE: ./node_modules/@actions/io/lib/io.js
-var io_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
-
-
-
-/**
- * Copies a file or folder.
- * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
- *
- * @param source source path
- * @param dest destination path
- * @param options optional. See CopyOptions.
- */
-function cp(source_1, dest_1) {
- return io_awaiter(this, arguments, void 0, function* (source, dest, options = {}) {
- const { force, recursive, copySourceDirectory } = readCopyOptions(options);
- const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;
- // Dest is an existing file, but not forcing
- if (destStat && destStat.isFile() && !force) {
- return;
- }
- // If dest is an existing directory, should copy inside.
- const newDest = destStat && destStat.isDirectory() && copySourceDirectory
- ? path.join(dest, path.basename(source))
- : dest;
- if (!(yield ioUtil.exists(source))) {
- throw new Error(`no such file or directory: ${source}`);
- }
- const sourceStat = yield ioUtil.stat(source);
- if (sourceStat.isDirectory()) {
- if (!recursive) {
- throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`);
- }
- else {
- yield cpDirRecursive(source, newDest, 0, force);
- }
- }
- else {
- if (path.relative(source, newDest) === '') {
- // a file cannot be copied to itself
- throw new Error(`'${newDest}' and '${source}' are the same file`);
- }
- yield io_copyFile(source, newDest, force);
- }
- });
-}
-/**
- * Moves a path.
- *
- * @param source source path
- * @param dest destination path
- * @param options optional. See MoveOptions.
- */
-function mv(source_1, dest_1) {
- return io_awaiter(this, arguments, void 0, function* (source, dest, options = {}) {
- if (yield ioUtil.exists(dest)) {
- let destExists = true;
- if (yield ioUtil.isDirectory(dest)) {
- // If dest is directory copy src into dest
- dest = path.join(dest, path.basename(source));
- destExists = yield ioUtil.exists(dest);
- }
- if (destExists) {
- if (options.force == null || options.force) {
- yield rmRF(dest);
- }
- else {
- throw new Error('Destination already exists');
- }
- }
- }
- yield mkdirP(path.dirname(dest));
- yield ioUtil.rename(source, dest);
- });
-}
-/**
- * Remove a path recursively with force
- *
- * @param inputPath path to remove
- */
-function rmRF(inputPath) {
- return io_awaiter(this, void 0, void 0, function* () {
- if (ioUtil.IS_WINDOWS) {
- // Check for invalid characters
- // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
- if (/[*"<>|]/.test(inputPath)) {
- throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows');
- }
- }
- try {
- // note if path does not exist, error is silent
- yield ioUtil.rm(inputPath, {
- force: true,
- maxRetries: 3,
- recursive: true,
- retryDelay: 300
- });
- }
- catch (err) {
- throw new Error(`File was unable to be removed ${err}`);
- }
- });
-}
-/**
- * Make a directory. Creates the full path with folders in between
- * Will throw if it fails
- *
- * @param fsPath path to create
- * @returns Promise
- */
-function mkdirP(fsPath) {
- return io_awaiter(this, void 0, void 0, function* () {
- ok(fsPath, 'a path argument must be provided');
- yield ioUtil.mkdir(fsPath, { recursive: true });
- });
-}
-/**
- * Returns path of a tool had the tool actually been invoked. Resolves via paths.
- * If you check and the tool does not exist, it will throw.
- *
- * @param tool name of the tool
- * @param check whether to check if tool exists
- * @returns Promise path to tool
- */
-function which(tool, check) {
- return io_awaiter(this, void 0, void 0, function* () {
- if (!tool) {
- throw new Error("parameter 'tool' is required");
- }
- // recursive when check=true
- if (check) {
- const result = yield which(tool, false);
- if (!result) {
- if (IS_WINDOWS) {
- throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`);
- }
- else {
- throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);
- }
- }
- return result;
- }
- const matches = yield findInPath(tool);
- if (matches && matches.length > 0) {
- return matches[0];
- }
- return '';
- });
-}
-/**
- * Returns a list of all occurrences of the given tool on the system path.
- *
- * @returns Promise the paths of the tool
- */
-function findInPath(tool) {
- return io_awaiter(this, void 0, void 0, function* () {
- if (!tool) {
- throw new Error("parameter 'tool' is required");
- }
- // build the list of extensions to try
- const extensions = [];
- if (IS_WINDOWS && process.env['PATHEXT']) {
- for (const extension of process.env['PATHEXT'].split(external_path_.delimiter)) {
- if (extension) {
- extensions.push(extension);
- }
- }
- }
- // if it's rooted, return it if exists. otherwise return empty.
- if (isRooted(tool)) {
- const filePath = yield tryGetExecutablePath(tool, extensions);
- if (filePath) {
- return [filePath];
- }
- return [];
- }
- // if any path separators, return empty
- if (tool.includes(external_path_.sep)) {
- return [];
- }
- // build the list of directories
- //
- // Note, technically "where" checks the current directory on Windows. From a toolkit perspective,
- // it feels like we should not do this. Checking the current directory seems like more of a use
- // case of a shell, and the which() function exposed by the toolkit should strive for consistency
- // across platforms.
- const directories = [];
- if (process.env.PATH) {
- for (const p of process.env.PATH.split(external_path_.delimiter)) {
- if (p) {
- directories.push(p);
- }
- }
- }
- // find all matches
- const matches = [];
- for (const directory of directories) {
- const filePath = yield tryGetExecutablePath(external_path_.join(directory, tool), extensions);
- if (filePath) {
- matches.push(filePath);
- }
- }
- return matches;
- });
-}
-function readCopyOptions(options) {
- const force = options.force == null ? true : options.force;
- const recursive = Boolean(options.recursive);
- const copySourceDirectory = options.copySourceDirectory == null
- ? true
- : Boolean(options.copySourceDirectory);
- return { force, recursive, copySourceDirectory };
-}
-function cpDirRecursive(sourceDir, destDir, currentDepth, force) {
- return io_awaiter(this, void 0, void 0, function* () {
- // Ensure there is not a run away recursive copy
- if (currentDepth >= 255)
- return;
- currentDepth++;
- yield mkdirP(destDir);
- const files = yield ioUtil.readdir(sourceDir);
- for (const fileName of files) {
- const srcFile = `${sourceDir}/${fileName}`;
- const destFile = `${destDir}/${fileName}`;
- const srcFileStat = yield ioUtil.lstat(srcFile);
- if (srcFileStat.isDirectory()) {
- // Recurse
- yield cpDirRecursive(srcFile, destFile, currentDepth, force);
- }
- else {
- yield io_copyFile(srcFile, destFile, force);
- }
- }
- // Change the mode for the newly created directory
- yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode);
- });
-}
-// Buffered file copy
-function io_copyFile(srcFile, destFile, force) {
- return io_awaiter(this, void 0, void 0, function* () {
- if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) {
- // unlink/re-link it
- try {
- yield ioUtil.lstat(destFile);
- yield ioUtil.unlink(destFile);
- }
- catch (e) {
- // Try to override file permission
- if (e.code === 'EPERM') {
- yield ioUtil.chmod(destFile, '0666');
- yield ioUtil.unlink(destFile);
- }
- // other errors = it doesn't exist, no work to do
- }
- // Copy over symlink
- const symlinkFull = yield ioUtil.readlink(srcFile);
- yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null);
- }
- else if (!(yield ioUtil.exists(destFile)) || force) {
- yield ioUtil.copyFile(srcFile, destFile);
- }
- });
-}
-//# sourceMappingURL=io.js.map
-;// CONCATENATED MODULE: external "timers"
-const external_timers_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("timers");
-;// CONCATENATED MODULE: ./node_modules/@actions/exec/lib/toolrunner.js
-var toolrunner_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
-
-
-
-
-
-
-
-/* eslint-disable @typescript-eslint/unbound-method */
-const toolrunner_IS_WINDOWS = process.platform === 'win32';
-/*
- * Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way.
- */
-class ToolRunner extends external_events_.EventEmitter {
- constructor(toolPath, args, options) {
- super();
- if (!toolPath) {
- throw new Error("Parameter 'toolPath' cannot be null or empty.");
- }
- this.toolPath = toolPath;
- this.args = args || [];
- this.options = options || {};
- }
- _debug(message) {
- if (this.options.listeners && this.options.listeners.debug) {
- this.options.listeners.debug(message);
- }
- }
- _getCommandString(options, noPrefix) {
- const toolPath = this._getSpawnFileName();
- const args = this._getSpawnArgs(options);
- let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool
- if (toolrunner_IS_WINDOWS) {
- // Windows + cmd file
- if (this._isCmdFile()) {
- cmd += toolPath;
- for (const a of args) {
- cmd += ` ${a}`;
- }
- }
- // Windows + verbatim
- else if (options.windowsVerbatimArguments) {
- cmd += `"${toolPath}"`;
- for (const a of args) {
- cmd += ` ${a}`;
- }
- }
- // Windows (regular)
- else {
- cmd += this._windowsQuoteCmdArg(toolPath);
- for (const a of args) {
- cmd += ` ${this._windowsQuoteCmdArg(a)}`;
- }
- }
- }
- else {
- // OSX/Linux - this can likely be improved with some form of quoting.
- // creating processes on Unix is fundamentally different than Windows.
- // on Unix, execvp() takes an arg array.
- cmd += toolPath;
- for (const a of args) {
- cmd += ` ${a}`;
- }
- }
- return cmd;
- }
- _processLineBuffer(data, strBuffer, onLine) {
- try {
- let s = strBuffer + data.toString();
- let n = s.indexOf(external_os_.EOL);
- while (n > -1) {
- const line = s.substring(0, n);
- onLine(line);
- // the rest of the string ...
- s = s.substring(n + external_os_.EOL.length);
- n = s.indexOf(external_os_.EOL);
- }
- return s;
- }
- catch (err) {
- // streaming lines to console is best effort. Don't fail a build.
- this._debug(`error processing line. Failed with error ${err}`);
- return '';
- }
- }
- _getSpawnFileName() {
- if (toolrunner_IS_WINDOWS) {
- if (this._isCmdFile()) {
- return process.env['COMSPEC'] || 'cmd.exe';
- }
- }
- return this.toolPath;
- }
- _getSpawnArgs(options) {
- if (toolrunner_IS_WINDOWS) {
- if (this._isCmdFile()) {
- let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;
- for (const a of this.args) {
- argline += ' ';
- argline += options.windowsVerbatimArguments
- ? a
- : this._windowsQuoteCmdArg(a);
- }
- argline += '"';
- return [argline];
- }
- }
- return this.args;
- }
- _endsWith(str, end) {
- return str.endsWith(end);
- }
- _isCmdFile() {
- const upperToolPath = this.toolPath.toUpperCase();
- return (this._endsWith(upperToolPath, '.CMD') ||
- this._endsWith(upperToolPath, '.BAT'));
- }
- _windowsQuoteCmdArg(arg) {
- // for .exe, apply the normal quoting rules that libuv applies
- if (!this._isCmdFile()) {
- return this._uvQuoteCmdArg(arg);
- }
- // otherwise apply quoting rules specific to the cmd.exe command line parser.
- // the libuv rules are generic and are not designed specifically for cmd.exe
- // command line parser.
- //
- // for a detailed description of the cmd.exe command line parser, refer to
- // http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912
- // need quotes for empty arg
- if (!arg) {
- return '""';
- }
- // determine whether the arg needs to be quoted
- const cmdSpecialChars = [
- ' ',
- '\t',
- '&',
- '(',
- ')',
- '[',
- ']',
- '{',
- '}',
- '^',
- '=',
- ';',
- '!',
- "'",
- '+',
- ',',
- '`',
- '~',
- '|',
- '<',
- '>',
- '"'
- ];
- let needsQuotes = false;
- for (const char of arg) {
- if (cmdSpecialChars.some(x => x === char)) {
- needsQuotes = true;
- break;
- }
- }
- // short-circuit if quotes not needed
- if (!needsQuotes) {
- return arg;
- }
- // the following quoting rules are very similar to the rules that by libuv applies.
- //
- // 1) wrap the string in quotes
- //
- // 2) double-up quotes - i.e. " => ""
- //
- // this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately
- // doesn't work well with a cmd.exe command line.
- //
- // note, replacing " with "" also works well if the arg is passed to a downstream .NET console app.
- // for example, the command line:
- // foo.exe "myarg:""my val"""
- // is parsed by a .NET console app into an arg array:
- // [ "myarg:\"my val\"" ]
- // which is the same end result when applying libuv quoting rules. although the actual
- // command line from libuv quoting rules would look like:
- // foo.exe "myarg:\"my val\""
- //
- // 3) double-up slashes that precede a quote,
- // e.g. hello \world => "hello \world"
- // hello\"world => "hello\\""world"
- // hello\\"world => "hello\\\\""world"
- // hello world\ => "hello world\\"
- //
- // technically this is not required for a cmd.exe command line, or the batch argument parser.
- // the reasons for including this as a .cmd quoting rule are:
- //
- // a) this is optimized for the scenario where the argument is passed from the .cmd file to an
- // external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.
- //
- // b) it's what we've been doing previously (by deferring to node default behavior) and we
- // haven't heard any complaints about that aspect.
- //
- // note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be
- // escaped when used on the command line directly - even though within a .cmd file % can be escaped
- // by using %%.
- //
- // the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts
- // the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.
- //
- // one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would
- // often work, since it is unlikely that var^ would exist, and the ^ character is removed when the
- // variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args
- // to an external program.
- //
- // an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.
- // % can be escaped within a .cmd file.
- let reverse = '"';
- let quoteHit = true;
- for (let i = arg.length; i > 0; i--) {
- // walk the string in reverse
- reverse += arg[i - 1];
- if (quoteHit && arg[i - 1] === '\\') {
- reverse += '\\'; // double the slash
- }
- else if (arg[i - 1] === '"') {
- quoteHit = true;
- reverse += '"'; // double the quote
- }
- else {
- quoteHit = false;
- }
- }
- reverse += '"';
- return reverse.split('').reverse().join('');
- }
- _uvQuoteCmdArg(arg) {
- // Tool runner wraps child_process.spawn() and needs to apply the same quoting as
- // Node in certain cases where the undocumented spawn option windowsVerbatimArguments
- // is used.
- //
- // Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,
- // see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),
- // pasting copyright notice from Node within this function:
- //
- // Copyright Joyent, Inc. and other Node contributors. All rights reserved.
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- if (!arg) {
- // Need double quotation for empty argument
- return '""';
- }
- if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) {
- // No quotation needed
- return arg;
- }
- if (!arg.includes('"') && !arg.includes('\\')) {
- // No embedded double quotes or backslashes, so I can just wrap
- // quote marks around the whole thing.
- return `"${arg}"`;
- }
- // Expected input/output:
- // input : hello"world
- // output: "hello\"world"
- // input : hello""world
- // output: "hello\"\"world"
- // input : hello\world
- // output: hello\world
- // input : hello\\world
- // output: hello\\world
- // input : hello\"world
- // output: "hello\\\"world"
- // input : hello\\"world
- // output: "hello\\\\\"world"
- // input : hello world\
- // output: "hello world\\" - note the comment in libuv actually reads "hello world\"
- // but it appears the comment is wrong, it should be "hello world\\"
- let reverse = '"';
- let quoteHit = true;
- for (let i = arg.length; i > 0; i--) {
- // walk the string in reverse
- reverse += arg[i - 1];
- if (quoteHit && arg[i - 1] === '\\') {
- reverse += '\\';
- }
- else if (arg[i - 1] === '"') {
- quoteHit = true;
- reverse += '\\';
- }
- else {
- quoteHit = false;
- }
- }
- reverse += '"';
- return reverse.split('').reverse().join('');
- }
- _cloneExecOptions(options) {
- options = options || {};
- const result = {
- cwd: options.cwd || process.cwd(),
- env: options.env || process.env,
- silent: options.silent || false,
- windowsVerbatimArguments: options.windowsVerbatimArguments || false,
- failOnStdErr: options.failOnStdErr || false,
- ignoreReturnCode: options.ignoreReturnCode || false,
- delay: options.delay || 10000
- };
- result.outStream = options.outStream || process.stdout;
- result.errStream = options.errStream || process.stderr;
- return result;
- }
- _getSpawnOptions(options, toolPath) {
- options = options || {};
- const result = {};
- result.cwd = options.cwd;
- result.env = options.env;
- result['windowsVerbatimArguments'] =
- options.windowsVerbatimArguments || this._isCmdFile();
- if (options.windowsVerbatimArguments) {
- result.argv0 = `"${toolPath}"`;
- }
- return result;
- }
- /**
- * Exec a tool.
- * Output will be streamed to the live console.
- * Returns promise with return code
- *
- * @param tool path to tool to exec
- * @param options optional exec options. See ExecOptions
- * @returns number
- */
- exec() {
- return toolrunner_awaiter(this, void 0, void 0, function* () {
- // root the tool path if it is unrooted and contains relative pathing
- if (!isRooted(this.toolPath) &&
- (this.toolPath.includes('/') ||
- (toolrunner_IS_WINDOWS && this.toolPath.includes('\\')))) {
- // prefer options.cwd if it is specified, however options.cwd may also need to be rooted
- this.toolPath = external_path_.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath);
- }
- // if the tool is only a file name, then resolve it from the PATH
- // otherwise verify it exists (add extension on Windows if necessary)
- this.toolPath = yield which(this.toolPath, true);
- return new Promise((resolve, reject) => toolrunner_awaiter(this, void 0, void 0, function* () {
- this._debug(`exec tool: ${this.toolPath}`);
- this._debug('arguments:');
- for (const arg of this.args) {
- this._debug(` ${arg}`);
- }
- const optionsNonNull = this._cloneExecOptions(this.options);
- if (!optionsNonNull.silent && optionsNonNull.outStream) {
- optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + external_os_.EOL);
- }
- const state = new ExecState(optionsNonNull, this.toolPath);
- state.on('debug', (message) => {
- this._debug(message);
- });
- if (this.options.cwd && !(yield exists(this.options.cwd))) {
- return reject(new Error(`The cwd: ${this.options.cwd} does not exist!`));
- }
- const fileName = this._getSpawnFileName();
- const cp = external_child_process_namespaceObject.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName));
- let stdbuffer = '';
- if (cp.stdout) {
- cp.stdout.on('data', (data) => {
- if (this.options.listeners && this.options.listeners.stdout) {
- this.options.listeners.stdout(data);
- }
- if (!optionsNonNull.silent && optionsNonNull.outStream) {
- optionsNonNull.outStream.write(data);
- }
- stdbuffer = this._processLineBuffer(data, stdbuffer, (line) => {
- if (this.options.listeners && this.options.listeners.stdline) {
- this.options.listeners.stdline(line);
- }
- });
- });
- }
- let errbuffer = '';
- if (cp.stderr) {
- cp.stderr.on('data', (data) => {
- state.processStderr = true;
- if (this.options.listeners && this.options.listeners.stderr) {
- this.options.listeners.stderr(data);
- }
- if (!optionsNonNull.silent &&
- optionsNonNull.errStream &&
- optionsNonNull.outStream) {
- const s = optionsNonNull.failOnStdErr
- ? optionsNonNull.errStream
- : optionsNonNull.outStream;
- s.write(data);
- }
- errbuffer = this._processLineBuffer(data, errbuffer, (line) => {
- if (this.options.listeners && this.options.listeners.errline) {
- this.options.listeners.errline(line);
- }
- });
- });
- }
- cp.on('error', (err) => {
- state.processError = err.message;
- state.processExited = true;
- state.processClosed = true;
- state.CheckComplete();
- });
- cp.on('exit', (code) => {
- state.processExitCode = code;
- state.processExited = true;
- this._debug(`Exit code ${code} received from tool '${this.toolPath}'`);
- state.CheckComplete();
- });
- cp.on('close', (code) => {
- state.processExitCode = code;
- state.processExited = true;
- state.processClosed = true;
- this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);
- state.CheckComplete();
- });
- state.on('done', (error, exitCode) => {
- if (stdbuffer.length > 0) {
- this.emit('stdline', stdbuffer);
- }
- if (errbuffer.length > 0) {
- this.emit('errline', errbuffer);
- }
- cp.removeAllListeners();
- if (error) {
- reject(error);
- }
- else {
- resolve(exitCode);
- }
- });
- if (this.options.input) {
- if (!cp.stdin) {
- throw new Error('child process missing stdin');
- }
- cp.stdin.end(this.options.input);
- }
- }));
- });
- }
-}
-/**
- * Convert an arg string to an array of args. Handles escaping
- *
- * @param argString string of arguments
- * @returns string[] array of arguments
- */
-function argStringToArray(argString) {
- const args = [];
- let inQuotes = false;
- let escaped = false;
- let arg = '';
- function append(c) {
- // we only escape double quotes.
- if (escaped && c !== '"') {
- arg += '\\';
- }
- arg += c;
- escaped = false;
- }
- for (let i = 0; i < argString.length; i++) {
- const c = argString.charAt(i);
- if (c === '"') {
- if (!escaped) {
- inQuotes = !inQuotes;
- }
- else {
- append(c);
- }
- continue;
- }
- if (c === '\\' && escaped) {
- append(c);
- continue;
- }
- if (c === '\\' && inQuotes) {
- escaped = true;
- continue;
- }
- if (c === ' ' && !inQuotes) {
- if (arg.length > 0) {
- args.push(arg);
- arg = '';
- }
- continue;
- }
- append(c);
- }
- if (arg.length > 0) {
- args.push(arg.trim());
- }
- return args;
-}
-class ExecState extends external_events_.EventEmitter {
- constructor(options, toolPath) {
- super();
- this.processClosed = false; // tracks whether the process has exited and stdio is closed
- this.processError = '';
- this.processExitCode = 0;
- this.processExited = false; // tracks whether the process has exited
- this.processStderr = false; // tracks whether stderr was written to
- this.delay = 10000; // 10 seconds
- this.done = false;
- this.timeout = null;
- if (!toolPath) {
- throw new Error('toolPath must not be empty');
- }
- this.options = options;
- this.toolPath = toolPath;
- if (options.delay) {
- this.delay = options.delay;
- }
- }
- CheckComplete() {
- if (this.done) {
- return;
- }
- if (this.processClosed) {
- this._setResult();
- }
- else if (this.processExited) {
- this.timeout = (0,external_timers_namespaceObject.setTimeout)(ExecState.HandleTimeout, this.delay, this);
- }
- }
- _debug(message) {
- this.emit('debug', message);
- }
- _setResult() {
- // determine whether there is an error
- let error;
- if (this.processExited) {
- if (this.processError) {
- error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`);
- }
- else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) {
- error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`);
- }
- else if (this.processStderr && this.options.failOnStdErr) {
- error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`);
- }
- }
- // clear the timeout
- if (this.timeout) {
- clearTimeout(this.timeout);
- this.timeout = null;
- }
- this.done = true;
- this.emit('done', error, this.processExitCode);
- }
- static HandleTimeout(state) {
- if (state.done) {
- return;
- }
- if (!state.processClosed && state.processExited) {
- const message = `The STDIO streams did not close within ${state.delay / 1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;
- state._debug(message);
- }
- state._setResult();
- }
-}
-//# sourceMappingURL=toolrunner.js.map
-;// CONCATENATED MODULE: ./node_modules/@actions/exec/lib/exec.js
-var exec_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
-
-
-/**
- * Exec a command.
- * Output will be streamed to the live console.
- * Returns promise with return code
- *
- * @param commandLine command to execute (can include additional args). Must be correctly escaped.
- * @param args optional arguments for tool. Escaping is handled by the lib.
- * @param options optional exec options. See ExecOptions
- * @returns Promise exit code
- */
-function exec_exec(commandLine, args, options) {
- return exec_awaiter(this, void 0, void 0, function* () {
- const commandArgs = tr.argStringToArray(commandLine);
- if (commandArgs.length === 0) {
- throw new Error(`Parameter 'commandLine' cannot be null or empty.`);
- }
- // Path to tool to execute should be first arg
- const toolPath = commandArgs[0];
- args = commandArgs.slice(1).concat(args || []);
- const runner = new tr.ToolRunner(toolPath, args, options);
- return runner.exec();
- });
-}
-/**
- * Exec a command and get the output.
- * Output will be streamed to the live console.
- * Returns promise with the exit code and collected stdout and stderr
- *
- * @param commandLine command to execute (can include additional args). Must be correctly escaped.
- * @param args optional arguments for tool. Escaping is handled by the lib.
- * @param options optional exec options. See ExecOptions
- * @returns Promise exit code, stdout, and stderr
- */
-function getExecOutput(commandLine, args, options) {
- return exec_awaiter(this, void 0, void 0, function* () {
- var _a, _b;
- let stdout = '';
- let stderr = '';
- //Using string decoder covers the case where a mult-byte character is split
- const stdoutDecoder = new StringDecoder('utf8');
- const stderrDecoder = new StringDecoder('utf8');
- const originalStdoutListener = (_a = options === null || options === void 0 ? void 0 : options.listeners) === null || _a === void 0 ? void 0 : _a.stdout;
- const originalStdErrListener = (_b = options === null || options === void 0 ? void 0 : options.listeners) === null || _b === void 0 ? void 0 : _b.stderr;
- const stdErrListener = (data) => {
- stderr += stderrDecoder.write(data);
- if (originalStdErrListener) {
- originalStdErrListener(data);
- }
- };
- const stdOutListener = (data) => {
- stdout += stdoutDecoder.write(data);
- if (originalStdoutListener) {
- originalStdoutListener(data);
- }
- };
- const listeners = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.listeners), { stdout: stdOutListener, stderr: stdErrListener });
- const exitCode = yield exec_exec(commandLine, args, Object.assign(Object.assign({}, options), { listeners }));
- //flush any remaining characters
- stdout += stdoutDecoder.end();
- stderr += stderrDecoder.end();
- return {
- exitCode,
- stdout,
- stderr
- };
- });
-}
-//# sourceMappingURL=exec.js.map
-;// CONCATENATED MODULE: ./node_modules/@actions/core/lib/platform.js
-var platform_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
-
-
-const getWindowsInfo = () => platform_awaiter(void 0, void 0, void 0, function* () {
- const { stdout: version } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', undefined, {
- silent: true
- });
- const { stdout: name } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Caption"', undefined, {
- silent: true
- });
- return {
- name: name.trim(),
- version: version.trim()
- };
-});
-const getMacOsInfo = () => platform_awaiter(void 0, void 0, void 0, function* () {
- var _a, _b, _c, _d;
- const { stdout } = yield exec.getExecOutput('sw_vers', undefined, {
- silent: true
- });
- const version = (_b = (_a = stdout.match(/ProductVersion:\s*(.+)/)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : '';
- const name = (_d = (_c = stdout.match(/ProductName:\s*(.+)/)) === null || _c === void 0 ? void 0 : _c[1]) !== null && _d !== void 0 ? _d : '';
- return {
- name,
- version
- };
-});
-const getLinuxInfo = () => platform_awaiter(void 0, void 0, void 0, function* () {
- const { stdout } = yield exec.getExecOutput('lsb_release', ['-i', '-r', '-s'], {
- silent: true
- });
- const [name, version] = stdout.trim().split('\n');
- return {
- name,
- version
- };
-});
-const platform = external_os_.platform();
-const arch = external_os_.arch();
-const isWindows = platform === 'win32';
-const isMacOS = platform === 'darwin';
-const isLinux = platform === 'linux';
-function getDetails() {
- return platform_awaiter(this, void 0, void 0, function* () {
- return Object.assign(Object.assign({}, (yield (isWindows
- ? getWindowsInfo()
- : isMacOS
- ? getMacOsInfo()
- : getLinuxInfo()))), { platform,
- arch,
- isWindows,
- isMacOS,
- isLinux });
- });
-}
-//# sourceMappingURL=platform.js.map
-;// CONCATENATED MODULE: ./node_modules/@actions/core/lib/core.js
-var core_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
-
-
-
-
-
-
-/**
- * The code to exit an action
- */
-var ExitCode;
-(function (ExitCode) {
- /**
- * A code indicating that the action was successful
- */
- ExitCode[ExitCode["Success"] = 0] = "Success";
- /**
- * A code indicating that the action was a failure
- */
- ExitCode[ExitCode["Failure"] = 1] = "Failure";
-})(ExitCode || (ExitCode = {}));
-//-----------------------------------------------------------------------
-// Variables
-//-----------------------------------------------------------------------
-/**
- * Sets env variable for this action and future actions in the job
- * @param name the name of the variable to set
- * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
- */
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-function exportVariable(name, val) {
- const convertedVal = toCommandValue(val);
- process.env[name] = convertedVal;
- const filePath = process.env['GITHUB_ENV'] || '';
- if (filePath) {
- return issueFileCommand('ENV', prepareKeyValueMessage(name, val));
- }
- issueCommand('set-env', { name }, convertedVal);
-}
-/**
- * Registers a secret which will get masked from logs
- *
- * @param secret - Value of the secret to be masked
- * @remarks
- * This function instructs the Actions runner to mask the specified value in any
- * logs produced during the workflow run. Once registered, the secret value will
- * be replaced with asterisks (***) whenever it appears in console output, logs,
- * or error messages.
- *
- * This is useful for protecting sensitive information such as:
- * - API keys
- * - Access tokens
- * - Authentication credentials
- * - URL parameters containing signatures (SAS tokens)
- *
- * Note that masking only affects future logs; any previous appearances of the
- * secret in logs before calling this function will remain unmasked.
- *
- * @example
- * ```typescript
- * // Register an API token as a secret
- * const apiToken = "abc123xyz456";
- * setSecret(apiToken);
- *
- * // Now any logs containing this value will show *** instead
- * console.log(`Using token: ${apiToken}`); // Outputs: "Using token: ***"
- * ```
- */
-function core_setSecret(secret) {
- command_issueCommand('add-mask', {}, secret);
-}
-/**
- * Prepends inputPath to the PATH (for this action and future actions)
- * @param inputPath
- */
-function addPath(inputPath) {
- const filePath = process.env['GITHUB_PATH'] || '';
- if (filePath) {
- issueFileCommand('PATH', inputPath);
- }
- else {
- issueCommand('add-path', {}, inputPath);
- }
- process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
-}
-/**
- * Gets the value of an input.
- * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed.
- * Returns an empty string if the value is not defined.
- *
- * @param name name of the input to get
- * @param options optional. See InputOptions.
- * @returns string
- */
-function getInput(name, options) {
- const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';
- if (options && options.required && !val) {
- throw new Error(`Input required and not supplied: ${name}`);
- }
- if (options && options.trimWhitespace === false) {
- return val;
- }
- return val.trim();
-}
-/**
- * Gets the values of an multiline input. Each value is also trimmed.
- *
- * @param name name of the input to get
- * @param options optional. See InputOptions.
- * @returns string[]
- *
- */
-function getMultilineInput(name, options) {
- const inputs = getInput(name, options)
- .split('\n')
- .filter(x => x !== '');
- if (options && options.trimWhitespace === false) {
- return inputs;
- }
- return inputs.map(input => input.trim());
-}
-/**
- * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification.
- * Support boolean input list: `true | True | TRUE | false | False | FALSE` .
- * The return value is also in boolean type.
- * ref: https://yaml.org/spec/1.2/spec.html#id2804923
- *
- * @param name name of the input to get
- * @param options optional. See InputOptions.
- * @returns boolean
- */
-function getBooleanInput(name, options) {
- const trueValue = ['true', 'True', 'TRUE'];
- const falseValue = ['false', 'False', 'FALSE'];
- const val = getInput(name, options);
- if (trueValue.includes(val))
- return true;
- if (falseValue.includes(val))
- return false;
- throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` +
- `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``);
-}
-/**
- * Sets the value of an output.
- *
- * @param name name of the output to set
- * @param value value to store. Non-string values will be converted to a string via JSON.stringify
- */
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-function setOutput(name, value) {
- const filePath = process.env['GITHUB_OUTPUT'] || '';
- if (filePath) {
- return file_command_issueFileCommand('OUTPUT', file_command_prepareKeyValueMessage(name, value));
- }
- process.stdout.write(external_os_.EOL);
- command_issueCommand('set-output', { name }, utils_toCommandValue(value));
-}
-/**
- * Enables or disables the echoing of commands into stdout for the rest of the step.
- * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
- *
- */
-function setCommandEcho(enabled) {
- issue('echo', enabled ? 'on' : 'off');
-}
-//-----------------------------------------------------------------------
-// Results
-//-----------------------------------------------------------------------
-/**
- * Sets the action status to failed.
- * When the action exits it will be with an exit code of 1
- * @param message add error issue message
- */
-function setFailed(message) {
- process.exitCode = ExitCode.Failure;
- core_error(message);
-}
-//-----------------------------------------------------------------------
-// Logging Commands
-//-----------------------------------------------------------------------
-/**
- * Gets whether Actions Step Debug is on or not
- */
-function isDebug() {
- return process.env['RUNNER_DEBUG'] === '1';
-}
-/**
- * Writes debug message to user log
- * @param message debug message
- */
-function core_debug(message) {
- command_issueCommand('debug', {}, message);
-}
-/**
- * Adds an error issue
- * @param message error issue message. Errors will be converted to string via toString()
- * @param properties optional properties to add to the annotation.
- */
-function core_error(message, properties = {}) {
- command_issueCommand('error', utils_toCommandProperties(properties), message instanceof Error ? message.toString() : message);
-}
-/**
- * Adds a warning issue
- * @param message warning issue message. Errors will be converted to string via toString()
- * @param properties optional properties to add to the annotation.
- */
-function warning(message, properties = {}) {
- command_issueCommand('warning', utils_toCommandProperties(properties), message instanceof Error ? message.toString() : message);
-}
-/**
- * Adds a notice issue
- * @param message notice issue message. Errors will be converted to string via toString()
- * @param properties optional properties to add to the annotation.
- */
-function notice(message, properties = {}) {
- issueCommand('notice', toCommandProperties(properties), message instanceof Error ? message.toString() : message);
-}
-/**
- * Writes info to log with console.log.
- * @param message info message
- */
-function info(message) {
- process.stdout.write(message + external_os_.EOL);
-}
-/**
- * Begin an output group.
- *
- * Output until the next `groupEnd` will be foldable in this group
- *
- * @param name The name of the output group
- */
-function startGroup(name) {
- issue('group', name);
-}
-/**
- * End an output group.
- */
-function endGroup() {
- issue('endgroup');
-}
-/**
- * Wrap an asynchronous function call in a group.
- *
- * Returns the same type as the function itself.
- *
- * @param name The name of the group
- * @param fn The function to wrap in the group
- */
-function group(name, fn) {
- return core_awaiter(this, void 0, void 0, function* () {
- startGroup(name);
- let result;
- try {
- result = yield fn();
- }
- finally {
- endGroup();
- }
- return result;
- });
-}
-//-----------------------------------------------------------------------
-// Wrapper action state
-//-----------------------------------------------------------------------
-/**
- * Saves state for current action, the state can only be retrieved by this action's post job execution.
- *
- * @param name name of the state to store
- * @param value value to store. Non-string values will be converted to a string via JSON.stringify
- */
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-function saveState(name, value) {
- const filePath = process.env['GITHUB_STATE'] || '';
- if (filePath) {
- return issueFileCommand('STATE', prepareKeyValueMessage(name, value));
- }
- issueCommand('save-state', { name }, toCommandValue(value));
-}
-/**
- * Gets the value of an state set by this action's main execution.
- *
- * @param name name of the state to get
- * @returns string
- */
-function getState(name) {
- return process.env[`STATE_${name}`] || '';
-}
-function getIDToken(aud) {
- return core_awaiter(this, void 0, void 0, function* () {
- return yield OidcClient.getIDToken(aud);
- });
-}
-/**
- * Summary exports
- */
-
-/**
- * @deprecated use core.summary
- */
-
-/**
- * Path exports
- */
-
-/**
- * Platform utilities exports
- */
-
-//# sourceMappingURL=core.js.map
-;// CONCATENATED MODULE: external "fs/promises"
-const promises_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("fs/promises");
-;// CONCATENATED MODULE: ./node_modules/balanced-match/dist/esm/index.js
-const balanced = (a, b, str) => {
- const ma = a instanceof RegExp ? maybeMatch(a, str) : a;
- const mb = b instanceof RegExp ? maybeMatch(b, str) : b;
- const r = ma !== null && mb != null && range(ma, mb, str);
- return (r && {
- start: r[0],
- end: r[1],
- pre: str.slice(0, r[0]),
- body: str.slice(r[0] + ma.length, r[1]),
- post: str.slice(r[1] + mb.length),
- });
-};
-const maybeMatch = (reg, str) => {
- const m = str.match(reg);
- return m ? m[0] : null;
-};
-const range = (a, b, str) => {
- let begs, beg, left, right = undefined, result;
- let ai = str.indexOf(a);
- let bi = str.indexOf(b, ai + 1);
- let i = ai;
- if (ai >= 0 && bi > 0) {
- if (a === b) {
- return [ai, bi];
- }
- begs = [];
- left = str.length;
- while (i >= 0 && !result) {
- if (i === ai) {
- begs.push(i);
- ai = str.indexOf(a, i + 1);
- }
- else if (begs.length === 1) {
- const r = begs.pop();
- if (r !== undefined)
- result = [r, bi];
- }
- else {
- beg = begs.pop();
- if (beg !== undefined && beg < left) {
- left = beg;
- right = bi;
- }
- bi = str.indexOf(b, i + 1);
- }
- i = ai < bi && ai >= 0 ? ai : bi;
- }
- if (begs.length && right !== undefined) {
- result = [left, right];
- }
- }
- return result;
-};
-//# sourceMappingURL=index.js.map
-;// CONCATENATED MODULE: ./node_modules/brace-expansion/dist/esm/index.js
-
-const escSlash = '\0SLASH' + Math.random() + '\0';
-const escOpen = '\0OPEN' + Math.random() + '\0';
-const escClose = '\0CLOSE' + Math.random() + '\0';
-const escComma = '\0COMMA' + Math.random() + '\0';
-const escPeriod = '\0PERIOD' + Math.random() + '\0';
-const escSlashPattern = new RegExp(escSlash, 'g');
-const escOpenPattern = new RegExp(escOpen, 'g');
-const escClosePattern = new RegExp(escClose, 'g');
-const escCommaPattern = new RegExp(escComma, 'g');
-const escPeriodPattern = new RegExp(escPeriod, 'g');
-const slashPattern = /\\\\/g;
-const openPattern = /\\{/g;
-const closePattern = /\\}/g;
-const commaPattern = /\\,/g;
-const periodPattern = /\\./g;
-const EXPANSION_MAX = 100_000;
-function numeric(str) {
- return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
-}
-function escapeBraces(str) {
- return str
- .replace(slashPattern, escSlash)
- .replace(openPattern, escOpen)
- .replace(closePattern, escClose)
- .replace(commaPattern, escComma)
- .replace(periodPattern, escPeriod);
-}
-function unescapeBraces(str) {
- return str
- .replace(escSlashPattern, '\\')
- .replace(escOpenPattern, '{')
- .replace(escClosePattern, '}')
- .replace(escCommaPattern, ',')
- .replace(escPeriodPattern, '.');
-}
-/**
- * Basically just str.split(","), but handling cases
- * where we have nested braced sections, which should be
- * treated as individual members, like {a,{b,c},d}
- */
-function parseCommaParts(str) {
- if (!str) {
- return [''];
- }
- const parts = [];
- const m = balanced('{', '}', str);
- if (!m) {
- return str.split(',');
- }
- const { pre, body, post } = m;
- const p = pre.split(',');
- p[p.length - 1] += '{' + body + '}';
- const postParts = parseCommaParts(post);
- if (post.length) {
- ;
- p[p.length - 1] += postParts.shift();
- p.push.apply(p, postParts);
- }
- parts.push.apply(parts, p);
- return parts;
-}
-function expand(str, options = {}) {
- if (!str) {
- return [];
- }
- const { max = EXPANSION_MAX } = options;
- // I don't know why Bash 4.3 does this, but it does.
- // Anything starting with {} will have the first two bytes preserved
- // but *only* at the top level, so {},a}b will not expand to anything,
- // but a{},b}c will be expanded to [a}c,abc].
- // One could argue that this is a bug in Bash, but since the goal of
- // this module is to match Bash's rules, we escape a leading {}
- if (str.slice(0, 2) === '{}') {
- str = '\\{\\}' + str.slice(2);
- }
- return expand_(escapeBraces(str), max, true).map(unescapeBraces);
-}
-function embrace(str) {
- return '{' + str + '}';
-}
-function isPadded(el) {
- return /^-?0\d/.test(el);
-}
-function lte(i, y) {
- return i <= y;
-}
-function gte(i, y) {
- return i >= y;
-}
-function expand_(str, max, isTop) {
- /** @type {string[]} */
- const expansions = [];
- const m = balanced('{', '}', str);
- if (!m)
- return [str];
- // no need to expand pre, since it is guaranteed to be free of brace-sets
- const pre = m.pre;
- const post = m.post.length ? expand_(m.post, max, false) : [''];
- if (/\$$/.test(m.pre)) {
- for (let k = 0; k < post.length && k < max; k++) {
- const expansion = pre + '{' + m.body + '}' + post[k];
- expansions.push(expansion);
- }
- }
- else {
- const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
- const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
- const isSequence = isNumericSequence || isAlphaSequence;
- const isOptions = m.body.indexOf(',') >= 0;
- if (!isSequence && !isOptions) {
- // {a},b}
- if (m.post.match(/,(?!,).*\}/)) {
- str = m.pre + '{' + m.body + escClose + m.post;
- return expand_(str, max, true);
- }
- return [str];
- }
- let n;
- if (isSequence) {
- n = m.body.split(/\.\./);
- }
- else {
- n = parseCommaParts(m.body);
- if (n.length === 1 && n[0] !== undefined) {
- // x{{a,b}}y ==> x{a}y x{b}y
- n = expand_(n[0], max, false).map(embrace);
- //XXX is this necessary? Can't seem to hit it in tests.
- /* c8 ignore start */
- if (n.length === 1) {
- return post.map(p => m.pre + n[0] + p);
- }
- /* c8 ignore stop */
- }
- }
- // at this point, n is the parts, and we know it's not a comma set
- // with a single entry.
- let N;
- if (isSequence && n[0] !== undefined && n[1] !== undefined) {
- const x = numeric(n[0]);
- const y = numeric(n[1]);
- const width = Math.max(n[0].length, n[1].length);
- let incr = n.length === 3 && n[2] !== undefined ? Math.abs(numeric(n[2])) : 1;
- let test = lte;
- const reverse = y < x;
- if (reverse) {
- incr *= -1;
- test = gte;
- }
- const pad = n.some(isPadded);
- N = [];
- for (let i = x; test(i, y); i += incr) {
- let c;
- if (isAlphaSequence) {
- c = String.fromCharCode(i);
- if (c === '\\') {
- c = '';
- }
- }
- else {
- c = String(i);
- if (pad) {
- const need = width - c.length;
- if (need > 0) {
- const z = new Array(need + 1).join('0');
- if (i < 0) {
- c = '-' + z + c.slice(1);
- }
- else {
- c = z + c;
- }
- }
- }
- }
- N.push(c);
- }
- }
- else {
- N = [];
- for (let j = 0; j < n.length; j++) {
- N.push.apply(N, expand_(n[j], max, false));
- }
- }
- for (let j = 0; j < N.length; j++) {
- for (let k = 0; k < post.length && expansions.length < max; k++) {
- const expansion = pre + N[j] + post[k];
- if (!isTop || isSequence || expansion) {
- expansions.push(expansion);
- }
- }
- }
- }
- return expansions;
-}
-//# sourceMappingURL=index.js.map
-;// CONCATENATED MODULE: ./node_modules/minimatch/dist/esm/assert-valid-pattern.js
-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');
- }
-};
-//# sourceMappingURL=assert-valid-pattern.js.map
-;// CONCATENATED MODULE: ./node_modules/minimatch/dist/esm/brace-expressions.js
-// translate the various posix character classes into unicode properties
-// this works across all unicode locales
-// { : [, /u flag required, negated]
-const posixClasses = {
- '[:alnum:]': ['\\p{L}\\p{Nl}\\p{Nd}', true],
- '[:alpha:]': ['\\p{L}\\p{Nl}', true],
- '[:ascii:]': ['\\x' + '00-\\x' + '7f', false],
- '[:blank:]': ['\\p{Zs}\\t', true],
- '[:cntrl:]': ['\\p{Cc}', true],
- '[:digit:]': ['\\p{Nd}', true],
- '[:graph:]': ['\\p{Z}\\p{C}', true, true],
- '[:lower:]': ['\\p{Ll}', true],
- '[:print:]': ['\\p{C}', true],
- '[:punct:]': ['\\p{P}', true],
- '[:space:]': ['\\p{Z}\\t\\r\\n\\v\\f', true],
- '[:upper:]': ['\\p{Lu}', true],
- '[:word:]': ['\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}', true],
- '[:xdigit:]': ['A-Fa-f0-9', false],
-};
-// only need to escape a few things inside of brace expressions
-// escapes: [ \ ] -
-const braceEscape = (s) => s.replace(/[[\]\\-]/g, '\\$&');
-// escape all regexp magic characters
-const regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
-// everything has already been escaped, we just have to join
-const rangesToString = (ranges) => ranges.join('');
-// takes a glob string at a posix brace expression, and returns
-// an equivalent regular expression source, and boolean indicating
-// whether the /u flag needs to be applied, and the number of chars
-// consumed to parse the character class.
-// This also removes out of order ranges, and returns ($.) if the
-// entire class just no good.
-const parseClass = (glob, position) => {
- const pos = position;
- /* c8 ignore start */
- if (glob.charAt(pos) !== '[') {
- throw new Error('not in a brace expression');
- }
- /* c8 ignore stop */
- const ranges = [];
- const negs = [];
- let i = pos + 1;
- let sawStart = false;
- let uflag = false;
- let escaping = false;
- let negate = false;
- let endPos = pos;
- let rangeStart = '';
- WHILE: while (i < glob.length) {
- const c = glob.charAt(i);
- if ((c === '!' || c === '^') && i === pos + 1) {
- negate = true;
- i++;
- continue;
- }
- if (c === ']' && sawStart && !escaping) {
- endPos = i + 1;
- break;
- }
- sawStart = true;
- if (c === '\\') {
- if (!escaping) {
- escaping = true;
- i++;
- continue;
- }
- // escaped \ char, fall through and treat like normal char
- }
- if (c === '[' && !escaping) {
- // either a posix class, a collation equivalent, or just a [
- for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {
- if (glob.startsWith(cls, i)) {
- // invalid, [a-[] is fine, but not [a-[:alpha]]
- if (rangeStart) {
- return ['$.', false, glob.length - pos, true];
- }
- i += cls.length;
- if (neg)
- negs.push(unip);
- else
- ranges.push(unip);
- uflag = uflag || u;
- continue WHILE;
- }
- }
- }
- // now it's just a normal character, effectively
- escaping = false;
- if (rangeStart) {
- // throw this range away if it's not valid, but others
- // can still match.
- if (c > rangeStart) {
- ranges.push(braceEscape(rangeStart) + '-' + braceEscape(c));
- }
- else if (c === rangeStart) {
- ranges.push(braceEscape(c));
- }
- rangeStart = '';
- i++;
- continue;
- }
- // now might be the start of a range.
- // can be either c-d or c-] or c] or c] at this point
- if (glob.startsWith('-]', i + 1)) {
- ranges.push(braceEscape(c + '-'));
- i += 2;
- continue;
- }
- if (glob.startsWith('-', i + 1)) {
- rangeStart = c;
- i += 2;
- continue;
- }
- // not the start of a range, just a single character
- ranges.push(braceEscape(c));
- i++;
- }
- if (endPos < i) {
- // didn't see the end of the class, not a valid class,
- // but might still be valid as a literal match.
- return ['', false, 0, false];
- }
- // if we got no ranges and no negates, then we have a range that
- // cannot possibly match anything, and that poisons the whole glob
- if (!ranges.length && !negs.length) {
- return ['$.', false, glob.length - pos, true];
- }
- // if we got one positive range, and it's a single character, then that's
- // not actually a magic pattern, it's just that one literal character.
- // we should not treat that as "magic", we should just return the literal
- // character. [_] is a perfectly valid way to escape glob magic chars.
- if (negs.length === 0 &&
- ranges.length === 1 &&
- /^\\?.$/.test(ranges[0]) &&
- !negate) {
- const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0];
- return [regexpEscape(r), false, endPos - pos, false];
- }
- const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']';
- const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']';
- const comb = ranges.length && negs.length ? '(' + sranges + '|' + snegs + ')'
- : ranges.length ? sranges
- : snegs;
- return [comb, uflag, endPos - pos, true];
-};
-//# sourceMappingURL=brace-expressions.js.map
-;// CONCATENATED MODULE: ./node_modules/minimatch/dist/esm/unescape.js
-/**
- * Un-escape a string that has been escaped with {@link escape}.
- *
- * If the {@link MinimatchOptions.windowsPathsNoEscape} option is used, then
- * square-bracket escapes are removed, but not backslash escapes.
- *
- * For example, it will turn the string `'[*]'` into `*`, but it will not
- * turn `'\\*'` into `'*'`, because `\` is a path separator in
- * `windowsPathsNoEscape` mode.
- *
- * When `windowsPathsNoEscape` is not set, then both square-bracket escapes and
- * backslash escapes are removed.
- *
- * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
- * or unescaped.
- *
- * When `magicalBraces` is not set, escapes of braces (`{` and `}`) will not be
- * unescaped.
- */
-const unescape_unescape = (s, { windowsPathsNoEscape = false, magicalBraces = true, } = {}) => {
- if (magicalBraces) {
- return windowsPathsNoEscape ?
- s.replace(/\[([^\/\\])\]/g, '$1')
- : s
- .replace(/((?!\\).|^)\[([^\/\\])\]/g, '$1$2')
- .replace(/\\([^\/])/g, '$1');
- }
- return windowsPathsNoEscape ?
- s.replace(/\[([^\/\\{}])\]/g, '$1')
- : s
- .replace(/((?!\\).|^)\[([^\/\\{}])\]/g, '$1$2')
- .replace(/\\([^\/{}])/g, '$1');
-};
-//# sourceMappingURL=unescape.js.map
-;// CONCATENATED MODULE: ./node_modules/minimatch/dist/esm/ast.js
-// parse a single path portion
-var _a;
-
-
-const types = new Set(['!', '?', '+', '*', '@']);
-const isExtglobType = (c) => types.has(c);
-const isExtglobAST = (c) => isExtglobType(c.type);
-// Map of which extglob types can adopt the children of a nested extglob
-//
-// anything but ! can adopt a matching type:
-// +(a|+(b|c)|d) => +(a|b|c|d)
-// *(a|*(b|c)|d) => *(a|b|c|d)
-// @(a|@(b|c)|d) => @(a|b|c|d)
-// ?(a|?(b|c)|d) => ?(a|b|c|d)
-//
-// * can adopt anything, because 0 or repetition is allowed
-// *(a|?(b|c)|d) => *(a|b|c|d)
-// *(a|+(b|c)|d) => *(a|b|c|d)
-// *(a|@(b|c)|d) => *(a|b|c|d)
-//
-// + can adopt @, because 1 or repetition is allowed
-// +(a|@(b|c)|d) => +(a|b|c|d)
-//
-// + and @ CANNOT adopt *, because 0 would be allowed
-// +(a|*(b|c)|d) => would match "", on *(b|c)
-// @(a|*(b|c)|d) => would match "", on *(b|c)
-//
-// + and @ CANNOT adopt ?, because 0 would be allowed
-// +(a|?(b|c)|d) => would match "", on ?(b|c)
-// @(a|?(b|c)|d) => would match "", on ?(b|c)
-//
-// ? can adopt @, because 0 or 1 is allowed
-// ?(a|@(b|c)|d) => ?(a|b|c|d)
-//
-// ? and @ CANNOT adopt * or +, because >1 would be allowed
-// ?(a|*(b|c)|d) => would match bbb on *(b|c)
-// @(a|*(b|c)|d) => would match bbb on *(b|c)
-// ?(a|+(b|c)|d) => would match bbb on +(b|c)
-// @(a|+(b|c)|d) => would match bbb on +(b|c)
-//
-// ! CANNOT adopt ! (nothing else can either)
-// !(a|!(b|c)|d) => !(a|b|c|d) would fail to match on b (not not b|c)
-//
-// ! can adopt @
-// !(a|@(b|c)|d) => !(a|b|c|d)
-//
-// ! CANNOT adopt *
-// !(a|*(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed
-//
-// ! CANNOT adopt +
-// !(a|+(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed
-//
-// ! CANNOT adopt ?
-// x!(a|?(b|c)|d) => x!(a|b|c|d) would fail to match "x"
-const adoptionMap = new Map([
- ['!', ['@']],
- ['?', ['?', '@']],
- ['@', ['@']],
- ['*', ['*', '+', '?', '@']],
- ['+', ['+', '@']],
-]);
-// nested extglobs that can be adopted in, but with the addition of
-// a blank '' element.
-const adoptionWithSpaceMap = new Map([
- ['!', ['?']],
- ['@', ['?']],
- ['+', ['?', '*']],
-]);
-// union of the previous two maps
-const adoptionAnyMap = new Map([
- ['!', ['?', '@']],
- ['?', ['?', '@']],
- ['@', ['?', '@']],
- ['*', ['*', '+', '?', '@']],
- ['+', ['+', '@', '?', '*']],
-]);
-// Extglobs that can take over their parent if they are the only child
-// the key is parent, value maps child to resulting extglob parent type
-// '@' is omitted because it's a special case. An `@` extglob with a single
-// member can always be usurped by that subpattern.
-const usurpMap = new Map([
- ['!', new Map([['!', '@']])],
- [
- '?',
- new Map([
- ['*', '*'],
- ['+', '*'],
- ]),
- ],
- [
- '@',
- new Map([
- ['!', '!'],
- ['?', '?'],
- ['@', '@'],
- ['*', '*'],
- ['+', '+'],
- ]),
- ],
- [
- '+',
- new Map([
- ['?', '*'],
- ['*', '*'],
- ]),
- ],
-]);
-// Patterns that get prepended to bind to the start of either the
-// entire string, or just a single path portion, to prevent dots
-// and/or traversal patterns, when needed.
-// Exts don't need the ^ or / bit, because the root binds that already.
-const startNoTraversal = '(?!(?:^|/)\\.\\.?(?:$|/))';
-const startNoDot = '(?!\\.)';
-// characters that indicate a start of pattern needs the "no dots" bit,
-// because a dot *might* be matched. ( is not in the list, because in
-// the case of a child extglob, it will handle the prevention itself.
-const addPatternStart = new Set(['[', '.']);
-// cases where traversal is A-OK, no dot prevention needed
-const justDots = new Set(['..', '.']);
-const reSpecials = new Set('().*{}+?[]^$\\!');
-const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
-// any single thing other than /
-const qmark = '[^/]';
-// * => any number of characters
-const star = qmark + '*?';
-// use + when we need to ensure that *something* matches, because the * is
-// the only thing in the path portion.
-const starNoEmpty = qmark + '+?';
-// remove the \ chars that we added if we end up doing a nonmagic compare
-// const deslash = (s: string) => s.replace(/\\(.)/g, '$1')
-let ID = 0;
-class AST {
- type;
- #root;
- #hasMagic;
- #uflag = false;
- #parts = [];
- #parent;
- #parentIndex;
- #negs;
- #filledNegs = false;
- #options;
- #toString;
- // set to true if it's an extglob with no children
- // (which really means one child of '')
- #emptyExt = false;
- id = ++ID;
- get depth() {
- return (this.#parent?.depth ?? -1) + 1;
- }
- [Symbol.for('nodejs.util.inspect.custom')]() {
- return {
- '@@type': 'AST',
- id: this.id,
- type: this.type,
- root: this.#root.id,
- parent: this.#parent?.id,
- depth: this.depth,
- partsLength: this.#parts.length,
- parts: this.#parts,
- };
- }
- constructor(type, parent, options = {}) {
- this.type = type;
- // extglobs are inherently magical
- if (type)
- this.#hasMagic = true;
- 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;
- }
- get hasMagic() {
- /* c8 ignore start */
- if (this.#hasMagic !== undefined)
- return this.#hasMagic;
- /* c8 ignore stop */
- for (const p of this.#parts) {
- if (typeof p === 'string')
- continue;
- if (p.type || p.hasMagic)
- return (this.#hasMagic = true);
- }
- // note: will be undefined until we generate the regexp src and find out
- return this.#hasMagic;
- }
- // reconstructs the pattern
- toString() {
- if (this.#toString !== undefined)
- return this.#toString;
- if (!this.type) {
- return (this.#toString = this.#parts.map(p => String(p)).join(''));
- }
- else {
- return (this.#toString =
- this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')');
- }
- }
- #fillNegs() {
- /* c8 ignore start */
- if (this !== this.#root)
- throw new Error('should only call on root');
- if (this.#filledNegs)
- return this;
- /* c8 ignore stop */
- // call toString() once to fill this out
- this.toString();
- 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 _a && 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()
- .map(p => (typeof p === 'string' ? p : p.toJSON()))
- : [this.type, ...this.#parts.map(p => p.toJSON())];
- 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;
- if (this.#parentIndex === 0)
- return true;
- // if everything AHEAD of this is a negation, then it's still the "start"
- const p = this.#parent;
- for (let i = 0; i < this.#parentIndex; i++) {
- const pp = p.#parts[i];
- if (!(pp instanceof _a && pp.type === '!')) {
- return false;
- }
- }
- return true;
- }
- 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();
- // if not root, it'll always have a parent
- /* c8 ignore start */
- const pl = this.#parent ? this.#parent.#parts.length : 0;
- /* c8 ignore stop */
- return this.#parentIndex === pl - 1;
- }
- copyIn(part) {
- if (typeof part === 'string')
- this.push(part);
- else
- this.push(part.clone(this));
- }
- clone(parent) {
- const c = new _a(this.type, parent);
- for (const p of this.#parts) {
- c.copyIn(p);
- }
- return c;
- }
- static #parseAST(str, ast, pos, opt, extDepth) {
- const maxDepth = opt.maxExtglobRecursion ?? 2;
- let escaping = false;
- let inBrace = false;
- let braceStart = -1;
- let braceNeg = 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 (inBrace) {
- if (i === braceStart + 1) {
- if (c === '^' || c === '!') {
- braceNeg = true;
- }
- }
- else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {
- inBrace = false;
- }
- acc += c;
- continue;
- }
- else if (c === '[') {
- inBrace = true;
- braceStart = i;
- braceNeg = false;
- acc += c;
- continue;
- }
- // we don't have to check for adoption here, because that's
- // done at the other recursion point.
- const doRecurse = !opt.noext &&
- isExtglobType(c) &&
- str.charAt(i) === '(' &&
- extDepth <= maxDepth;
- if (doRecurse) {
- ast.push(acc);
- acc = '';
- const ext = new _a(c, ast);
- i = _a.#parseAST(str, ext, i, opt, extDepth + 1);
- 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 _a(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 (inBrace) {
- if (i === braceStart + 1) {
- if (c === '^' || c === '!') {
- braceNeg = true;
- }
- }
- else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {
- inBrace = false;
- }
- acc += c;
- continue;
- }
- else if (c === '[') {
- inBrace = true;
- braceStart = i;
- braceNeg = false;
- acc += c;
- continue;
- }
- const doRecurse = !opt.noext &&
- isExtglobType(c) &&
- str.charAt(i) === '(' &&
- /* c8 ignore start - the maxDepth is sufficient here */
- (extDepth <= maxDepth || (ast && ast.#canAdoptType(c)));
- /* c8 ignore stop */
- if (doRecurse) {
- const depthAdd = ast && ast.#canAdoptType(c) ? 0 : 1;
- part.push(acc);
- acc = '';
- const ext = new _a(c, part);
- part.push(ext);
- i = _a.#parseAST(str, ext, i, opt, extDepth + depthAdd);
- continue;
- }
- if (c === '|') {
- part.push(acc);
- acc = '';
- parts.push(part);
- part = new _a(null, ast);
- continue;
- }
- if (c === ')') {
- if (acc === '' && ast.#parts.length === 0) {
- ast.#emptyExt = true;
- }
- part.push(acc);
- acc = '';
- ast.push(...parts, part);
- return i;
- }
- acc += c;
- }
- // unfinished extglob
- // if we got here, it was a malformed extglob! not an extglob, but
- // maybe something else in there.
- ast.type = null;
- ast.#hasMagic = undefined;
- ast.#parts = [str.substring(pos - 1)];
- return i;
- }
- #canAdoptWithSpace(child) {
- return this.#canAdopt(child, adoptionWithSpaceMap);
- }
- #canAdopt(child, map = adoptionMap) {
- if (!child ||
- typeof child !== 'object' ||
- child.type !== null ||
- child.#parts.length !== 1 ||
- this.type === null) {
- return false;
- }
- const gc = child.#parts[0];
- if (!gc || typeof gc !== 'object' || gc.type === null) {
- return false;
- }
- return this.#canAdoptType(gc.type, map);
- }
- #canAdoptType(c, map = adoptionAnyMap) {
- return !!map.get(this.type)?.includes(c);
- }
- #adoptWithSpace(child, index) {
- const gc = child.#parts[0];
- const blank = new _a(null, gc, this.options);
- blank.#parts.push('');
- gc.push(blank);
- this.#adopt(child, index);
- }
- #adopt(child, index) {
- const gc = child.#parts[0];
- this.#parts.splice(index, 1, ...gc.#parts);
- for (const p of gc.#parts) {
- if (typeof p === 'object')
- p.#parent = this;
- }
- this.#toString = undefined;
- }
- #canUsurpType(c) {
- const m = usurpMap.get(this.type);
- return !!(m?.has(c));
- }
- #canUsurp(child) {
- if (!child ||
- typeof child !== 'object' ||
- child.type !== null ||
- child.#parts.length !== 1 ||
- this.type === null ||
- this.#parts.length !== 1) {
- return false;
- }
- const gc = child.#parts[0];
- if (!gc || typeof gc !== 'object' || gc.type === null) {
- return false;
- }
- return this.#canUsurpType(gc.type);
- }
- #usurp(child) {
- const m = usurpMap.get(this.type);
- const gc = child.#parts[0];
- const nt = m?.get(gc.type);
- /* c8 ignore start - impossible */
- if (!nt)
- return false;
- /* c8 ignore stop */
- this.#parts = gc.#parts;
- for (const p of this.#parts) {
- if (typeof p === 'object') {
- p.#parent = this;
- }
- }
- this.type = nt;
- this.#toString = undefined;
- this.#emptyExt = false;
- }
- static fromGlob(pattern, options = {}) {
- const ast = new _a(null, undefined, options);
- _a.#parseAST(pattern, ast, 0, options, 0);
- return ast;
- }
- // returns the regular expression if there's magic, or the unescaped
- // string if not.
- toMMPattern() {
- // should only be called on root
- /* c8 ignore start */
- if (this !== this.#root)
- return this.#root.toMMPattern();
- /* c8 ignore stop */
- const glob = this.toString();
- const [re, body, hasMagic, uflag] = this.toRegExpSource();
- // if we're in nocase mode, and not nocaseMagicOnly, then we do
- // still need a regular expression if we have to case-insensitively
- // match capital/lowercase characters.
- const anyMagic = hasMagic ||
- this.#hasMagic ||
- (this.#options.nocase &&
- !this.#options.nocaseMagicOnly &&
- glob.toUpperCase() !== glob.toLowerCase());
- if (!anyMagic) {
- return body;
- }
- const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : '');
- return Object.assign(new RegExp(`^${re}$`, flags), {
- _src: re,
- _glob: glob,
- });
- }
- get options() {
- return this.#options;
- }
- // returns the string match, the regexp source, whether there's magic
- // in the regexp (so a regular expression is required) and whether or
- // not the uflag is needed for the regular expression (for posix classes)
- // TODO: instead of injecting the start/end at this point, just return
- // the BODY of the regexp, along with the start/end portions suitable
- // for binding the start/end in either a joined full-path makeRe context
- // (where we bind to (^|/), or a standalone matchPart context (where
- // we bind to ^, and not /). Otherwise slashes get duped!
- //
- // In part-matching mode, the start is:
- // - if not isStart: nothing
- // - if traversal possible, but not allowed: ^(?!\.\.?$)
- // - if dots allowed or not possible: ^
- // - if dots possible and not allowed: ^(?!\.)
- // end is:
- // - if not isEnd(): nothing
- // - else: $
- //
- // In full-path matching mode, we put the slash at the START of the
- // pattern, so start is:
- // - if first pattern: same as part-matching mode
- // - if not isStart(): nothing
- // - if traversal possible, but not allowed: /(?!\.\.?(?:$|/))
- // - if dots allowed or not possible: /
- // - if dots possible and not allowed: /(?!\.)
- // end is:
- // - if last pattern, same as part-matching mode
- // - else nothing
- //
- // Always put the (?:$|/) on negated tails, though, because that has to be
- // there to bind the end of the negated pattern portion, and it's easier to
- // just stick it in now rather than try to inject it later in the middle of
- // the pattern.
- //
- // We can just always return the same end, and leave it up to the caller
- // to know whether it's going to be used joined or in parts.
- // And, if the start is adjusted slightly, can do the same there:
- // - if not isStart: nothing
- // - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$)
- // - if dots allowed or not possible: (?:/|^)
- // - if dots possible and not allowed: (?:/|^)(?!\.)
- //
- // But it's better to have a simpler binding without a conditional, for
- // performance, so probably better to return both start options.
- //
- // Then the caller just ignores the end if it's not the first pattern,
- // and the start always gets applied.
- //
- // But that's always going to be $ if it's the ending pattern, or nothing,
- // so the caller can just attach $ at the end of the pattern when building.
- //
- // So the todo is:
- // - better detect what kind of start is needed
- // - return both flavors of starting pattern
- // - attach $ at the end of the pattern when creating the actual RegExp
- //
- // Ah, but wait, no, that all only applies to the root when the first pattern
- // is not an extglob. If the first pattern IS an extglob, then we need all
- // that dot prevention biz to live in the extglob portions, because eg
- // +(*|.x*) can match .xy but not .yx.
- //
- // So, return the two flavors if it's #root and the first child is not an
- // AST, otherwise leave it to the child AST to handle it, and there,
- // use the (?:^|/) style of start binding.
- //
- // Even simplified further:
- // - Since the start for a join is eg /(?!\.) and the start for a part
- // is ^(?!\.), we can just prepend (?!\.) to the pattern (either root
- // or start or whatever) and prepend ^ or / at the Regexp construction.
- toRegExpSource(allowDot) {
- const dot = allowDot ?? !!this.#options.dot;
- if (this.#root === this) {
- this.#flatten();
- this.#fillNegs();
- }
- if (!isExtglobAST(this)) {
- const noEmpty = this.isStart() &&
- this.isEnd() &&
- !this.#parts.some(s => typeof s !== 'string');
- const src = this.#parts
- .map(p => {
- const [re, _, hasMagic, uflag] = typeof p === 'string' ?
- _a.#parseGlob(p, this.#hasMagic, noEmpty)
- : p.toRegExpSource(allowDot);
- this.#hasMagic = this.#hasMagic || hasMagic;
- this.#uflag = this.#uflag || uflag;
- return re;
- })
- .join('');
- let start = '';
- if (this.isStart()) {
- if (typeof this.#parts[0] === 'string') {
- // this is the string that will match the start of the pattern,
- // so we need to protect against dots and such.
- // '.' and '..' cannot match unless the pattern is that exactly,
- // even if it starts with . or dot:true is set.
- const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]);
- if (!dotTravAllowed) {
- const aps = addPatternStart;
- // check if we have a possibility of matching . or ..,
- // and prevent that.
- const needNoTrav =
- // dots are allowed, and the pattern starts with [ or .
- (dot && aps.has(src.charAt(0))) ||
- // the pattern starts with \., and then [ or .
- (src.startsWith('\\.') && aps.has(src.charAt(2))) ||
- // the pattern starts with \.\., and then [ or .
- (src.startsWith('\\.\\.') && aps.has(src.charAt(4)));
- // no need to prevent dots if it can't match a dot, or if a
- // sub-pattern will be preventing it anyway.
- const needNoDot = !dot && !allowDot && aps.has(src.charAt(0));
- start =
- needNoTrav ? startNoTraversal
- : needNoDot ? startNoDot
- : '';
- }
- }
- }
- // append the "end of path portion" pattern to negation tails
- let end = '';
- if (this.isEnd() &&
- this.#root.#filledNegs &&
- this.#parent?.type === '!') {
- end = '(?:$|\\/)';
- }
- const final = start + src + end;
- return [
- final,
- unescape_unescape(src),
- (this.#hasMagic = !!this.#hasMagic),
- this.#uflag,
- ];
- }
- // We need to calculate the body *twice* if it's a repeat pattern
- // at the start, once in nodot mode, then again in dot mode, so a
- // pattern like *(?) can match 'x.y'
- const repeated = this.type === '*' || this.type === '+';
- // some kind of extglob
- const start = this.type === '!' ? '(?:(?!(?:' : '(?:';
- let body = this.#partsToRegExp(dot);
- if (this.isStart() && this.isEnd() && !body && this.type !== '!') {
- // invalid extglob, has to at least be *something* present, if it's
- // the entire path portion.
- const s = this.toString();
- const me = this;
- me.#parts = [s];
- me.type = null;
- me.#hasMagic = undefined;
- return [s, unescape_unescape(this.toString()), false, false];
- }
- let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ?
- ''
- : this.#partsToRegExp(true);
- if (bodyDotAllowed === body) {
- bodyDotAllowed = '';
- }
- if (bodyDotAllowed) {
- body = `(?:${body})(?:${bodyDotAllowed})*?`;
- }
- // an empty !() is exactly equivalent to a starNoEmpty
- let final = '';
- if (this.type === '!' && this.#emptyExt) {
- final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty;
- }
- else {
- const close = this.type === '!' ?
- // !() must match something,but !(x) can match ''
- '))' +
- (this.isStart() && !dot && !allowDot ? startNoDot : '') +
- star +
- ')'
- : this.type === '@' ? ')'
- : this.type === '?' ? ')?'
- : this.type === '+' && bodyDotAllowed ? ')'
- : this.type === '*' && bodyDotAllowed ? `)?`
- : `)${this.type}`;
- final = start + body + close;
- }
- return [
- final,
- unescape_unescape(body),
- (this.#hasMagic = !!this.#hasMagic),
- this.#uflag,
- ];
- }
- #flatten() {
- if (!isExtglobAST(this)) {
- for (const p of this.#parts) {
- if (typeof p === 'object') {
- p.#flatten();
- }
- }
- }
- else {
- // do up to 10 passes to flatten as much as possible
- let iterations = 0;
- let done = false;
- do {
- done = true;
- for (let i = 0; i < this.#parts.length; i++) {
- const c = this.#parts[i];
- if (typeof c === 'object') {
- c.#flatten();
- if (this.#canAdopt(c)) {
- done = false;
- this.#adopt(c, i);
- }
- else if (this.#canAdoptWithSpace(c)) {
- done = false;
- this.#adoptWithSpace(c, i);
- }
- else if (this.#canUsurp(c)) {
- done = false;
- this.#usurp(c);
- }
- }
- }
- } while (!done && ++iterations < 10);
- }
- this.#toString = undefined;
- }
- #partsToRegExp(dot) {
- return this.#parts
- .map(p => {
- // extglob ASTs should only contain parent ASTs
- /* c8 ignore start */
- if (typeof p === 'string') {
- throw new Error('string type in extglob ast??');
- }
- /* c8 ignore stop */
- // can ignore hasMagic, because extglobs are already always magic
- const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot);
- this.#uflag = this.#uflag || uflag;
- return re;
- })
- .filter(p => !(this.isStart() && this.isEnd()) || !!p)
- .join('|');
- }
- static #parseGlob(glob, hasMagic, noEmpty = false) {
- let escaping = false;
- let re = '';
- let uflag = false;
- // multiple stars that aren't globstars coalesce into one *
- let inStar = 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 (inStar)
- continue;
- inStar = true;
- re += noEmpty && /^[*]+$/.test(glob) ? starNoEmpty : star;
- hasMagic = true;
- continue;
- }
- else {
- inStar = false;
- }
- 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 += qmark;
- hasMagic = true;
- continue;
- }
- re += regExpEscape(c);
- }
- return [re, unescape_unescape(glob), !!hasMagic, uflag];
- }
-}
-_a = AST;
-//# sourceMappingURL=ast.js.map
-;// CONCATENATED MODULE: ./node_modules/minimatch/dist/esm/escape.js
-/**
- * Escape all magic characters in a glob pattern.
- *
- * If the {@link MinimatchOptions.windowsPathsNoEscape}
- * option is used, then characters are escaped by wrapping in `[]`, because
- * a magic character wrapped in a character class can only be satisfied by
- * that exact character. In this mode, `\` is _not_ escaped, because it is
- * not interpreted as a magic character, but instead as a path separator.
- *
- * If the {@link MinimatchOptions.magicalBraces} option is used,
- * then braces (`{` and `}`) will be escaped.
- */
-const escape_escape = (s, { windowsPathsNoEscape = false, magicalBraces = false, } = {}) => {
- // don't need to escape +@! because we escape the parens
- // that make those magic, and escaping ! as [!] isn't valid,
- // because [!]] is a valid glob class meaning not ']'.
- if (magicalBraces) {
- return windowsPathsNoEscape ?
- s.replace(/[?*()[\]{}]/g, '[$&]')
- : s.replace(/[?*()[\]\\{}]/g, '\\$&');
- }
- return windowsPathsNoEscape ?
- s.replace(/[?*()[\]]/g, '[$&]')
- : s.replace(/[?*()[\]\\]/g, '\\$&');
-};
-//# sourceMappingURL=escape.js.map
-;// CONCATENATED MODULE: ./node_modules/minimatch/dist/esm/index.js
-
-
-
-
-
-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);
-};
-// 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 defaultPlatform = (typeof process === 'object' && process ?
- (typeof process.env === 'object' &&
- process.env &&
- process.env.__MINIMATCH_TESTING_PLATFORM__) ||
- process.platform
- : 'posix');
-const esm_path = {
- win32: { sep: '\\' },
- posix: { sep: '/' },
-};
-/* c8 ignore stop */
-const sep = defaultPlatform === 'win32' ? esm_path.win32.sep : esm_path.posix.sep;
-minimatch.sep = sep;
-const GLOBSTAR = Symbol('globstar **');
-minimatch.GLOBSTAR = GLOBSTAR;
-// any single thing other than /
-// don't need to escape / when using new RegExp()
-const esm_qmark = '[^/]';
-// * => any number of characters
-const esm_star = esm_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 = '(?:(?!(?:\\/|^)\\.).)*?';
-const filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options);
-minimatch.filter = filter;
-const ext = (a, b = {}) => Object.assign({}, a, b);
-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;
- }
- },
- AST: class AST extends orig.AST {
- /* c8 ignore start */
- constructor(type, parent, options = {}) {
- super(type, parent, ext(def, options));
- }
- /* c8 ignore stop */
- static fromGlob(pattern, options = {}) {
- return orig.AST.fromGlob(pattern, ext(def, options));
- }
- },
- unescape: (s, options = {}) => orig.unescape(s, ext(def, options)),
- escape: (s, options = {}) => orig.escape(s, ext(def, options)),
- 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
-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, { max: options.braceExpandMax });
-};
-minimatch.braceExpand = braceExpand;
-// 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 makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
-minimatch.makeRe = 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;
-};
-minimatch.match = match;
-// replace stuff like \* with *
-const globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/;
-const esm_regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
-class Minimatch {
- options;
- set;
- pattern;
- windowsPathsNoEscape;
- nonegate;
- negate;
- comment;
- empty;
- preserveMultipleSlashes;
- partial;
- globSet;
- globParts;
- nocase;
- isWindows;
- platform;
- windowsNoMagicRoot;
- maxGlobstarRecursion;
- regexp;
- constructor(pattern, options = {}) {
- assertValidPattern(pattern);
- options = options || {};
- this.options = options;
- this.maxGlobstarRecursion = options.maxGlobstarRecursion ?? 200;
- this.pattern = pattern;
- this.platform = options.platform || defaultPlatform;
- this.isWindows = this.platform === 'win32';
- // avoid the annoying deprecation flag lol
- const awe = ('allowWindow' + 'sEscape');
- this.windowsPathsNoEscape =
- !!options.windowsPathsNoEscape || options[awe] === 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.nocase = !!this.options.nocase;
- this.windowsNoMagicRoot =
- options.windowsNoMagicRoot !== undefined ?
- options.windowsNoMagicRoot
- : !!(this.isWindows && this.nocase);
- this.globSet = [];
- this.globParts = [];
- this.set = [];
- // make the set of regexps etc.
- this.make();
- }
- hasMagic() {
- if (this.options.magicalBraces && this.set.length > 1) {
- return true;
- }
- for (const pattern of this.set) {
- for (const part of pattern) {
- if (typeof part !== 'string')
- return true;
- }
- }
- return false;
- }
- 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 = [...new Set(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
- //
- // First, we preprocess to make the glob pattern sets a bit simpler
- // and deduped. There are some perf-killing patterns that can cause
- // problems with a glob walk, but we can simplify them down a bit.
- const rawGlobParts = this.globSet.map(s => this.slashSplit(s));
- this.globParts = this.preprocess(rawGlobParts);
- this.debug(this.pattern, this.globParts);
- // glob --> regexps
- let set = this.globParts.map((s, _, __) => {
- if (this.isWindows && this.windowsNoMagicRoot) {
- // check if it's a drive or unc path.
- const isUNC = s[0] === '' &&
- s[1] === '' &&
- (s[2] === '?' || !globMagic.test(s[2])) &&
- !globMagic.test(s[3]);
- const isDrive = /^[a-z]:/i.test(s[0]);
- if (isUNC) {
- return [
- ...s.slice(0, 4),
- ...s.slice(4).map(ss => this.parse(ss)),
- ];
- }
- else if (isDrive) {
- return [s[0], ...s.slice(1).map(ss => this.parse(ss))];
- }
- }
- return 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 (this.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);
- }
- // various transforms to equivalent pattern sets that are
- // faster to process in a filesystem walk. The goal is to
- // eliminate what we can, and push all ** patterns as far
- // to the right as possible, even if it increases the number
- // of patterns that we have to process.
- preprocess(globParts) {
- // if we're not in globstar mode, then turn ** into *
- if (this.options.noglobstar) {
- for (let i = 0; i < globParts.length; i++) {
- for (let j = 0; j < globParts[i].length; j++) {
- if (globParts[i][j] === '**') {
- globParts[i][j] = '*';
- }
- }
- }
- }
- const { optimizationLevel = 1 } = this.options;
- if (optimizationLevel >= 2) {
- // aggressive optimization for the purpose of fs walking
- globParts = this.firstPhasePreProcess(globParts);
- globParts = this.secondPhasePreProcess(globParts);
- }
- else if (optimizationLevel >= 1) {
- // just basic optimizations to remove some .. parts
- globParts = this.levelOneOptimize(globParts);
- }
- else {
- // just collapse multiple ** portions into one
- globParts = this.adjascentGlobstarOptimize(globParts);
- }
- return globParts;
- }
- // just get rid of adjascent ** portions
- adjascentGlobstarOptimize(globParts) {
- return globParts.map(parts => {
- let gs = -1;
- while (-1 !== (gs = parts.indexOf('**', gs + 1))) {
- let i = gs;
- while (parts[i + 1] === '**') {
- i++;
- }
- if (i !== gs) {
- parts.splice(gs, i - gs);
- }
- }
- return parts;
- });
- }
- // get rid of adjascent ** and resolve .. portions
- levelOneOptimize(globParts) {
- return globParts.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;
- });
- }
- levelTwoFileOptimize(parts) {
- if (!Array.isArray(parts)) {
- parts = this.slashSplit(parts);
- }
- let didSomething = false;
- do {
- didSomething = false;
- // // -> /
- if (!this.preserveMultipleSlashes) {
- for (let i = 1; i < parts.length - 1; i++) {
- const p = parts[i];
- // don't squeeze out UNC patterns
- if (i === 1 && p === '' && parts[0] === '')
- continue;
- if (p === '.' || p === '') {
- didSomething = true;
- parts.splice(i, 1);
- i--;
- }
- }
- if (parts[0] === '.' &&
- parts.length === 2 &&
- (parts[1] === '.' || parts[1] === '')) {
- didSomething = true;
- parts.pop();
- }
- }
- // //../ -> /
- let dd = 0;
- while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
- const p = parts[dd - 1];
- if (p && p !== '.' && p !== '..' && p !== '**') {
- didSomething = true;
- parts.splice(dd - 1, 2);
- dd -= 2;
- }
- }
- } while (didSomething);
- return parts.length === 0 ? [''] : parts;
- }
- // First phase: single-pattern processing
- // is 1 or more portions
- // is 1 or more portions
- // is any portion other than ., .., '', or **
- // is . or ''
- //
- // **/.. is *brutal* for filesystem walking performance, because
- // it effectively resets the recursive walk each time it occurs,
- // and ** cannot be reduced out by a .. pattern part like a regexp
- // or most strings (other than .., ., and '') can be.
- //
- // /**/..//
/ -> {/..//
/,/**//
/}
- // // -> /
- // //../ -> /
- // **/**/ -> **/
- //
- // **/*/ -> */**/ <== not valid because ** doesn't follow
- // this WOULD be allowed if ** did follow symlinks, or * didn't
- firstPhasePreProcess(globParts) {
- let didSomething = false;
- do {
- didSomething = false;
- // /**/..//
/ -> {/..//
/,/**//
/}
- for (let parts of globParts) {
- let gs = -1;
- while (-1 !== (gs = parts.indexOf('**', gs + 1))) {
- let gss = gs;
- while (parts[gss + 1] === '**') {
- // /**/**/ -> /**/
- gss++;
- }
- // eg, if gs is 2 and gss is 4, that means we have 3 **
- // parts, and can remove 2 of them.
- if (gss > gs) {
- parts.splice(gs + 1, gss - gs);
- }
- let next = parts[gs + 1];
- const p = parts[gs + 2];
- const p2 = parts[gs + 3];
- if (next !== '..')
- continue;
- if (!p ||
- p === '.' ||
- p === '..' ||
- !p2 ||
- p2 === '.' ||
- p2 === '..') {
- continue;
- }
- didSomething = true;
- // edit parts in place, and push the new one
- parts.splice(gs, 1);
- const other = parts.slice(0);
- other[gs] = '**';
- globParts.push(other);
- gs--;
- }
- // // -> /
- if (!this.preserveMultipleSlashes) {
- for (let i = 1; i < parts.length - 1; i++) {
- const p = parts[i];
- // don't squeeze out UNC patterns
- if (i === 1 && p === '' && parts[0] === '')
- continue;
- if (p === '.' || p === '') {
- didSomething = true;
- parts.splice(i, 1);
- i--;
- }
- }
- if (parts[0] === '.' &&
- parts.length === 2 &&
- (parts[1] === '.' || parts[1] === '')) {
- didSomething = true;
- parts.pop();
- }
- }
- // /