+ 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();
+ }
+ }
+ // /