packx
Version:
Smart file filter for Repomix - search and bundle only files containing specific strings
6,745 lines • 206 kB
JavaScript
#!/usr/bin/env node
import { createRequire } from "node:module";
var __create = Object.create;
var __getProtoOf = Object.getPrototypeOf;
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __toESM = (mod, isNodeMode, target) => {
target = mod != null ? __create(__getProtoOf(mod)) : {};
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
for (let key of __getOwnPropNames(mod))
if (!__hasOwnProp.call(to, key))
__defProp(to, key, {
get: () => mod[key],
enumerable: true
});
return to;
};
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
var __require = /* @__PURE__ */ createRequire(import.meta.url);
// node_modules/mri/lib/index.js
var require_lib = __commonJS((exports, module) => {
function toArr(any) {
return any == null ? [] : Array.isArray(any) ? any : [any];
}
function toVal(out, key, val, opts) {
var x, old = out[key], nxt = ~opts.string.indexOf(key) ? val == null || val === true ? "" : String(val) : typeof val === "boolean" ? val : ~opts.boolean.indexOf(key) ? val === "false" ? false : val === "true" || (out._.push((x = +val, x * 0 === 0) ? x : val), !!val) : (x = +val, x * 0 === 0) ? x : val;
out[key] = old == null ? nxt : Array.isArray(old) ? old.concat(nxt) : [old, nxt];
}
module.exports = function(args, opts) {
args = args || [];
opts = opts || {};
var k, arr, arg, name, val, out = { _: [] };
var i = 0, j = 0, idx = 0, len = args.length;
const alibi = opts.alias !== undefined;
const strict = opts.unknown !== undefined;
const defaults = opts.default !== undefined;
opts.alias = opts.alias || {};
opts.string = toArr(opts.string);
opts.boolean = toArr(opts.boolean);
if (alibi) {
for (k in opts.alias) {
arr = opts.alias[k] = toArr(opts.alias[k]);
for (i = 0;i < arr.length; i++) {
(opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
}
}
}
for (i = opts.boolean.length;i-- > 0; ) {
arr = opts.alias[opts.boolean[i]] || [];
for (j = arr.length;j-- > 0; )
opts.boolean.push(arr[j]);
}
for (i = opts.string.length;i-- > 0; ) {
arr = opts.alias[opts.string[i]] || [];
for (j = arr.length;j-- > 0; )
opts.string.push(arr[j]);
}
if (defaults) {
for (k in opts.default) {
name = typeof opts.default[k];
arr = opts.alias[k] = opts.alias[k] || [];
if (opts[name] !== undefined) {
opts[name].push(k);
for (i = 0;i < arr.length; i++) {
opts[name].push(arr[i]);
}
}
}
}
const keys = strict ? Object.keys(opts.alias) : [];
for (i = 0;i < len; i++) {
arg = args[i];
if (arg === "--") {
out._ = out._.concat(args.slice(++i));
break;
}
for (j = 0;j < arg.length; j++) {
if (arg.charCodeAt(j) !== 45)
break;
}
if (j === 0) {
out._.push(arg);
} else if (arg.substring(j, j + 3) === "no-") {
name = arg.substring(j + 3);
if (strict && !~keys.indexOf(name)) {
return opts.unknown(arg);
}
out[name] = false;
} else {
for (idx = j + 1;idx < arg.length; idx++) {
if (arg.charCodeAt(idx) === 61)
break;
}
name = arg.substring(j, idx);
val = arg.substring(++idx) || (i + 1 === len || ("" + args[i + 1]).charCodeAt(0) === 45 || args[++i]);
arr = j === 2 ? [name] : name;
for (idx = 0;idx < arr.length; idx++) {
name = arr[idx];
if (strict && !~keys.indexOf(name))
return opts.unknown("-".repeat(j) + name);
toVal(out, name, idx + 1 < arr.length || val, opts);
}
}
}
if (defaults) {
for (k in opts.default) {
if (out[k] === undefined) {
out[k] = opts.default[k];
}
}
}
if (alibi) {
for (k in out) {
arr = opts.alias[k] || [];
while (arr.length > 0) {
out[arr.shift()] = out[k];
}
}
}
return out;
};
});
// node_modules/balanced-match/index.js
var require_balanced_match = __commonJS((exports, module) => {
module.exports = balanced;
function balanced(a, b, str) {
if (a instanceof RegExp)
a = maybeMatch(a, str);
if (b instanceof RegExp)
b = maybeMatch(b, str);
var r = range(a, b, str);
return r && {
start: r[0],
end: r[1],
pre: str.slice(0, r[0]),
body: str.slice(r[0] + a.length, r[1]),
post: str.slice(r[1] + b.length)
};
}
function maybeMatch(reg, str) {
var m = str.match(reg);
return m ? m[0] : null;
}
balanced.range = range;
function range(a, b, str) {
var begs, beg, left, right, result;
var ai = str.indexOf(a);
var bi = str.indexOf(b, ai + 1);
var 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) {
result = [begs.pop(), bi];
} else {
beg = begs.pop();
if (beg < left) {
left = beg;
right = bi;
}
bi = str.indexOf(b, i + 1);
}
i = ai < bi && ai >= 0 ? ai : bi;
}
if (begs.length) {
result = [left, right];
}
}
return result;
}
});
// node_modules/brace-expansion/index.js
var require_brace_expansion = __commonJS((exports, module) => {
var balanced = require_balanced_match();
module.exports = expandTop;
var escSlash = "\x00SLASH" + Math.random() + "\x00";
var escOpen = "\x00OPEN" + Math.random() + "\x00";
var escClose = "\x00CLOSE" + Math.random() + "\x00";
var escComma = "\x00COMMA" + Math.random() + "\x00";
var escPeriod = "\x00PERIOD" + Math.random() + "\x00";
function numeric(str) {
return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0);
}
function escapeBraces(str) {
return str.split("\\\\").join(escSlash).split("\\{").join(escOpen).split("\\}").join(escClose).split("\\,").join(escComma).split("\\.").join(escPeriod);
}
function unescapeBraces(str) {
return str.split(escSlash).join("\\").split(escOpen).join("{").split(escClose).join("}").split(escComma).join(",").split(escPeriod).join(".");
}
function parseCommaParts(str) {
if (!str)
return [""];
var parts = [];
var m = balanced("{", "}", str);
if (!m)
return str.split(",");
var pre = m.pre;
var body = m.body;
var post = m.post;
var p = pre.split(",");
p[p.length - 1] += "{" + body + "}";
var 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 expandTop(str) {
if (!str)
return [];
if (str.substr(0, 2) === "{}") {
str = "\\{\\}" + str.substr(2);
}
return expand(escapeBraces(str), 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, isTop) {
var expansions = [];
var m = balanced("{", "}", str);
if (!m)
return [str];
var pre = m.pre;
var post = m.post.length ? expand(m.post, false) : [""];
if (/\$$/.test(m.pre)) {
for (var k = 0;k < post.length; k++) {
var expansion = pre + "{" + m.body + "}" + post[k];
expansions.push(expansion);
}
} else {
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
var isSequence = isNumericSequence || isAlphaSequence;
var isOptions = m.body.indexOf(",") >= 0;
if (!isSequence && !isOptions) {
if (m.post.match(/,(?!,).*\}/)) {
str = m.pre + "{" + m.body + escClose + m.post;
return expand(str);
}
return [str];
}
var n;
if (isSequence) {
n = m.body.split(/\.\./);
} else {
n = parseCommaParts(m.body);
if (n.length === 1) {
n = expand(n[0], false).map(embrace);
if (n.length === 1) {
return post.map(function(p) {
return m.pre + n[0] + p;
});
}
}
}
var N;
if (isSequence) {
var x = numeric(n[0]);
var y = numeric(n[1]);
var width = Math.max(n[0].length, n[1].length);
var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1;
var test = lte;
var reverse = y < x;
if (reverse) {
incr *= -1;
test = gte;
}
var pad = n.some(isPadded);
N = [];
for (var i = x;test(i, y); i += incr) {
var c;
if (isAlphaSequence) {
c = String.fromCharCode(i);
if (c === "\\")
c = "";
} else {
c = String(i);
if (pad) {
var need = width - c.length;
if (need > 0) {
var 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 (var j = 0;j < n.length; j++) {
N.push.apply(N, expand(n[j], false));
}
}
for (var j = 0;j < N.length; j++) {
for (var k = 0;k < post.length; k++) {
var expansion = pre + N[j] + post[k];
if (!isTop || isSequence || expansion)
expansions.push(expansion);
}
}
}
return expansions;
}
});
// src/index.ts
var import_mri = __toESM(require_lib(), 1);
import { promises as fs } from "node:fs";
import * as path2 from "node:path";
// node_modules/minimatch/dist/esm/index.js
var import_brace_expansion = __toESM(require_brace_expansion(), 1);
// node_modules/minimatch/dist/esm/assert-valid-pattern.js
var MAX_PATTERN_LENGTH = 1024 * 64;
var assertValidPattern = (pattern) => {
if (typeof pattern !== "string") {
throw new TypeError("invalid pattern");
}
if (pattern.length > MAX_PATTERN_LENGTH) {
throw new TypeError("pattern is too long");
}
};
// node_modules/minimatch/dist/esm/brace-expressions.js
var 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]
};
var braceEscape = (s) => s.replace(/[[\]\\-]/g, "\\$&");
var regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
var rangesToString = (ranges) => ranges.join("");
var parseClass = (glob, position) => {
const pos = position;
if (glob.charAt(pos) !== "[") {
throw new Error("not in a brace expression");
}
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;
}
}
if (c === "[" && !escaping) {
for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {
if (glob.startsWith(cls, i)) {
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;
}
}
}
escaping = false;
if (rangeStart) {
if (c > rangeStart) {
ranges.push(braceEscape(rangeStart) + "-" + braceEscape(c));
} else if (c === rangeStart) {
ranges.push(braceEscape(c));
}
rangeStart = "";
i++;
continue;
}
if (glob.startsWith("-]", i + 1)) {
ranges.push(braceEscape(c + "-"));
i += 2;
continue;
}
if (glob.startsWith("-", i + 1)) {
rangeStart = c;
i += 2;
continue;
}
ranges.push(braceEscape(c));
i++;
}
if (endPos < i) {
return ["", false, 0, false];
}
if (!ranges.length && !negs.length) {
return ["$.", false, glob.length - pos, true];
}
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];
};
// node_modules/minimatch/dist/esm/unescape.js
var unescape = (s, { windowsPathsNoEscape = false } = {}) => {
return windowsPathsNoEscape ? s.replace(/\[([^\/\\])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, "$1$2").replace(/\\([^\/])/g, "$1");
};
// node_modules/minimatch/dist/esm/ast.js
var types = new Set(["!", "?", "+", "*", "@"]);
var isExtglobType = (c) => types.has(c);
var startNoTraversal = "(?!(?:^|/)\\.\\.?(?:$|/))";
var startNoDot = "(?!\\.)";
var addPatternStart = new Set(["[", "."]);
var justDots = new Set(["..", "."]);
var reSpecials = new Set("().*{}+?[]^$\\!");
var regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
var qmark = "[^/]";
var star = qmark + "*?";
var starNoEmpty = qmark + "+?";
class AST {
type;
#root;
#hasMagic;
#uflag = false;
#parts = [];
#parent;
#parentIndex;
#negs;
#filledNegs = false;
#options;
#toString;
#emptyExt = false;
constructor(type, parent, options = {}) {
this.type = type;
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() {
if (this.#hasMagic !== undefined)
return this.#hasMagic;
for (const p of this.#parts) {
if (typeof p === "string")
continue;
if (p.type || p.hasMagic)
return this.#hasMagic = true;
}
return this.#hasMagic;
}
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() {
if (this !== this.#root)
throw new Error("should only call on root");
if (this.#filledNegs)
return this;
this.toString();
this.#filledNegs = true;
let n;
while (n = this.#negs.pop()) {
if (n.type !== "!")
continue;
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) {
if (typeof part === "string") {
throw new Error("string part in extglob AST??");
}
part.copyIn(pp.#parts[i]);
}
}
p = pp;
pp = p.#parent;
}
}
return this;
}
push(...parts) {
for (const p of parts) {
if (p === "")
continue;
if (typeof p !== "string" && !(p instanceof AST && p.#parent === this)) {
throw new Error("invalid part: " + p);
}
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.#parent?.isStart())
return false;
if (this.#parentIndex === 0)
return true;
const p = this.#parent;
for (let i = 0;i < this.#parentIndex; i++) {
const pp = p.#parts[i];
if (!(pp instanceof AST && 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();
const pl = this.#parent ? this.#parent.#parts.length : 0;
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 AST(this.type, parent);
for (const p of this.#parts) {
c.copyIn(p);
}
return c;
}
static #parseAST(str, ast, pos, opt) {
let escaping = false;
let inBrace = false;
let braceStart = -1;
let braceNeg = false;
if (ast.type === null) {
let i2 = pos;
let acc2 = "";
while (i2 < str.length) {
const c = str.charAt(i2++);
if (escaping || c === "\\") {
escaping = !escaping;
acc2 += c;
continue;
}
if (inBrace) {
if (i2 === braceStart + 1) {
if (c === "^" || c === "!") {
braceNeg = true;
}
} else if (c === "]" && !(i2 === braceStart + 2 && braceNeg)) {
inBrace = false;
}
acc2 += c;
continue;
} else if (c === "[") {
inBrace = true;
braceStart = i2;
braceNeg = false;
acc2 += c;
continue;
}
if (!opt.noext && isExtglobType(c) && str.charAt(i2) === "(") {
ast.push(acc2);
acc2 = "";
const ext = new AST(c, ast);
i2 = AST.#parseAST(str, ext, i2, opt);
ast.push(ext);
continue;
}
acc2 += c;
}
ast.push(acc2);
return i2;
}
let i = pos + 1;
let part = new AST(null, ast);
const parts = [];
let acc = "";
while (i < str.length) {
const c = str.charAt(i++);
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;
}
if (isExtglobType(c) && str.charAt(i) === "(") {
part.push(acc);
acc = "";
const ext = new AST(c, part);
part.push(ext);
i = AST.#parseAST(str, ext, i, opt);
continue;
}
if (c === "|") {
part.push(acc);
acc = "";
parts.push(part);
part = new AST(null, ast);
continue;
}
if (c === ")") {
if (acc === "" && ast.#parts.length === 0) {
ast.#emptyExt = true;
}
part.push(acc);
acc = "";
ast.push(...parts, part);
return i;
}
acc += c;
}
ast.type = null;
ast.#hasMagic = undefined;
ast.#parts = [str.substring(pos - 1)];
return i;
}
static fromGlob(pattern, options = {}) {
const ast = new AST(null, undefined, options);
AST.#parseAST(pattern, ast, 0, options);
return ast;
}
toMMPattern() {
if (this !== this.#root)
return this.#root.toMMPattern();
const glob = this.toString();
const [re, body, hasMagic, uflag] = this.toRegExpSource();
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;
}
toRegExpSource(allowDot) {
const dot = allowDot ?? !!this.#options.dot;
if (this.#root === this)
this.#fillNegs();
if (!this.type) {
const noEmpty = this.isStart() && this.isEnd();
const src = this.#parts.map((p) => {
const [re, _, hasMagic, uflag] = typeof p === "string" ? AST.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
this.#hasMagic = this.#hasMagic || hasMagic;
this.#uflag = this.#uflag || uflag;
return re;
}).join("");
let start2 = "";
if (this.isStart()) {
if (typeof this.#parts[0] === "string") {
const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]);
if (!dotTravAllowed) {
const aps = addPatternStart;
const needNoTrav = dot && aps.has(src.charAt(0)) || src.startsWith("\\.") && aps.has(src.charAt(2)) || src.startsWith("\\.\\.") && aps.has(src.charAt(4));
const needNoDot = !dot && !allowDot && aps.has(src.charAt(0));
start2 = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : "";
}
}
}
let end = "";
if (this.isEnd() && this.#root.#filledNegs && this.#parent?.type === "!") {
end = "(?:$|\\/)";
}
const final2 = start2 + src + end;
return [
final2,
unescape(src),
this.#hasMagic = !!this.#hasMagic,
this.#uflag
];
}
const repeated = this.type === "*" || this.type === "+";
const start = this.type === "!" ? "(?:(?!(?:" : "(?:";
let body = this.#partsToRegExp(dot);
if (this.isStart() && this.isEnd() && !body && this.type !== "!") {
const s = this.toString();
this.#parts = [s];
this.type = null;
this.#hasMagic = undefined;
return [s, unescape(this.toString()), false, false];
}
let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ? "" : this.#partsToRegExp(true);
if (bodyDotAllowed === body) {
bodyDotAllowed = "";
}
if (bodyDotAllowed) {
body = `(?:${body})(?:${bodyDotAllowed})*?`;
}
let final = "";
if (this.type === "!" && this.#emptyExt) {
final = (this.isStart() && !dot ? startNoDot : "") + starNoEmpty;
} else {
const close = this.type === "!" ? "))" + (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(body),
this.#hasMagic = !!this.#hasMagic,
this.#uflag
];
}
#partsToRegExp(dot) {
return this.#parts.map((p) => {
if (typeof p === "string") {
throw new Error("string type in extglob ast??");
}
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;
for (let i = 0;i < glob.length; i++) {
const c = glob.charAt(i);
if (escaping) {
escaping = false;
re += (reSpecials.has(c) ? "\\" : "") + c;
continue;
}
if (c === "\\") {
if (i === glob.length - 1) {
re += "\\\\";
} else {
escaping = true;
}
continue;
}
if (c === "[") {
const [src, needUflag, consumed, magic] = parseClass(glob, i);
if (consumed) {
re += src;
uflag = uflag || needUflag;
i += consumed - 1;
hasMagic = hasMagic || magic;
continue;
}
}
if (c === "*") {
if (noEmpty && glob === "*")
re += starNoEmpty;
else
re += star;
hasMagic = true;
continue;
}
if (c === "?") {
re += qmark;
hasMagic = true;
continue;
}
re += regExpEscape(c);
}
return [re, unescape(glob), !!hasMagic, uflag];
}
}
// node_modules/minimatch/dist/esm/escape.js
var escape = (s, { windowsPathsNoEscape = false } = {}) => {
return windowsPathsNoEscape ? s.replace(/[?*()[\]]/g, "[$&]") : s.replace(/[?*()[\]\\]/g, "\\$&");
};
// node_modules/minimatch/dist/esm/index.js
var minimatch = (p, pattern, options = {}) => {
assertValidPattern(pattern);
if (!options.nocomment && pattern.charAt(0) === "#") {
return false;
}
return new Minimatch(pattern, options).match(p);
};
var starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/;
var starDotExtTest = (ext) => (f) => !f.startsWith(".") && f.endsWith(ext);
var starDotExtTestDot = (ext) => (f) => f.endsWith(ext);
var starDotExtTestNocase = (ext) => {
ext = ext.toLowerCase();
return (f) => !f.startsWith(".") && f.toLowerCase().endsWith(ext);
};
var starDotExtTestNocaseDot = (ext) => {
ext = ext.toLowerCase();
return (f) => f.toLowerCase().endsWith(ext);
};
var starDotStarRE = /^\*+\.\*+$/;
var starDotStarTest = (f) => !f.startsWith(".") && f.includes(".");
var starDotStarTestDot = (f) => f !== "." && f !== ".." && f.includes(".");
var dotStarRE = /^\.\*+$/;
var dotStarTest = (f) => f !== "." && f !== ".." && f.startsWith(".");
var starRE = /^\*+$/;
var starTest = (f) => f.length !== 0 && !f.startsWith(".");
var starTestDot = (f) => f.length !== 0 && f !== "." && f !== "..";
var qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/;
var qmarksTestNocase = ([$0, ext = ""]) => {
const noext = qmarksTestNoExt([$0]);
if (!ext)
return noext;
ext = ext.toLowerCase();
return (f) => noext(f) && f.toLowerCase().endsWith(ext);
};
var qmarksTestNocaseDot = ([$0, ext = ""]) => {
const noext = qmarksTestNoExtDot([$0]);
if (!ext)
return noext;
ext = ext.toLowerCase();
return (f) => noext(f) && f.toLowerCase().endsWith(ext);
};
var qmarksTestDot = ([$0, ext = ""]) => {
const noext = qmarksTestNoExtDot([$0]);
return !ext ? noext : (f) => noext(f) && f.endsWith(ext);
};
var qmarksTest = ([$0, ext = ""]) => {
const noext = qmarksTestNoExt([$0]);
return !ext ? noext : (f) => noext(f) && f.endsWith(ext);
};
var qmarksTestNoExt = ([$0]) => {
const len = $0.length;
return (f) => f.length === len && !f.startsWith(".");
};
var qmarksTestNoExtDot = ([$0]) => {
const len = $0.length;
return (f) => f.length === len && f !== "." && f !== "..";
};
var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
var path = {
win32: { sep: "\\" },
posix: { sep: "/" }
};
var sep = defaultPlatform === "win32" ? path.win32.sep : path.posix.sep;
minimatch.sep = sep;
var GLOBSTAR = Symbol("globstar **");
minimatch.GLOBSTAR = GLOBSTAR;
var qmark2 = "[^/]";
var star2 = qmark2 + "*?";
var twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?";
var twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?";
var filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options);
minimatch.filter = filter;
var ext = (a, b = {}) => Object.assign({}, a, b);
var 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 AST2 extends orig.AST {
constructor(type, parent, options = {}) {
super(type, parent, ext(def, options));
}
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
});
};
minimatch.defaults = defaults;
var braceExpand = (pattern, options = {}) => {
assertValidPattern(pattern);
if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
return [pattern];
}
return import_brace_expansion.default(pattern);
};
minimatch.braceExpand = braceExpand;
var makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
minimatch.makeRe = makeRe;
var 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;
var globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/;
var regExpEscape2 = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
class Minimatch {
options;
set;
pattern;
windowsPathsNoEscape;
nonegate;
negate;
comment;
empty;
preserveMultipleSlashes;
partial;
globSet;
globParts;
nocase;
isWindows;
platform;
windowsNoMagicRoot;
regexp;
constructor(pattern, options = {}) {
assertValidPattern(pattern);
options = options || {};
this.options = options;
this.pattern = pattern;
this.platform = options.platform || defaultPlatform;
this.isWindows = this.platform === "win32";
this.windowsPathsNoEscape = !!options.windowsPathsNoEscape || options.allowWindowsEscape === false;
if (this.windowsPathsNoEscape) {
this.pattern = this.pattern.replace(/\\/g, "/");
}
this.preserveMultipleSlashes = !!options.preserveMultipleSlashes;
this.regexp = null;
this.negate = false;
this.nonegate = !!options.nonegate;
this.comment = false;
this.empty = false;
this.partial = !!options.partial;
this.nocase = !!this.options.nocase;
this.windowsNoMagicRoot = options.windowsNoMagicRoot !== undefined ? options.windowsNoMagicRoot : !!(this.isWindows && this.nocase);
this.globSet = [];
this.globParts = [];
this.set = [];
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;
if (!options.nocomment && pattern.charAt(0) === "#") {
this.comment = true;
return;
}
if (!pattern) {
this.empty = true;
return;
}
this.parseNegate();
this.globSet = [...new Set(this.braceExpand())];
if (options.debug) {
this.debug = (...args) => console.error(...args);
}
this.debug(this.pattern, this.globSet);
const rawGlobParts = this.globSet.map((s) => this.slashSplit(s));
this.globParts = this.preprocess(rawGlobParts);
this.debug(this.pattern, this.globParts);
let set = this.globParts.map((s, _, __) => {
if (this.isWindows && this.windowsNoMagicRoot) {
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);
this.set = set.filter((s) => s.indexOf(false) === -1);
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);
}
preprocess(globParts) {
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) {
globParts = this.firstPhasePreProcess(globParts);
globParts = this.secondPhasePreProcess(globParts);
} else if (optimizationLevel >= 1) {
globParts = this.levelOneOptimize(globParts);
} else {
globParts = this.adjascentGlobstarOptimize(globParts);
}
return globParts;
}
adjascentGlobstarOptimize(globParts) {
return globParts.map((parts) => {
let gs = -1;
while ((gs = parts.indexOf("**", gs + 1)) !== -1) {
let i = gs;
while (parts[i + 1] === "**") {
i++;
}
if (i !== gs) {
parts.splice(gs, i - gs);
}
}
return parts;
});
}
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];
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 ((dd = parts.indexOf("..", dd + 1)) !== -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;
}
firstPhasePreProcess(globParts) {
let didSomething = false;
do {
didSomething = false;
for (let parts of globParts) {
let gs = -1;
while ((gs = parts.indexOf("**", gs + 1)) !== -1) {
let gss = gs;
while (parts[gss + 1] === "**") {
gss++;
}
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;
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];
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 ((dd = parts.indexOf("..", dd + 1)) !== -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;
}
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;
}
}
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;
}
matchOne(file, pattern, partial = false) {
const options = this.options;
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;
if (pdi > fdi) {
pattern = pattern.slice(pdi);
} else if (fdi > pdi) {
file = file.slice(fdi);
}
}
}
}
const { optimizationLevel = 1 } = this.options;
if (optimizationLevel >= 2) {
file = this.levelTwoFileOptimize(file);
}
this.debug("matchOne", this, { file, pattern });
this.debug("matchOne", file.length, pattern.length);
for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length;fi < fl && pi < pl; fi++, pi++) {
this.debug("matchOne loop");
var p = pattern[pi];
var f = file[fi];
this.debug(pattern, p, f);
if (p === false) {
return false;
}
if (p === GLOBSTAR) {
this.debug("GLOBSTAR", [pattern, p, f]);
var fr = fi;
var pr = pi + 1;
if (pr === pl) {
this.debug("** at the end");
for (;fi < fl; fi++) {
if (file[fi] === "." || file[fi] === ".." || !options.dot && file[fi].charAt(0) === ".")
return false;
}
return true;
}
while (fr < fl) {
var swallowee = file[fr];
this.debug(`
globstar while`, file, fr, pattern, pr, swallowee);
if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
this.debug("globstar found match!", fr, fl, swallowee);
return true;
} else {
if (swallowee === "." || swallowee === ".." || !options.dot && swallowee.charAt(0) === ".") {
this.debug("dot detected!", file, fr, pattern, pr);
break;
}
this.debug("globstar swallow a segment, and continue");
fr++;
}
}
if (partial) {
this.debug(`
>>> no match, partial?`, file, fr, pattern, pr);
if (fr === fl) {
return true;
}
}
return false;
}
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] === "";
} else {
throw new Error("wtf?");
}
}
braceExpand() {
return braceExpand(this.pattern, this.options);
}
parse(pattern) {
assertValidPattern(pattern);
const options = this.options;
if (pattern === "**")
return GLOBSTAR;
if (pattern === "")
return "";
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.fromGlob(pattern, this.options).toMMPattern();
if (fastTest && typeof re === "object") {
Reflect.defineProperty(re, "test", { value: fastTest });
}
return re;
}
makeRe() {
if (this.regexp || this.regexp === false)
return this.regexp;
const set = this.set;
if (!set.length) {
this.regexp = false;
return this.regexp;
}
const options = this.options;
const twoStar = options.noglobstar ? star2 : options.dot ? twoStarDot : twoStarNoDot;
const flags = new Set(options.nocase ? ["i"] : []);
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" ? regExpEscape2(p) : p === GLOBSTAR ? GLOBSTAR : p._src;
});
pp.forEach((p, i) => {
const next = pp[i + 1];
const prev = pp[i - 1];
if (p !== GLOBSTAR || prev === GLOBSTAR) {
return;
}
if (prev === undefined) {
if (next !== undefined && next !== GLOBSTAR) {
pp[i + 1] = "(?:\\/|" + twoStar + "\\/)?" + next;
} else {
pp[i] = twoStar;
}
} else if (next === undefined) {
pp[i - 1] = prev + "(?:\\/|" + twoStar + ")?";
} else if (next !== GLOBSTAR) {
pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + "\\/)" + next;
pp[i + 1] = GLOBSTAR;
}
});
return pp.filter((p) => p !== GLOBSTAR).join("/");
}).join("|");
const [open, close] = set.length > 1 ? ["(?:", ")"] : ["", ""];
re = "^" + open + re + close + "$";
if (this.negate)
re = "^(?!" + re + ").+$";
try {
this.regexp = new RegExp(re, [...flags].join(""));
} catch (ex) {
this.regexp = false;
}
return this.regexp;
}
slashSplit(p) {
if (this.preserveMultipleSlashes) {
return p.split("/");
} else if (this.isWindows && /^\/\/[^\/]+/.test(p)) {
return ["", ...p.split(/\/+/)];
} else {
return p.split(/\/+/);
}
}
match(f, partial = this.partial) {
this.debug("match", f, this.pattern);
if (this.comment) {
return false;
}
if (this.empty) {
return f === "";
}
if (f === "/" && partial) {
return true;
}
const options = this.options;
if (this.isWindows) {
f = f.split("\\").join("/");
}
const ff = this.slashSplit(f);
this.debug(this.pattern, "split", ff);
const set = this.set;
this.debug(this.pattern, "set", set);
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;
}
}
if (options.flipNegate) {
return false;
}
return this.negate;
}
static defaults(def) {
return minimatch.defaults(def).Minimatch;
}
}
minimatch.AST = AST;
minimatch.Minimatch = Minimatch;
minimatch.escape = escape;
minimatch.unescape = unescape;
// node_modules/glob/dist/esm/glob.js
import { fileURLToPath as fileURLToPath2 } from "node:url";
// node_modules/lru-cache/dist/esm/index.js
var perf = typeof performance === "object" && performance && typeof performance.now === "function" ? performance : Date;
var warned = new Set;
var PROCESS = typeof process === "object" && !!process ? process : {};
var emitWarning = (msg, type, code, fn) => {
typeof PROCESS.emitWarning === "function" ? PROCESS.emitWarning(msg, type, code, fn) : console.error(`[${code}] ${type}: ${msg}`);
};
var AC = globalThis.AbortController;
var AS = globalThis.AbortSignal;
if (typeof AC === "undefined") {
AS = class AbortSignal {
onabort;
_onabort = [];
reason;
aborted = false;
addEventListener(_, fn) {
this._onabort.push(fn);
}
};
AC = class AbortController {
constructor() {
warnACPolyfill();
}
signal = new AS;
abort(reason) {
if (this.signal.aborted)
return;
this.signal.reason = reason;
this.signal.aborted = true;
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);
};
}
var shouldWarn = (code) => !warned.has(code);
var TYPE = Symbol("type");
var isPosInt = (n) => n && n === Math.floor(n) && n > 0 && isFinite(n);
var 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;
class ZeroArray extends Array {
constructor(size) {
super(size);
this.fill(0);
}
}
class Stack {
heap;
length;
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) {
if (!Stack.#constructing) {
throw new TypeError("instantiate Stack using Stack.create(n)");
}
this.heap = new HeapCls(max);
this.length = 0;
}
push(n) {
this.heap[this.length++] = n;
}
pop() {
return this.heap[--this.length];
}
}
class LRUCache {
#max;
#maxSize;
#dispose;
#disposeAfter;
#fetchMethod;
#memoMethod;
ttl;
ttlResolution;
ttlAutopurge;
updateAgeOnGet;
updateAgeOnHas;
allowStale;
noDisposeOnSet;
noUpdateTTL;
maxEntrySize;
sizeCalculation;
noDeleteOnFetchRejection;
noDeleteOnStaleGet;
allowStaleOnFetchAbort;
allowStaleOnFetchRejection;
ignoreFetchAbort;
#size;
#calculatedSize;
#keyMap;
#keyList;
#valList;
#next;
#prev;
#head;
#tail;
#free;
#disposed;
#sizes;
#starts;
#ttls;
#hasDispose;
#hasFetchMethod;
#hasDisposeAfter;
static unsafeExposeInternals(c) {
return {
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,
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)
};
}
get max() {
return this.#max;
}
get maxSize() {
return this.#maxSize;
}
get calculatedSize() {
return this.#calculatedSize;
}
get size() {
return this.#size;
}
get fetchMethod() {
return this.#fetchMethod;
}
get memoMethod() {
return this.#memoMethod;
}
get dispose() {
return this.#dispose;
}
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;
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();
}
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);
}
}
}
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);
if (t.unref) {
t.unref();
}
}
};
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];
if (!ttl || !start)
return;
status.ttl = ttl;
status.start = start;
status.now = cachedNow || getNow();
const age = status.now - start;
status.remainingTTL = ttl - age;
}
};
let cachedNow = 0;
const getNow = () => {
const n = perf.now();
if (this.ttlResolution > 0) {
cachedNow = n;
const t = setTimeout(() => cachedNow = 0, this.ttlResolution);
if (t.unref) {
t.unref();
}
}
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;
};
}
#updateItemAge = () => {};
#statusTTL = () => {};
#setItemTTL = () => {};
#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) => {
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;; ) {
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;; ) {
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;
}
*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]];
}
}
}
*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]];
}
}
}
*keys() {
for (const i of this.#indexes()) {
const k = this.#keyList[i];
if (k !== undefined && !this.#isBackgroundFetch(this.#valList[i])) {
yield k;
}
}
}
*rkeys() {
for (const i of this.#rindexes()) {
const k = this.#keyList[i];
if (k !== undefined && !this.#isBackgroundFetch(this.#valList[i])) {
yield k;
}
}
}
*values() {
for (const i of this.#indexes()) {
const v = this.#valList[i];
if (v !== undefined && !this.#isBackgroundFetch(this.#valList[i])) {
yield this.#valList[i];
}
}
}
*rvalues() {
for (const i of this.#rindexes()) {
const v = this.#valList[i];
if (v !== undefined && !this.#isBackgroundFetch(this.#valList[i])) {
yield this.#valList[i];
}
}
}
[Symbol.iterator]() {
return this.entries();
}
[Symbol.toStringTag] = "LRUCache";
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);
}
}
}
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);
}
}
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);
}
}
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;
}
info(key) {
const i = this.#keyMap.get(key);
if (i === undefined)
return;
const v = this.#valList[i];
const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
if (value === undefined)
return;
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;
}
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];
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;
}
load(arr) {
this.clear();
for (const [key, entry] of arr) {
if (entry.start) {
const age = Date.now() - entry.start;
entry.start = perf.now() - age;
}
this.set(key, entry.value, entry);
}
}
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 (this.maxEntrySize && size > this.maxEntrySize) {
if (status) {
status.set = "miss";
status.maxEntrySizeExceeded = true;
}
this.#delete(k, "set");
return this;
}
let index = this.#size === 0 ? undefined : this.#keyMap.get(k);
if (index === undefined) {
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 {
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;
}
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 (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;
}
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;
}
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];
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;
signal?.addEventListener("abort", () => ac.abort(signal.reason), {
signal: ac.signal
});
const fetchOpts = {
signal: ac.signal,
options,
context
};
const cb = (v2, updateCache = false) => {
const { aborted } = ac.signal;
const ignoreAbort = options.ignoreFetchAbort && v2 !== 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);
}
const bf2 = p;
if (this.#valList[index] === p) {
if (v2 === undefined) {
if (bf2.__staleWhileFetching) {
this.#valList[index] = bf2.__staleWhileFetching;
} else {
this.#delete(k, "fetch");
}
} else {
if (options.status)
options.status.fetchUpdated = true;
this.set(k, v2, fetchOpts.options);
}
}
return v2;
};
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 bf2 = p;
if (this.#valList[index] === p) {
const del = !noDelete || bf2.__staleWhileFetching === undefined;
if (del) {
this.#delete(k, "fetch");
} else if (!allowStaleAborted) {
this.#valList[index] = bf2.__staleWhileFetching;
}
}
if (allowStale) {
if (options.status && bf2.__staleWhileFetching !== undefined) {
options.status.returnedStale = true;
}
return bf2.__staleWhileFetching;
} else if (bf2.__returned === bf2) {
throw er;
}
};
const pcall = (res, rej) => {
const fmp = this.#fetchMethod?.(k, v, fetchOpts);
if (fmp && fmp instanceof Promise) {
fmp.then((v2) => res(v2 === undefined ? undefined : v2), rej);
}
ac.signal.addEventListener("abort", () => {
if (!options.ignoreFetchAbort || options.allowStaleOnFetchAbort) {
res(undefined);
if (options.allowStaleOnFetchAbort) {
res = (v2) => cb(v2, 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) {
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 {
allowStale = this.allowStale,
updateAgeOnGet = this.updateAgeOnGet,
noDeleteOnStaleGet = this.noDeleteOnStaleGet,
ttl = this.ttl,
noDisposeOnSet = this.noDisposeOnSet,
size = 0,
sizeCalculation = this.sizeCalculation,
noUpdateTTL = this.noUpdateTTL,
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 {
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;
}
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;
}
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;
}
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";
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 (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 (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;
}
}
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() {
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);
}
}
}
}
// node_modules/path-scurry/dist/esm/index.js
import { posix, win32 } from "node:path";
import { fileURLToPath } from "node:url";
import { lstatSync, readdir as readdirCB, readdirSync, readlinkSync, realpathSync as rps } from "fs";
import * as actualFS from "node:fs";
import { lstat, readdir, readlink, realpath } from "node:fs/promises";
// node_modules/minipass/dist/esm/index.js
import { EventEmitter } from "node:events";
import Stream from "node:stream";
import { StringDecoder } from "node:string_decoder";
var proc = typeof process === "object" && process ? process : {
stdout: null,
stderr: null
};
var isStream = (s) => !!s && typeof s === "object" && (s instanceof Minipass || s instanceof Stream || isReadable(s) || isWritable(s));
var isReadable = (s) => !!s && typeof s === "object" && s instanceof EventEmitter && typeof s.pipe === "function" && s.pipe !== Stream.Writable.prototype.pipe;
var isWritable = (s) => !!s && typeof s === "object" && s instanceof EventEmitter && typeof s.write === "function" && typeof s.end === "function";
var EOF = Symbol("EOF");
var MAYBE_EMIT_END = Symbol("maybeEmitEnd");
var EMITTED_END = Symbol("emittedEnd");
var EMITTING_END = Symbol("emittingEnd");
var EMITTED_ERROR = Symbol("emittedError");
var CLOSED = Symbol("closed");
var READ = Symbol("read");
var FLUSH = Symbol("flush");
var FLUSHCHUNK = Symbol("flushChunk");
var ENCODING = Symbol("encoding");
var DECODER = Symbol("decoder");
var FLOWING = Symbol("flowing");
var PAUSED = Symbol("paused");
var RESUME = Symbol("resume");
var BUFFER = Symbol("buffer");
var PIPES = Symbol("pipes");
var BUFFERLENGTH = Symbol("bufferLength");
var BUFFERPUSH = Symbol("bufferPush");
var BUFFERSHIFT = Symbol("bufferShift");
var OBJECTMODE = Symbol("objectMode");
var DESTROYED = Symbol("destroyed");
var ERROR = Symbol("error");
var EMITDATA = Symbol("emitData");
var EMITEND = Symbol("emitEnd");
var EMITEND2 = Symbol("emitEnd2");
var ASYNC = Symbol("async");
var ABORT = Symbol("abort");
var ABORTED = Symbol("aborted");
var SIGNAL = Symbol("signal");
var DATALISTENERS = Symbol("dataListeners");
var DISCARDED = Symbol("discarded");
var defer = (fn) => Promise.resolve().then(fn);
var nodefer = (fn) => fn();
var isEndish = (ev) => ev === "end" || ev === "finish" || ev === "prefinish";
var isArrayBufferLike = (b) => b instanceof ArrayBuffer || !!b && typeof b === "object" && b.constructor && b.constructor.name === "ArrayBuffer" && b.byteLength >= 0;
var isArrayBufferView = (b) => !Buffer.isBuffer(b) && ArrayBuffer.isView(b);
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);
}
proxyErrors(_er) {}
end() {
this.unpipe();
if (this.opts.end)
this.dest.end();
}
}
class PipeProxyErrors extends Pipe {
unpipe() {
this.src.removeListener("error", this.proxyErrors);
super.unpipe();
}
constructor(src, dest, opts) {
super(src, dest, opts);
this.proxyErrors = (er) => dest.emit("error", er);
src.on("error", this.proxyErrors);
}
}
var isObjectModeOptions = (o) => !!o.objectMode;
var isEncodingOptions = (o) => !o.objectMode && !!o.encoding && o.encoding !== "buffer";
class Minipass extends 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;
writable = true;
readable = true;
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 StringDecoder(this[ENCODING]) : null;
if (options && options.debugExposeBuffer === true) {
Object.defineProperty(this, "buffer", { get: () => this[BUFFER] });
}
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]());
}
}
}
get bufferLength() {
return this[BUFFERLENGTH];
}
get encoding() {
return this[ENCODING];
}
set encoding(_enc) {
throw new Error("Encoding must be set at instantiation time");
}
setEncoding(_enc) {
throw new Error("Encoding must be set at instantiation time");
}
get objectMode() {
return this[OBJECTMODE];
}
set objectMode(_om) {
throw new Error("objectMode must be set at instantiation time");
}
get ["async"]() {
return this[ASYNC];
}
set ["async"](a) {
this[ASYNC] = this[ASYNC] || !!a;
}
[ABORT]() {
this[ABORTED] = true;
this.emit("abort", this[SIGNAL]?.reason);
this.destroy(this[SIGNAL]?.reason);
}
get aborted() {
return this[ABORTED];
}
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;
if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {
if (isArrayBufferView(chunk)) {
chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
} else if (isArrayBufferLike(chunk)) {
chunk = Buffer.from(chunk);
} else if (typeof chunk !== "string") {
throw new Error("Non-contiguous data written to non-objectMode stream");
}
}
if (this[OBJECTMODE]) {
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];
}
if (!chunk.length) {
if (this[BUFFERLENGTH] !== 0)
this.emit("readable");
if (cb)
fn(cb);
return this[FLOWING];
}
if (typeof chunk === "string" && !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) {
chunk = Buffer.from(chunk, encoding);
}
if (Buffer.isBuffer(chunk) && this[ENCODING]) {
chunk = this[DECODER].write(chunk);
}
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];
}
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]) {
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 (this[FLOWING] || !this[PAUSED])
this[MAYBE_EMIT_END]();
return this;
}
[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() {
return this[RESUME]();
}
pause() {
this[FLOWING] = false;
this[PAUSED] = true;
this[DISCARDED] = false;
}
get destroyed() {
return this[DESTROYED];
}
get flowing() {
return this[FLOWING];
}
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(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;
if (ended) {
if (opts.end)
dest.end();
} else {
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;
}
unpipe(dest) {
const p = this[PIPES].find((p2) => p2.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();
}
}
addListener(ev, handler) {
return this.on(ev, handler);
}
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;
}
removeListener(ev, handler) {
return this.off(ev, handler);
}
off(ev, handler) {
const ret = super.off(ev, handler);
if (ev === "data") {
this[DATALISTENERS] = this.listeners("data").length;
if (this[DATALISTENERS] === 0 && !this[DISCARDED] && !this[PIPES].length) {
this[FLOWING] = false;
}
}
return ret;
}
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;
}
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;
}
}
emit(ev, ...args) {
const data = args[0];
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;
if (!this[EMITTED_END] && !this[DESTROYED])
return false;
const ret2 = super.emit("close");
this.removeAllListeners("close");
return ret2;
} else if (ev === "error") {
this[EMITTED_ERROR] = data;
super.emit(ERROR, data);
const ret2 = !this[SIGNAL] || this.listeners("error").length ? super.emit("error", data) : false;
this[MAYBE_EMIT_END]();
return ret2;
} else if (ev === "resume") {
const ret2 = super.emit("resume");
this[MAYBE_EMIT_END]();
return ret2;
} else if (ev === "finish" || ev === "prefinish") {
const ret2 = super.emit(ev);
this.removeAllListeners(ev);
return ret2;
}
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;
}
async collect() {
const buf = Object.assign([], {
dataLength: 0
});
if (!this[OBJECTMODE])
buf.dataLength = 0;
const p = this.promise();
this.on("data", (c) => {
buf.push(c);
if (!this[OBJECTMODE])
buf.dataLength += c.length;
});
await p;
return buf;
}
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);
}
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());
});
}
[Symbol.asyncIterator]() {
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((res2, rej) => {
reject = rej;
resolve = res2;
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.iterator]() {
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;
}
};
}
destroy(er) {
if (this[DESTROYED]) {
if (er)
this.emit("error", er);
else
this.emit(DESTROYED);
return this;
}
this[DESTROYED] = true;
this[DISCARDED] = true;
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);
else
this.emit(DESTROYED);
return this;
}
static get isStream() {
return isStream;
}
}
// node_modules/path-scurry/dist/esm/index.js
var realpathSync = rps.native;
var defaultFS = {
lstatSync,
readdir: readdirCB,
readdirSync,
readlinkSync,
realpathSync,
promises: {
lstat,
readdir,
readlink,
realpath
}
};
var fsFromOption = (fsOption) => !fsOption || fsOption === defaultFS || fsOption === actualFS ? defaultFS : {
...defaultFS,
...fsOption,
promises: {
...defaultFS.promises,
...fsOption.promises || {}
}
};
var uncDriveRegexp = /^\\\\\?\\([a-z]:)\\?$/i;
var uncToDrive = (rootPath) => rootPath.replace(/\//g, "\\").replace(uncDriveRegexp, "$1\\");
var eitherSep = /[\\\/]/;
var UNKNOWN = 0;
var IFIFO = 1;
var IFCHR = 2;
var IFDIR = 4;
var IFBLK = 6;
var IFREG = 8;
var IFLNK = 10;
var IFSOCK = 12;
var IFMT = 15;
var IFMT_UNKNOWN = ~IFMT;
var READDIR_CALLED = 16;
var LSTAT_CALLED = 32;
var ENOTDIR = 64;
var ENOENT = 128;
var ENOREADLINK = 256;
var ENOREALPATH = 512;
var ENOCHILD = ENOTDIR | ENOENT | ENOREALPATH;
var TYPEMASK = 1023;
var entToType = (s) => s.isFile() ? IFREG : s.isDirectory() ? IFDIR : s.isSymbolicLink() ? IFLNK : s.isCharacterDevice() ? IFCHR : s.isBlockDevice() ? IFBLK : s.isSocket() ? IFSOCK : s.isFIFO() ? IFIFO : UNKNOWN;
var normalizeCache = new Map;
var normalize = (s) => {
const c = normalizeCache.get(s);
if (c)
return c;
const n = s.normalize("NFKD");
normalizeCache.set(s, n);
return n;
};
var normalizeNocaseCache = new Map;
var normalizeNocase = (s) => {
const c = normalizeNocaseCache.get(s);
if (c)
return c;
const n = normalize(s.toLowerCase());
normalizeNocaseCache.set(s, n);
return n;
};
class ResolveCache extends LRUCache {
constructor() {
super({ max: 256 });
}
}
class ChildrenCache extends LRUCache {
constructor(maxSize = 16 * 1024) {
super({
maxSize,
sizeCalculation: (a) => a.length + 1
});
}
}
var setAsCwd = Symbol("PathScurry setAsCwd");
class PathBase {
name;
root;
roots;
parent;
nocase;
isCWD = false;
#fs;
#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;
get parentPath() {
return (this.parent || this).fullpath();
}
get path() {
return this.parentPath;
}
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);
}
}
depth() {
if (this.#depth !== undefined)
return this.#depth;
if (!this.parent)
return this.#depth = 0;
return this.#depth = this.parent.depth() + 1;
}
childrenCache() {
return this.#children;
}
resolve(path2) {
if (!path2) {
return this;
}
const rootPath = this.getRootString(path2);
const dir = path2.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;
}
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;
}
child(pathPart, opts) {
if (pathPart === "" || pathPart === ".") {
return this;
}
if (pathPart === "..") {
return this.parent || this;
}
const children = this.children();
const name = this.nocase ? normalizeNocase(pathPart) : normalize(pathPart);
for (const p of children) {
if (p.#matchName === name) {
return p;
}
}
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;
}
children.push(pchild);
return pchild;
}
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;
}
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;
}
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;
}
fullpathPosix() {
if (this.#fullpathPosix !== undefined)
return this.#fullpathPosix;
if (this.sep === "/")
return this.#fullpathPosix = this.fullpath();
if (!this.parent) {
const p2 = this.fullpath().replace(/\\/g, "/");
if (/^[a-z]:\//i.test(p2)) {
return this.#fullpathPosix = `//?/${p2}`;
} else {
return this.#fullpathPosix = p2;
}
}
const p = this.parent;
const pfpp = p.fullpathPosix();
const fpp = pfpp + (!pfpp || !p.parent ? "" : "/") + this.name;
return this.#fullpathPosix = fpp;
}
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" : this.isSocket() ? "Socket" : "Unknown";
}
isFile() {
return (this.#type & IFMT) === IFREG;
}
isDirectory() {
return (this.#type & IFMT) === IFDIR;
}
isCharacterDevice() {
return (this.#type & IFMT) === IFCHR;
}
isBlockDevice() {
return (this.#type & IFMT) === IFBLK;
}
isFIFO() {
return (this.#type & IFMT) === IFIFO;
}
isSocket() {
return (this.#type & IFMT) === IFSOCK;
}
isSymbolicLink() {
return (this.#type & IFLNK) === IFLNK;
}
lstatCached() {
return this.#type & LSTAT_CALLED ? this : undefined;
}
readlinkCached() {
return this.#linkTarget;
}
realpathCached() {
return this.#realpath;
}
readdirCached() {
const children = this.children();
return children.slice(0, children.provisional);
}
canReadlink() {
if (this.#linkTarget)
return true;
if (!this.parent)
return false;
const ifmt = this.#type & IFMT;
return !(ifmt !== UNKNOWN && ifmt !== IFLNK || this.#type & ENOREADLINK || this.#type & ENOENT);
}
calledReaddir() {
return !!(this.#type & READDIR_CALLED);
}
isENOENT() {
return !!(this.#type & ENOENT);
}
isNamed(n) {
return !this.nocase ? this.#matchName === normalize(n) : this.#matchName === normalizeNocase(n);
}
async readlink() {
const target = this.#linkTarget;
if (target) {
return target;
}
if (!this.canReadlink()) {
return;
}
if (!this.parent) {
return;
}
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;
}
}
readlinkSync() {
const target = this.#linkTarget;
if (target) {
return target;
}
if (!this.canReadlink()) {
return;
}
if (!this.parent) {
return;
}
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;
}
}
#readdirSuccess(children) {
this.#type |= READDIR_CALLED;
for (let p = children.provisional;p < children.length; p++) {
const c = children[p];
if (c)
c.#markENOENT();
}
}
#markENOENT() {
if (this.#type & ENOENT)
return;
this.#type = (this.#type | ENOENT) & IFMT_UNKNOWN;
this.#markChildrenENOENT();
}
#markChildrenENOENT() {
const children = this.children();
children.provisional = 0;
for (const p of children) {
p.#markENOENT();
}
}
#markENOREALPATH() {
this.#type |= ENOREALPATH;
this.#markENOTDIR();
}
#markENOTDIR() {
if (this.#type & ENOTDIR)
return;
let t = this.#type;
if ((t & IFMT) === IFDIR)
t &= IFMT_UNKNOWN;
this.#type = t | ENOTDIR;
this.#markChildrenENOENT();
}
#readdirFail(code = "") {
if (code === "ENOTDIR" || code === "EPERM") {
this.#markENOTDIR();
} else if (code === "ENOENT") {
this.#markENOENT();
} else {
this.children().provisional = 0;
}
}
#lstatFail(code = "") {
if (code === "ENOTDIR") {
const p = this.parent;
p.#markENOTDIR();
} else if (code === "ENOENT") {
this.#markENOENT();
}
}
#readlinkFail(code = "") {
let ter = this.#type;
ter |= ENOREADLINK;
if (code === "ENOENT")
ter |= ENOENT;
if (code === "EINVAL" || code === "UNKNOWN") {
ter &= IFMT_UNKNOWN;
}
this.#type = ter;
if (code === "ENOTDIR" && this.parent) {
this.parent.#markENOTDIR();
}
}
#readdirAddChild(e, c) {
return this.#readdirMaybePromoteChild(e, c) || this.#readdirAddNewChild(e, c);
}
#readdirAddNewChild(e, c) {
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;
p.#type = p.#type & IFMT_UNKNOWN | entToType(e);
if (v !== e.name)
p.name = e.name;
if (index !== c.provisional) {
if (index === c.length - 1)
c.pop();
else
c.splice(index, 1);
c.unshift(p);
}
c.provisional++;
return p;
}
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);
}
}
}
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);
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));
}
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;
}
this.#onReaddirCB.push(cb);
if (this.#readdirCBInFlight) {
return;
}
this.#readdirCBInFlight = true;
const fullpath = this.fullpath();
this.#fs.readdir(fullpath, { withFileTypes: true }, (er, entries) => {
if (er) {
this.#readdirFail(er.code);
children.provisional = 0;
} else {
for (const e of entries) {
this.#readdirAddChild(e, children);
}
this.#readdirSuccess(children);
}
this.#callOnReaddirCB(children.slice(0, children.provisional));
return;
});
}
#asyncReaddirInFlight;
async readdir() {
if (!this.canReaddir()) {
return [];
}
const children = this.children();
if (this.calledReaddir()) {
return children.slice(0, children.provisional);
}
const fullpath = this.fullpath();
if (this.#asyncReaddirInFlight) {
await this.#asyncReaddirInFlight;
} else {
let resolve = () => {};
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);
}
readdirSync() {
if (!this.canReaddir()) {
return [];
}
const children = this.children();
if (this.calledReaddir()) {
return children.slice(0, children.provisional);
}
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;
if (!(ifmt === UNKNOWN || ifmt === IFDIR || ifmt === IFLNK)) {
return false;
}
return true;
}
shouldWalk(dirs, walkFilter) {
return (this.#type & IFDIR) === IFDIR && !(this.#type & ENOCHILD) && !dirs.has(this) && (!walkFilter || walkFilter(this));
}
async realpath() {
if (this.#realpath)
return this.#realpath;
if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type)
return;
try {
const rp = await this.#fs.promises.realpath(this.fullpath());
return this.#realpath = this.resolve(rp);
} catch (_) {
this.#markENOREALPATH();
}
}
realpathSync() {
if (this.#realpath)
return this.#realpath;
if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type)
return;
try {
const rp = this.#fs.realpathSync(this.fullpath());
return this.#realpath = this.resolve(rp);
} catch (_) {
this.#markENOREALPATH();
}
}
[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("..");
}
p = oldCwd;
while (p && p.parent && !changed.has(p)) {
p.#relative = undefined;
p.#relativePosix = undefined;
p = p.parent;
}
}
}
class PathWin32 extends PathBase {
sep = "\\";
splitSep = eitherSep;
constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) {
super(name, type, root, roots, nocase, children, opts);
}
newChild(name, type = UNKNOWN, opts = {}) {
return new PathWin32(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts);
}
getRootString(path2) {
return win32.parse(path2).root;
}
getRoot(rootPath) {
rootPath = uncToDrive(rootPath.toUpperCase());
if (rootPath === this.root.name) {
return this.root;
}
for (const [compare, root] of Object.entries(this.roots)) {
if (this.sameRoot(rootPath, compare)) {
return this.roots[rootPath] = root;
}
}
return this.roots[rootPath] = new PathScurryWin32(rootPath, this).root;
}
sameRoot(rootPath, compare = this.root.name) {
rootPath = rootPath.toUpperCase().replace(/\//g, "\\").replace(uncDriveRegexp, "$1\\");
return rootPath === compare;
}
}
class PathPosix extends PathBase {
splitSep = "/";
sep = "/";
constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) {
super(name, type, root, roots, nocase, children, opts);
}
getRootString(path2) {
return path2.startsWith("/") ? "/" : "";
}
getRoot(_rootPath) {
return this.root;
}
newChild(name, type = UNKNOWN, opts = {}) {
return new PathPosix(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts);
}
}
class PathScurryBase {
root;
rootPath;
roots;
cwd;
#resolveCache;
#resolvePosixCache;
#children;
nocase;
#fs;
constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs = defaultFS } = {}) {
this.#fs = fsFromOption(fs);
if (cwd instanceof URL || cwd.startsWith("file://")) {
cwd = fileURLToPath(cwd);
}
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(sep2);
if (split.length === 1 && !split[0]) {
split.pop();
}
if (nocase === undefined) {
throw new TypeError("must provide nocase setting to PathScurryBase ctor");
}
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;
}
depth(path2 = this.cwd) {
if (typeof path2 === "string") {
path2 = this.cwd.resolve(path2);
}
return path2.depth();
}
childrenCache() {
return this.#children;
}
resolve(...paths) {
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;
}
resolvePosix(...paths) {
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;
}
relative(entry = this.cwd) {
if (typeof entry === "string") {
entry = this.cwd.resolve(entry);
}
return entry.relative();
}
relativePosix(entry = this.cwd) {
if (typeof entry === "string") {
entry = this.cwd.resolve(entry);
}
return entry.relativePosix();
}
basename(entry = this.cwd) {
if (typeof entry === "string") {
entry = this.cwd.resolve(entry);
}
return entry.name;
}
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);
}
}
async lstat(entry = this.cwd) {
if (typeof entry === "string") {
entry = this.cwd.resolve(entry);
}
return entry.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: filter2, walkFilter } = opts;
const results = [];
if (!filter2 || filter2(entry)) {
results.push(withFileTypes ? entry : entry.fullpath());
}
const dirs = new Set;
const walk = (dir, cb) => {
dirs.add(dir);
dir.readdirCB((er, entries) => {
if (er) {
return cb(er);
}
let len = entries.length;
if (!len)
return cb();
const next = () => {
if (--len === 0) {
cb();
}
};
for (const e of entries) {
if (!filter2 || filter2(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);
};
const start = entry;
return new Promise((res, rej) => {
walk(start, (er) => {
if (er)
return rej(er);
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: filter2, walkFilter } = opts;
const results = [];
if (!filter2 || filter2(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 (!filter2 || filter2(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;
}
[Symbol.asyncIterator]() {
return this.iterate();
}
iterate(entry = this.cwd, options = {}) {
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]();
}
[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: filter2, walkFilter } = opts;
if (!filter2 || filter2(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 (!filter2 || filter2(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: filter2, walkFilter } = opts;
const results = new Minipass({ objectMode: true });
if (!filter2 || filter2(entry)) {
results.write(withFileTypes ? entry : entry.fullpath());
}
const dirs = new Set;
const queue = [entry];
let processing = 0;
const process2 = () => {
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) => {
if (er)
return results.emit("error", er);
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 && (!filter2 || filter2(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", process2);
} else if (!sync) {
process2();
}
};
let sync = true;
dir.readdirCB(onReaddir, true);
sync = false;
}
};
process2();
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: filter2, walkFilter } = opts;
const results = new Minipass({ objectMode: true });
const dirs = new Set;
if (!filter2 || filter2(entry)) {
results.write(withFileTypes ? entry : entry.fullpath());
}
const queue = [entry];
let processing = 0;
const process2 = () => {
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 (!filter2 || filter2(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", process2);
};
process2();
return results;
}
chdir(path2 = this.cwd) {
const oldCwd = this.cwd;
this.cwd = typeof path2 === "string" ? this.cwd.resolve(path2) : path2;
this.cwd[setAsCwd](oldCwd);
}
}
class PathScurryWin32 extends PathScurryBase {
sep = "\\";
constructor(cwd = process.cwd(), opts = {}) {
const { nocase = true } = opts;
super(cwd, win32, "\\", { ...opts, nocase });
this.nocase = nocase;
for (let p = this.cwd;p; p = p.parent) {
p.nocase = this.nocase;
}
}
parseRootPath(dir) {
return win32.parse(dir).root.toUpperCase();
}
newRoot(fs) {
return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs });
}
isAbsolute(p) {
return p.startsWith("/") || p.startsWith("\\") || /^[a-z]:(\/|\\)/i.test(p);
}
}
class PathScurryPosix extends PathScurryBase {
sep = "/";
constructor(cwd = process.cwd(), opts = {}) {
const { nocase = false } = opts;
super(cwd, posix, "/", { ...opts, nocase });
this.nocase = nocase;
}
parseRootPath(_dir) {
return "/";
}
newRoot(fs) {
return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs });
}
isAbsolute(p) {
return p.startsWith("/");
}
}
class PathScurryDarwin extends PathScurryPosix {
constructor(cwd = process.cwd(), opts = {}) {
const { nocase = true } = opts;
super(cwd, { ...opts, nocase });
}
}
var Path = process.platform === "win32" ? PathWin32 : PathPosix;
var PathScurry = process.platform === "win32" ? PathScurryWin32 : process.platform === "darwin" ? PathScurryDarwin : PathScurryPosix;
// node_modules/glob/dist/esm/pattern.js
var isPatternList = (pl) => pl.length >= 1;
var isGlobList = (gl) => gl.length >= 1;
class Pattern {
#patternList;
#globList;
#index;
length;
#platform;
#rest;
#globString;
#isDrive;
#isUNC;
#isAbsolute;
#followGlobstar = true;
constructor(patternList, globList, index, platform) {
if (!isPatternList(patternList)) {
throw new TypeError("empty pattern list");
}
if (!isGlobList(globList)) {
throw new TypeError("empty glob list");
}
if (globList.length !== patternList.length) {
throw new TypeError("mismatched pattern list and glob list lengths");
}
this.length = patternList.length;
if (index < 0 || index >= this.length) {
throw new TypeError("index out of range");
}
this.#patternList = patternList;
this.#globList = globList;
this.#index = index;
this.#platform = platform;
if (this.#index === 0) {
if (this.isUNC()) {
const [p0, p1, p2, p3, ...prest] = this.#patternList;
const [g0, g1, g2, g3, ...grest] = this.#globList;
if (prest[0] === "") {
prest.shift();
grest.shift();
}
const p = [p0, p1, p2, p3, ""].join("/");
const g = [g0, g1, g2, g3, ""].join("/");
this.#patternList = [p, ...prest];
this.#globList = [g, ...grest];
this.length = this.#patternList.length;
} else if (this.isDrive() || this.isAbsolute()) {
const [p1, ...prest] = this.#patternList;
const [g1, ...grest] = this.#globList;
if (prest[0] === "") {
prest.shift();
grest.shift();
}
const p = p1 + "/";
const g = g1 + "/";
this.#patternList = [p, ...prest];
this.#globList = [g, ...grest];
this.length = this.#patternList.length;
}
}
}
pattern() {
return this.#patternList[this.#index];
}
isString() {
return typeof this.#patternList[this.#index] === "string";
}
isGlobstar() {
return this.#patternList[this.#index] === GLOBSTAR;
}
isRegExp() {
return this.#patternList[this.#index] instanceof RegExp;
}
globString() {
return this.#globString = this.#globString || (this.#index === 0 ? this.isAbsolute() ? this.#globList[0] + this.#globList.slice(1).join("/") : this.#globList.join("/") : this.#globList.slice(this.#index).join("/"));
}
hasMore() {
return this.length > this.#index + 1;
}
rest() {
if (this.#rest !== undefined)
return this.#rest;
if (!this.hasMore())
return this.#rest = null;
this.#rest = new Pattern(this.#patternList, this.#globList, this.#index + 1, this.#platform);
this.#rest.#isAbsolute = this.#isAbsolute;
this.#rest.#isUNC = this.#isUNC;
this.#rest.#isDrive = this.#isDrive;
return this.#rest;
}
isUNC() {
const pl = this.#patternList;
return this.#isUNC !== undefined ? this.#isUNC : this.#isUNC = this.#platform === "win32" && this.#index === 0 && pl[0] === "" && pl[1] === "" && typeof pl[2] === "string" && !!pl[2] && typeof pl[3] === "string" && !!pl[3];
}
isDrive() {
const pl = this.#patternList;
return this.#isDrive !== undefined ? this.#isDrive : this.#isDrive = this.#platform === "win32" && this.#index === 0 && this.length > 1 && typeof pl[0] === "string" && /^[a-z]:$/i.test(pl[0]);
}
isAbsolute() {
const pl = this.#patternList;
return this.#isAbsolute !== undefined ? this.#isAbsolute : this.#isAbsolute = pl[0] === "" && pl.length > 1 || this.isDrive() || this.isUNC();
}
root() {
const p = this.#patternList[0];
return typeof p === "string" && this.isAbsolute() && this.#index === 0 ? p : "";
}
checkFollowGlobstar() {
return !(this.#index === 0 || !this.isGlobstar() || !this.#followGlobstar);
}
markFollowGlobstar() {
if (this.#index === 0 || !this.isGlobstar() || !this.#followGlobstar)
return false;
this.#followGlobstar = false;
return true;
}
}
// node_modules/glob/dist/esm/ignore.js
var defaultPlatform2 = typeof process === "object" && process && typeof process.platform === "string" ? process.platform : "linux";
class Ignore {
relative;
relativeChildren;
absolute;
absoluteChildren;
platform;
mmopts;
constructor(ignored, { nobrace, nocase, noext, noglobstar, platform = defaultPlatform2 }) {
this.relative = [];
this.absolute = [];
this.relativeChildren = [];
this.absoluteChildren = [];
this.platform = platform;
this.mmopts = {
dot: true,
nobrace,
nocase,
noext,
noglobstar,
optimizationLevel: 2,
platform,
nocomment: true,
nonegate: true
};
for (const ign of ignored)
this.add(ign);
}
add(ign) {
const mm = new Minimatch(ign, this.mmopts);
for (let i = 0;i < mm.set.length; i++) {
const parsed = mm.set[i];
const globParts = mm.globParts[i];
if (!parsed || !globParts) {
throw new Error("invalid pattern object");
}
while (parsed[0] === "." && globParts[0] === ".") {
parsed.shift();
globParts.shift();
}
const p = new Pattern(parsed, globParts, 0, this.platform);
const m = new Minimatch(p.globString(), this.mmopts);
const children = globParts[globParts.length - 1] === "**";
const absolute = p.isAbsolute();
if (absolute)
this.absolute.push(m);
else
this.relative.push(m);
if (children) {
if (absolute)
this.absoluteChildren.push(m);
else
this.relativeChildren.push(m);
}
}
}
ignored(p) {
const fullpath = p.fullpath();
const fullpaths = `${fullpath}/`;
const relative = p.relative() || ".";
const relatives = `${relative}/`;
for (const m of this.relative) {
if (m.match(relative) || m.match(relatives))
return true;
}
for (const m of this.absolute) {
if (m.match(fullpath) || m.match(fullpaths))
return true;
}
return false;
}
childrenIgnored(p) {
const fullpath = p.fullpath() + "/";
const relative = (p.relative() || ".") + "/";
for (const m of this.relativeChildren) {
if (m.match(relative))
return true;
}
for (const m of this.absoluteChildren) {
if (m.match(fullpath))
return true;
}
return false;
}
}
// node_modules/glob/dist/esm/processor.js
class HasWalkedCache {
store;
constructor(store = new Map) {
this.store = store;
}
copy() {
return new HasWalkedCache(new Map(this.store));
}
hasWalked(target, pattern) {
return this.store.get(target.fullpath())?.has(pattern.globString());
}
storeWalked(target, pattern) {
const fullpath = target.fullpath();
const cached = this.store.get(fullpath);
if (cached)
cached.add(pattern.globString());
else
this.store.set(fullpath, new Set([pattern.globString()]));
}
}
class MatchRecord {
store = new Map;
add(target, absolute, ifDir) {
const n = (absolute ? 2 : 0) | (ifDir ? 1 : 0);
const current = this.store.get(target);
this.store.set(target, current === undefined ? n : n & current);
}
entries() {
return [...this.store.entries()].map(([path2, n]) => [
path2,
!!(n & 2),
!!(n & 1)
]);
}
}
class SubWalks {
store = new Map;
add(target, pattern) {
if (!target.canReaddir()) {
return;
}
const subs = this.store.get(target);
if (subs) {
if (!subs.find((p) => p.globString() === pattern.globString())) {
subs.push(pattern);
}
} else
this.store.set(target, [pattern]);
}
get(target) {
const subs = this.store.get(target);
if (!subs) {
throw new Error("attempting to walk unknown path");
}
return subs;
}
entries() {
return this.keys().map((k) => [k, this.store.get(k)]);
}
keys() {
return [...this.store.keys()].filter((t) => t.canReaddir());
}
}
class Processor {
hasWalkedCache;
matches = new MatchRecord;
subwalks = new SubWalks;
patterns;
follow;
dot;
opts;
constructor(opts, hasWalkedCache) {
this.opts = opts;
this.follow = !!opts.follow;
this.dot = !!opts.dot;
this.hasWalkedCache = hasWalkedCache ? hasWalkedCache.copy() : new HasWalkedCache;
}
processPatterns(target, patterns) {
this.patterns = patterns;
const processingSet = patterns.map((p) => [target, p]);
for (let [t, pattern] of processingSet) {
this.hasWalkedCache.storeWalked(t, pattern);
const root = pattern.root();
const absolute = pattern.isAbsolute() && this.opts.absolute !== false;
if (root) {
t = t.resolve(root === "/" && this.opts.root !== undefined ? this.opts.root : root);
const rest2 = pattern.rest();
if (!rest2) {
this.matches.add(t, true, false);
continue;
} else {
pattern = rest2;
}
}
if (t.isENOENT())
continue;
let p;
let rest;
let changed = false;
while (typeof (p = pattern.pattern()) === "string" && (rest = pattern.rest())) {
const c = t.resolve(p);
t = c;
pattern = rest;
changed = true;
}
p = pattern.pattern();
rest = pattern.rest();
if (changed) {
if (this.hasWalkedCache.hasWalked(t, pattern))
continue;
this.hasWalkedCache.storeWalked(t, pattern);
}
if (typeof p === "string") {
const ifDir = p === ".." || p === "" || p === ".";
this.matches.add(t.resolve(p), absolute, ifDir);
continue;
} else if (p === GLOBSTAR) {
if (!t.isSymbolicLink() || this.follow || pattern.checkFollowGlobstar()) {
this.subwalks.add(t, pattern);
}
const rp = rest?.pattern();
const rrest = rest?.rest();
if (!rest || (rp === "" || rp === ".") && !rrest) {
this.matches.add(t, absolute, rp === "" || rp === ".");
} else {
if (rp === "..") {
const tp = t.parent || t;
if (!rrest)
this.matches.add(tp, absolute, true);
else if (!this.hasWalkedCache.hasWalked(tp, rrest)) {
this.subwalks.add(tp, rrest);
}
}
}
} else if (p instanceof RegExp) {
this.subwalks.add(t, pattern);
}
}
return this;
}
subwalkTargets() {
return this.subwalks.keys();
}
child() {
return new Processor(this.opts, this.hasWalkedCache);
}
filterEntries(parent, entries) {
const patterns = this.subwalks.get(parent);
const results = this.child();
for (const e of entries) {
for (const pattern of patterns) {
const absolute = pattern.isAbsolute();
const p = pattern.pattern();
const rest = pattern.rest();
if (p === GLOBSTAR) {
results.testGlobstar(e, pattern, rest, absolute);
} else if (p instanceof RegExp) {
results.testRegExp(e, p, rest, absolute);
} else {
results.testString(e, p, rest, absolute);
}
}
}
return results;
}
testGlobstar(e, pattern, rest, absolute) {
if (this.dot || !e.name.startsWith(".")) {
if (!pattern.hasMore()) {
this.matches.add(e, absolute, false);
}
if (e.canReaddir()) {
if (this.follow || !e.isSymbolicLink()) {
this.subwalks.add(e, pattern);
} else if (e.isSymbolicLink()) {
if (rest && pattern.checkFollowGlobstar()) {
this.subwalks.add(e, rest);
} else if (pattern.markFollowGlobstar()) {
this.subwalks.add(e, pattern);
}
}
}
}
if (rest) {
const rp = rest.pattern();
if (typeof rp === "string" && rp !== ".." && rp !== "" && rp !== ".") {
this.testString(e, rp, rest.rest(), absolute);
} else if (rp === "..") {
const ep = e.parent || e;
this.subwalks.add(ep, rest);
} else if (rp instanceof RegExp) {
this.testRegExp(e, rp, rest.rest(), absolute);
}
}
}
testRegExp(e, p, rest, absolute) {
if (!p.test(e.name))
return;
if (!rest) {
this.matches.add(e, absolute, false);
} else {
this.subwalks.add(e, rest);
}
}
testString(e, p, rest, absolute) {
if (!e.isNamed(p))
return;
if (!rest) {
this.matches.add(e, absolute, false);
} else {
this.subwalks.add(e, rest);
}
}
}
// node_modules/glob/dist/esm/walker.js
var makeIgnore = (ignore, opts) => typeof ignore === "string" ? new Ignore([ignore], opts) : Array.isArray(ignore) ? new Ignore(ignore, opts) : ignore;
class GlobUtil {
path;
patterns;
opts;
seen = new Set;
paused = false;
aborted = false;
#onResume = [];
#ignore;
#sep;
signal;
maxDepth;
includeChildMatches;
constructor(patterns, path2, opts) {
this.patterns = patterns;
this.path = path2;
this.opts = opts;
this.#sep = !opts.posix && opts.platform === "win32" ? "\\" : "/";
this.includeChildMatches = opts.includeChildMatches !== false;
if (opts.ignore || !this.includeChildMatches) {
this.#ignore = makeIgnore(opts.ignore ?? [], opts);
if (!this.includeChildMatches && typeof this.#ignore.add !== "function") {
const m = "cannot ignore child matches, ignore lacks add() method.";
throw new Error(m);
}
}
this.maxDepth = opts.maxDepth || Infinity;
if (opts.signal) {
this.signal = opts.signal;
this.signal.addEventListener("abort", () => {
this.#onResume.length = 0;
});
}
}
#ignored(path2) {
return this.seen.has(path2) || !!this.#ignore?.ignored?.(path2);
}
#childrenIgnored(path2) {
return !!this.#ignore?.childrenIgnored?.(path2);
}
pause() {
this.paused = true;
}
resume() {
if (this.signal?.aborted)
return;
this.paused = false;
let fn = undefined;
while (!this.paused && (fn = this.#onResume.shift())) {
fn();
}
}
onResume(fn) {
if (this.signal?.aborted)
return;
if (!this.paused) {
fn();
} else {
this.#onResume.push(fn);
}
}
async matchCheck(e, ifDir) {
if (ifDir && this.opts.nodir)
return;
let rpc;
if (this.opts.realpath) {
rpc = e.realpathCached() || await e.realpath();
if (!rpc)
return;
e = rpc;
}
const needStat = e.isUnknown() || this.opts.stat;
const s = needStat ? await e.lstat() : e;
if (this.opts.follow && this.opts.nodir && s?.isSymbolicLink()) {
const target = await s.realpath();
if (target && (target.isUnknown() || this.opts.stat)) {
await target.lstat();
}
}
return this.matchCheckTest(s, ifDir);
}
matchCheckTest(e, ifDir) {
return e && (this.maxDepth === Infinity || e.depth() <= this.maxDepth) && (!ifDir || e.canReaddir()) && (!this.opts.nodir || !e.isDirectory()) && (!this.opts.nodir || !this.opts.follow || !e.isSymbolicLink() || !e.realpathCached()?.isDirectory()) && !this.#ignored(e) ? e : undefined;
}
matchCheckSync(e, ifDir) {
if (ifDir && this.opts.nodir)
return;
let rpc;
if (this.opts.realpath) {
rpc = e.realpathCached() || e.realpathSync();
if (!rpc)
return;
e = rpc;
}
const needStat = e.isUnknown() || this.opts.stat;
const s = needStat ? e.lstatSync() : e;
if (this.opts.follow && this.opts.nodir && s?.isSymbolicLink()) {
const target = s.realpathSync();
if (target && (target?.isUnknown() || this.opts.stat)) {
target.lstatSync();
}
}
return this.matchCheckTest(s, ifDir);
}
matchFinish(e, absolute) {
if (this.#ignored(e))
return;
if (!this.includeChildMatches && this.#ignore?.add) {
const ign = `${e.relativePosix()}/**`;
this.#ignore.add(ign);
}
const abs = this.opts.absolute === undefined ? absolute : this.opts.absolute;
this.seen.add(e);
const mark = this.opts.mark && e.isDirectory() ? this.#sep : "";
if (this.opts.withFileTypes) {
this.matchEmit(e);
} else if (abs) {
const abs2 = this.opts.posix ? e.fullpathPosix() : e.fullpath();
this.matchEmit(abs2 + mark);
} else {
const rel = this.opts.posix ? e.relativePosix() : e.relative();
const pre = this.opts.dotRelative && !rel.startsWith(".." + this.#sep) ? "." + this.#sep : "";
this.matchEmit(!rel ? "." + mark : pre + rel + mark);
}
}
async match(e, absolute, ifDir) {
const p = await this.matchCheck(e, ifDir);
if (p)
this.matchFinish(p, absolute);
}
matchSync(e, absolute, ifDir) {
const p = this.matchCheckSync(e, ifDir);
if (p)
this.matchFinish(p, absolute);
}
walkCB(target, patterns, cb) {
if (this.signal?.aborted)
cb();
this.walkCB2(target, patterns, new Processor(this.opts), cb);
}
walkCB2(target, patterns, processor, cb) {
if (this.#childrenIgnored(target))
return cb();
if (this.signal?.aborted)
cb();
if (this.paused) {
this.onResume(() => this.walkCB2(target, patterns, processor, cb));
return;
}
processor.processPatterns(target, patterns);
let tasks = 1;
const next = () => {
if (--tasks === 0)
cb();
};
for (const [m, absolute, ifDir] of processor.matches.entries()) {
if (this.#ignored(m))
continue;
tasks++;
this.match(m, absolute, ifDir).then(() => next());
}
for (const t of processor.subwalkTargets()) {
if (this.maxDepth !== Infinity && t.depth() >= this.maxDepth) {
continue;
}
tasks++;
const childrenCached = t.readdirCached();
if (t.calledReaddir())
this.walkCB3(t, childrenCached, processor, next);
else {
t.readdirCB((_, entries) => this.walkCB3(t, entries, processor, next), true);
}
}
next();
}
walkCB3(target, entries, processor, cb) {
processor = processor.filterEntries(target, entries);
let tasks = 1;
const next = () => {
if (--tasks === 0)
cb();
};
for (const [m, absolute, ifDir] of processor.matches.entries()) {
if (this.#ignored(m))
continue;
tasks++;
this.match(m, absolute, ifDir).then(() => next());
}
for (const [target2, patterns] of processor.subwalks.entries()) {
tasks++;
this.walkCB2(target2, patterns, processor.child(), next);
}
next();
}
walkCBSync(target, patterns, cb) {
if (this.signal?.aborted)
cb();
this.walkCB2Sync(target, patterns, new Processor(this.opts), cb);
}
walkCB2Sync(target, patterns, processor, cb) {
if (this.#childrenIgnored(target))
return cb();
if (this.signal?.aborted)
cb();
if (this.paused) {
this.onResume(() => this.walkCB2Sync(target, patterns, processor, cb));
return;
}
processor.processPatterns(target, patterns);
let tasks = 1;
const next = () => {
if (--tasks === 0)
cb();
};
for (const [m, absolute, ifDir] of processor.matches.entries()) {
if (this.#ignored(m))
continue;
this.matchSync(m, absolute, ifDir);
}
for (const t of processor.subwalkTargets()) {
if (this.maxDepth !== Infinity && t.depth() >= this.maxDepth) {
continue;
}
tasks++;
const children = t.readdirSync();
this.walkCB3Sync(t, children, processor, next);
}
next();
}
walkCB3Sync(target, entries, processor, cb) {
processor = processor.filterEntries(target, entries);
let tasks = 1;
const next = () => {
if (--tasks === 0)
cb();
};
for (const [m, absolute, ifDir] of processor.matches.entries()) {
if (this.#ignored(m))
continue;
this.matchSync(m, absolute, ifDir);
}
for (const [target2, patterns] of processor.subwalks.entries()) {
tasks++;
this.walkCB2Sync(target2, patterns, processor.child(), next);
}
next();
}
}
class GlobWalker extends GlobUtil {
matches = new Set;
constructor(patterns, path2, opts) {
super(patterns, path2, opts);
}
matchEmit(e) {
this.matches.add(e);
}
async walk() {
if (this.signal?.aborted)
throw this.signal.reason;
if (this.path.isUnknown()) {
await this.path.lstat();
}
await new Promise((res, rej) => {
this.walkCB(this.path, this.patterns, () => {
if (this.signal?.aborted) {
rej(this.signal.reason);
} else {
res(this.matches);
}
});
});
return this.matches;
}
walkSync() {
if (this.signal?.aborted)
throw this.signal.reason;
if (this.path.isUnknown()) {
this.path.lstatSync();
}
this.walkCBSync(this.path, this.patterns, () => {
if (this.signal?.aborted)
throw this.signal.reason;
});
return this.matches;
}
}
class GlobStream extends GlobUtil {
results;
constructor(patterns, path2, opts) {
super(patterns, path2, opts);
this.results = new Minipass({
signal: this.signal,
objectMode: true
});
this.results.on("drain", () => this.resume());
this.results.on("resume", () => this.resume());
}
matchEmit(e) {
this.results.write(e);
if (!this.results.flowing)
this.pause();
}
stream() {
const target = this.path;
if (target.isUnknown()) {
target.lstat().then(() => {
this.walkCB(target, this.patterns, () => this.results.end());
});
} else {
this.walkCB(target, this.patterns, () => this.results.end());
}
return this.results;
}
streamSync() {
if (this.path.isUnknown()) {
this.path.lstatSync();
}
this.walkCBSync(this.path, this.patterns, () => this.results.end());
return this.results;
}
}
// node_modules/glob/dist/esm/glob.js
var defaultPlatform3 = typeof process === "object" && process && typeof process.platform === "string" ? process.platform : "linux";
class Glob {
absolute;
cwd;
root;
dot;
dotRelative;
follow;
ignore;
magicalBraces;
mark;
matchBase;
maxDepth;
nobrace;
nocase;
nodir;
noext;
noglobstar;
pattern;
platform;
realpath;
scurry;
stat;
signal;
windowsPathsNoEscape;
withFileTypes;
includeChildMatches;
opts;
patterns;
constructor(pattern, opts) {
if (!opts)
throw new TypeError("glob options required");
this.withFileTypes = !!opts.withFileTypes;
this.signal = opts.signal;
this.follow = !!opts.follow;
this.dot = !!opts.dot;
this.dotRelative = !!opts.dotRelative;
this.nodir = !!opts.nodir;
this.mark = !!opts.mark;
if (!opts.cwd) {
this.cwd = "";
} else if (opts.cwd instanceof URL || opts.cwd.startsWith("file://")) {
opts.cwd = fileURLToPath2(opts.cwd);
}
this.cwd = opts.cwd || "";
this.root = opts.root;
this.magicalBraces = !!opts.magicalBraces;
this.nobrace = !!opts.nobrace;
this.noext = !!opts.noext;
this.realpath = !!opts.realpath;
this.absolute = opts.absolute;
this.includeChildMatches = opts.includeChildMatches !== false;
this.noglobstar = !!opts.noglobstar;
this.matchBase = !!opts.matchBase;
this.maxDepth = typeof opts.maxDepth === "number" ? opts.maxDepth : Infinity;
this.stat = !!opts.stat;
this.ignore = opts.ignore;
if (this.withFileTypes && this.absolute !== undefined) {
throw new Error("cannot set absolute and withFileTypes:true");
}
if (typeof pattern === "string") {
pattern = [pattern];
}
this.windowsPathsNoEscape = !!opts.windowsPathsNoEscape || opts.allowWindowsEscape === false;
if (this.windowsPathsNoEscape) {
pattern = pattern.map((p) => p.replace(/\\/g, "/"));
}
if (this.matchBase) {
if (opts.noglobstar) {
throw new TypeError("base matching requires globstar");
}
pattern = pattern.map((p) => p.includes("/") ? p : `./**/${p}`);
}
this.pattern = pattern;
this.platform = opts.platform || defaultPlatform3;
this.opts = { ...opts, platform: this.platform };
if (opts.scurry) {
this.scurry = opts.scurry;
if (opts.nocase !== undefined && opts.nocase !== opts.scurry.nocase) {
throw new Error("nocase option contradicts provided scurry option");
}
} else {
const Scurry = opts.platform === "win32" ? PathScurryWin32 : opts.platform === "darwin" ? PathScurryDarwin : opts.platform ? PathScurryPosix : PathScurry;
this.scurry = new Scurry(this.cwd, {
nocase: opts.nocase,
fs: opts.fs
});
}
this.nocase = this.scurry.nocase;
const nocaseMagicOnly = this.platform === "darwin" || this.platform === "win32";
const mmo = {
...opts,
dot: this.dot,
matchBase: this.matchBase,
nobrace: this.nobrace,
nocase: this.nocase,
nocaseMagicOnly,
nocomment: true,
noext: this.noext,
nonegate: true,
optimizationLevel: 2,
platform: this.platform,
windowsPathsNoEscape: this.windowsPathsNoEscape,
debug: !!this.opts.debug
};
const mms = this.pattern.map((p) => new Minimatch(p, mmo));
const [matchSet, globParts] = mms.reduce((set, m) => {
set[0].push(...m.set);
set[1].push(...m.globParts);
return set;
}, [[], []]);
this.patterns = matchSet.map((set, i) => {
const g = globParts[i];
if (!g)
throw new Error("invalid pattern object");
return new Pattern(set, g, 0, this.platform);
});
}
async walk() {
return [
...await new GlobWalker(this.patterns, this.scurry.cwd, {
...this.opts,
maxDepth: this.maxDepth !== Infinity ? this.maxDepth + this.scurry.cwd.depth() : Infinity,
platform: this.platform,
nocase: this.nocase,
includeChildMatches: this.includeChildMatches
}).walk()
];
}
walkSync() {
return [
...new GlobWalker(this.patterns, this.scurry.cwd, {
...this.opts,
maxDepth: this.maxDepth !== Infinity ? this.maxDepth + this.scurry.cwd.depth() : Infinity,
platform: this.platform,
nocase: this.nocase,
includeChildMatches: this.includeChildMatches
}).walkSync()
];
}
stream() {
return new GlobStream(this.patterns, this.scurry.cwd, {
...this.opts,
maxDepth: this.maxDepth !== Infinity ? this.maxDepth + this.scurry.cwd.depth() : Infinity,
platform: this.platform,
nocase: this.nocase,
includeChildMatches: this.includeChildMatches
}).stream();
}
streamSync() {
return new GlobStream(this.patterns, this.scurry.cwd, {
...this.opts,
maxDepth: this.maxDepth !== Infinity ? this.maxDepth + this.scurry.cwd.depth() : Infinity,
platform: this.platform,
nocase: this.nocase,
includeChildMatches: this.includeChildMatches
}).streamSync();
}
iterateSync() {
return this.streamSync()[Symbol.iterator]();
}
[Symbol.iterator]() {
return this.iterateSync();
}
iterate() {
return this.stream()[Symbol.asyncIterator]();
}
[Symbol.asyncIterator]() {
return this.iterate();
}
}
// node_modules/glob/dist/esm/has-magic.js
var hasMagic = (pattern, options = {}) => {
if (!Array.isArray(pattern)) {
pattern = [pattern];
}
for (const p of pattern) {
if (new Minimatch(p, options).hasMagic())
return true;
}
return false;
};
// node_modules/glob/dist/esm/index.js
function globStreamSync(pattern, options = {}) {
return new Glob(pattern, options).streamSync();
}
function globStream(pattern, options = {}) {
return new Glob(pattern, options).stream();
}
function globSync(pattern, options = {}) {
return new Glob(pattern, options).walkSync();
}
async function glob_(pattern, options = {}) {
return new Glob(pattern, options).walk();
}
function globIterateSync(pattern, options = {}) {
return new Glob(pattern, options).iterateSync();
}
function globIterate(pattern, options = {}) {
return new Glob(pattern, options).iterate();
}
var streamSync = globStreamSync;
var stream = Object.assign(globStream, { sync: globStreamSync });
var iterateSync = globIterateSync;
var iterate = Object.assign(globIterate, {
sync: globIterateSync
});
var sync = Object.assign(globSync, {
stream: globStreamSync,
iterate: globIterateSync
});
var glob = Object.assign(glob_, {
glob: glob_,
globSync,
sync,
globStream,
stream,
globStreamSync,
streamSync,
globIterate,
iterate,
globIterateSync,
iterateSync,
Glob,
hasMagic,
escape,
unescape
});
glob.glob = glob;
// src/index.ts
function printHelp() {
const txt = `
╔══════════════════════════════════════════════════════════════════════════════╗
║ PACKX - Smart File Filter ║
║ Bundle only the files you need for focused AI analysis ║
╚══════════════════════════════════════════════════════════════════════════════╝
OVERVIEW
Packx filters your repository files by content AND extension, then bundles
only matching files for AI consumption. Perfect for providing focused context
to LLMs without overwhelming them with irrelevant code.
USAGE
packx init [filename] Create a config file template
packx -s "string" [options] [repomix...] Search and bundle files
packx -f config.txt [options] [repomix...] Use a config file
╭──────────────────────────────────────────────────────────────────────────────╮
│ QUICK START │
╰──────────────────────────────────────────────────────────────────────────────╯
1. Install packx:
npm install -g packx
2. Create a search config:
packx init my-search
3. Edit the config with your patterns:
nano my-search.ini
4. Run the search:
packx -f my-search.ini -o results.md
╭──────────────────────────────────────────────────────────────────────────────╮
│ COMMON USE CASES │
╰──────────────────────────────────────────────────────────────────────────────╯
\uD83D\uDD0D FIND ALL TODOS AND FIXMES
packx -s "TODO" -s "FIXME" -s "HACK" -s "XXX"
This searches ALL common code files by default - no need to specify extensions!
\uD83D\uDCE6 BUNDLE REACT HOOKS FOR REVIEW
packx -s "useState" -s "useEffect" -s "useCallback" -e "tsx,jsx" -o hooks.md
Focus on just React/JSX files containing hooks.
\uD83D\uDC1B DEBUG WITH CONTEXT LINES
packx -s "error" -s "exception" -l 20 --style markdown
Extract only 20 lines around each error/exception - perfect for debugging!
\uD83D\uDD12 SECURITY AUDIT
packx -s "apiKey" -s "secret" -s "password" -s "token" \\
-e "js,ts,env,json" -x "test.js,spec.js" -o security.xml
Find sensitive strings, excluding test files.
\uD83D\uDCCB COPY TO CLIPBOARD
packx -s "console.log" --copy
packx -s "debugger" -c # -c is shorthand for --copy
Instantly copy results to clipboard for pasting into ChatGPT, Claude, etc.
╭──────────────────────────────────────────────────────────────────────────────╮
│ DETAILED EXAMPLES │
╰──────────────────────────────────────────────────────────────────────────────╯
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. BASIC STRING SEARCH
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Single string search across all default extensions
packx -s "localStorage"
# Multiple strings (files must contain at least ONE)
packx -s "fetch" -s "axios" -s "XMLHttpRequest"
# Strings with special characters (no escaping needed!)
packx -s "array[index]" -s "obj.prop" -s "foo(bar, baz)"
packx -s "// TODO:" -s "/* FIXME" -s "@deprecated"
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2. EXTENSION FILTERING
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Specific extensions (multiple formats supported)
packx -s "import" -e "ts,tsx" # Comma-separated
packx -s "import" -e "ts" -e "tsx" # Multiple flags
packx -s "import" -e ts -e tsx -e jsx # No quotes needed
# Exclude patterns (matched from end of filename)
packx -s "interface" -e "ts" -x "d.ts" # Exclude .d.ts files
packx -s "test" -x "spec.ts" -x "test.ts" # Exclude test files
packx -s "build" -x ".min.js" -x ".min.css" # Exclude minified
# Exclude files containing specific strings
packx -s "useState" -S "test" -S "mock" # Find useState, skip test/mock files
packx -s "API" -S "deprecated" -S "legacy" # Find API, skip deprecated/legacy
# Case-sensitive search (default is case-insensitive)
packx -s "API" -C # Match API but not api or Api
packx -s "TODO" --case-sensitive # Match TODO but not todo
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3. CONTEXT LINES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Extract only N lines around each match (not entire files!)
packx -s "TODO" -l 5 # 5 lines before & after
packx -s "error" -l 20 -o errors.md # 20 lines of context
packx -s "FIXME" --lines 10 # Long form flag
# Context windows are automatically merged when they overlap!
# If two TODOs are 3 lines apart with -l 5, you get one combined window
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
4. CONFIG FILES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Create config templates
packx init # Creates pack-config.ini
packx init todos # Creates todos.ini
packx init team-search.config # Keep custom extension if specified
# Use config files
packx -f todos.txt
packx -f api-search.txt -o api.md
packx -f hooks.txt --style markdown --compress
# Combine config with CLI args (CLI adds to config)
packx -f base.txt -s "extraSearch" -e "vue"
Example config file (todos.txt):
────────────────────────────────
[search]
TODO
FIXME
HACK
XXX
NOTE
[extensions]
# Leave empty for all defaults
# Or specify specific ones:
ts
tsx
js
jsx
[exclude]
node_modules
.min.js
dist
build
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
5. OUTPUT OPTIONS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Different output formats
packx -s "API" --style markdown -o api.md
packx -s "API" --style xml -o api.xml
packx -s "API" --style plain -o api.txt
# Copy to clipboard (multiple ways)
packx -s "bug" --copy # Long form
packx -s "bug" -c # Short form
packx -s "bug" -l 10 -c # With context + copy
# Preview mode (just list files, no bundling)
packx -s "deprecated" --preview
packx -s "legacy" -e "js" --preview
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
6. REPOMIX INTEGRATION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# All Repomix flags pass through automatically
packx -s "class" --compress --remove-comments
packx -s "function" --token-count-tree
packx -s "import" --instruction-file-path ./instructions.md
# Complex Repomix examples
packx -s "useState" -e "tsx" \\
--compress \\
--style markdown \\
--remove-comments \\
--token-count-tree \\
-o react-analysis.md
╭──────────────────────────────────────────────────────────────────────────────╮
│ REAL-WORLD WORKFLOWS │
╰──────────────────────────────────────────────────────────────────────────────╯
\uD83D\uDCF1 REACT NATIVE DEBUGGING
# Find all state management issues
packx -s "setState" -s "useState" -s "redux" -s "mobx" \\
-e "tsx,jsx" -l 30 -o state-debug.md
# Find navigation problems
packx -s "navigation" -s "navigate" -s "route" \\
-e "tsx" -x "test.tsx" --compress
\uD83D\uDD27 REFACTORING PREPARATION
# Find all deprecated patterns
packx -s "componentWillMount" -s "componentWillReceiveProps" \\
-s "componentWillUpdate" -e "jsx,tsx" -o deprecated.md
# Find all console.logs to remove
packx -s "console.log" -s "console.debug" \\
-x "test.js" --preview
\uD83C\uDFD7️ ARCHITECTURE REVIEW
# Find all API endpoints
packx -s "/api/" -s "fetch(" -s "axios" -s ".get(" -s ".post(" \\
-e "ts,tsx,js" -o api-surface.md
# Find all database queries
packx -s "SELECT" -s "INSERT" -s "UPDATE" -s "DELETE" \\
-s "mongodb" -s "mongoose" -o database-layer.md
\uD83E\uDDEA TEST COVERAGE ANALYSIS
# Find untested functions
packx -s "export function" -s "export const" -e "ts" \\
-x "test.ts" -x "spec.ts" -o possibly-untested.md
# Find all test files
packx -s "describe(" -s "test(" -s "it(" \\
-e "test.ts,spec.ts,test.js,spec.js" -o all-tests.md
\uD83D\uDE80 PERFORMANCE OPTIMIZATION
# Find potential performance issues
packx -s "forEach" -s "map" -s "filter" -s "reduce" \\
-s "for (" -s "while (" -l 20 -o loops-analysis.md
# Find all async operations
packx -s "async" -s "await" -s "Promise" -s "then(" \\
-e "ts,tsx" -l 30 --compress
╭──────────────────────────────────────────────────────────────────────────────╮
│ OPTIONS REFERENCE │
╰──────────────────────────────────────────────────────────────────────────────╯
PACKX OPTIONS
-s, --strings STRING Search string (use multiple times)
-S, --exclude-strings Exclude files containing these strings
-e, --extensions EXTS Include only these extensions (comma-separated)
-x, --exclude-extensions Exclude these patterns (matched from end)
-f, --file PATH Read configuration from file
-l, --lines NUMBER Context lines around matches (default: entire file)
-C, --case-sensitive Make search case-sensitive (default: case-insensitive)
--preview List matched files without bundling
-h, --help Show this help message
-v, --version Show version number
REPOMIX PASSTHROUGH OPTIONS
-o, --output PATH Output file path (default: repomix-output.xml)
--style FORMAT Output format: xml, markdown, plain
--compress Compress output for smaller size
-c, --copy Copy output to clipboard
--remove-comments Strip comments from code
--token-count-tree Show token count statistics
--instruction-file-path Custom instructions file
(All other Repomix flags are automatically passed through)
DEFAULT EXTENSIONS
When -e is not specified, packx searches ALL of these by default:
• Languages: js, jsx, ts, tsx, mjs, cjs, py, rb, go, java, cpp, c, h,
rs, swift, kt, scala, php
• Frameworks: vue, svelte, astro
• Styles: css, scss, less
• Config: json, yaml, yml, toml, xml
• Docs: md, mdx, txt
• Scripts: sh, bash, zsh, fish
• Data: sql, graphql, gql
╭──────────────────────────────────────────────────────────────────────────────╮
│ TIPS & TRICKS │
╰──────────────────────────────────────────────────────────────────────────────╯
\uD83D\uDCA1 PRO TIPS
1. Use --preview first to verify your search:
packx -s "password" --preview
# Check the file list, then run without --preview
2. Combine multiple patterns for OR logic:
packx -s "error" -s "exception" -s "fail" -s "crash"
# Finds files with ANY of these strings
3. Use config files for team sharing:
# Create standard searches for your team
packx init team-standards.txt
git add team-standards.txt
git commit -m "Add team search patterns"
4. Context lines for token optimization:
# Instead of sending entire files to AI:
packx -s "bug" -l 20 # Just 20 lines around bugs
packx -s "TODO" -l 5 # Minimal context for TODOs
5. Quick clipboard for AI chats:
# Search and instantly copy for ChatGPT/Claude
packx -s "function calculatePrice" -l 50 -c
# Now just paste into your AI chat!
⚠️ COMMON PITFALLS
• Don't use dots in extensions: use "ts" not ".ts"
• Search is case-insensitive by default (use -C for case-sensitive)
• Use quotes for special chars in shell: -s "foo()"
• Large repos: use -e to limit extensions: -e "ts,tsx"
• -x matches from END: "d.ts" matches "*.d.ts" files
\uD83D\uDCCA PERFORMANCE NOTES
• Packx uses ripgrep-like algorithms for speed
• .gitignore patterns are respected automatically
• Binary files are skipped automatically
• Files > 10MB are skipped for safety
• Use --preview to estimate before processing
╭──────────────────────────────────────────────────────────────────────────────╮
│ ABOUT PACKX │
╰──────────────────────────────────────────────────────────────────────────────╯
Version: v1.4.1
Author: John Lindquist
License: MIT
Repository: https://github.com/johnlindquist/pack
Packx is a smart wrapper around Repomix that filters files BEFORE bundling,
ensuring you only package what you need. Perfect for focused AI analysis,
code reviews, debugging sessions, and codebase exploration.
Report issues: https://github.com/johnlindquist/pack/issues
Star if useful: https://github.com/johnlindquist/pack ⭐
`;
process.stdout.write(txt);
}
function parseCSV(input) {
if (!input)
return [];
return input.split(",").map((s) => s.trim()).filter(Boolean);
}
function toExtSet(exts) {
const s = new Set;
for (const e of exts) {
const dot = e.startsWith(".") ? e.toLowerCase() : `.${e.toLowerCase()}`;
s.add(dot);
}
return s;
}
function escRegex(lit) {
return lit.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function findAllMatches(content, pattern) {
const lines = content.split(`
`);
const matches = [];
lines.forEach((line, lineIndex) => {
let match2;
const linePattern = new RegExp(pattern.source, pattern.flags.replace("g", "") + "g");
while ((match2 = linePattern.exec(line)) !== null) {
matches.push({
line: lineIndex + 1,
column: match2.index,
match: match2[0]
});
}
});
return matches;
}
function extractContextWindows(content, pattern, contextLines) {
const lines = content.split(`
`);
const matches = findAllMatches(content, pattern);
if (matches.length === 0)
return [];
const windows = [];
for (const match2 of matches) {
const startLine = Math.max(1, match2.line - contextLines);
const endLine = Math.min(lines.length, match2.line + contextLines);
windows.push({
startLine,
endLine,
lines: lines.slice(startLine - 1, endLine),
matches: [match2]
});
}
const merged = [];
let current = null;
for (const window of windows) {
if (!current) {
current = window;
} else if (window.startLine <= current.endLine + 1) {
current.endLine = Math.max(current.endLine, window.endLine);
current.lines = lines.slice(current.startLine - 1, current.endLine);
current.matches.push(...window.matches);
} else {
merged.push(current);
current = window;
}
}
if (current) {
merged.push(current);
}
return merged;
}
function formatContextWindows(windows, filePath) {
if (windows.length === 0)
return "";
let output = "";
for (const window of windows) {
if (output) {
output += `
...
`;
}
window.lines.forEach((line, index) => {
const lineNum = window.startLine + index;
output += `${String(lineNum).padStart(6, " ")}│ ${line}
`;
});
}
return output;
}
async function fileContainsAnyStrings(absPath, pattern, excludePattern) {
try {
const stat = await fs.stat(absPath);
if (stat.size > 10 * 1024 * 1024)
return false;
const buf = await fs.readFile(absPath, "utf8");
if (excludePattern && excludePattern.test(buf)) {
return false;
}
return pattern ? pattern.test(buf) : true;
} catch {
return false;
}
}
function normalizeStrings(value) {
if (!value)
return [];
if (Array.isArray(value))
return value;
return [value];
}
async function parseConfigFile(filePath) {
const config = {
search: [],
extensions: [],
exclude: []
};
try {
const content = await fs.readFile(filePath, "utf8");
const lines = content.split(`
`);
let currentSection = null;
for (const line of lines) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith("#"))
continue;
if (trimmed === "[search]" || trimmed === "[strings]") {
currentSection = "search";
continue;
}
if (trimmed === "[extensions]" || trimmed === "[include]") {
currentSection = "extensions";
continue;
}
if (trimmed === "[exclude]" || trimmed === "[exclude-extensions]" || trimmed === "[ignore]") {
currentSection = "exclude";
continue;
}
if (currentSection) {
config[currentSection].push(trimmed);
}
}
return config;
} catch (error) {
console.error(`Error reading config file: ${filePath}`);
if (error instanceof Error) {
console.error(error.message);
}
process.exit(1);
}
}
async function createConfigTemplate(filename = "pack-config.ini") {
const template = `# Pack configuration file
# Search for specific strings in your codebase
# Lines starting with # are comments
# Empty lines are ignored
[search]
# Add search strings here, one per line
# Examples:
# console.log
# TODO
# FIXME
[extensions]
# File extensions to include (without dots)
# Leave empty to search all common code files
# Examples:
# ts
# tsx
# js
# jsx
[exclude]
# Exclude patterns using gitignore syntax
# Examples:
# *.d.ts # All TypeScript declaration files
# *.test.ts # All test files
# *.spec.ts # All spec files
# *.min.js # All minified JS files
# docs/ # Docs directory
# site/ # Site directory
# **/test/** # Any test directories
# **/*.test.ts # Test files anywhere
# examples/** # Everything under examples
# !important.test.ts # Exception: include this test file
`;
try {
try {
await fs.access(filename);
console.error(`❌ File '${filename}' already exists. Use a different name or delete the existing file.`);
process.exit(1);
} catch {}
const dir = path2.dirname(filename);
if (dir && dir !== "." && dir !== "") {
try {
await fs.access(dir);
} catch {
console.log(`\uD83D\uDCC1 Directory '${dir}' does not exist.`);
const readline = await import("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const answer = await new Promise((resolve2) => {
rl.question("Would you like to create it? (y/n): ", resolve2);
});
rl.close();
if (answer.toLowerCase() === "y" || answer.toLowerCase() === "yes") {
await fs.mkdir(dir, { recursive: true });
console.log(`✅ Created directory: ${dir}`);
} else {
console.log("❌ Directory creation cancelled.");
process.exit(1);
}
}
}
await fs.writeFile(filename, template, "utf8");
console.log(`✅ Created config template: ${filename}`);
console.log(`
Edit the file and then run:`);
console.log(` packx -f ${filename}`);
} catch (error) {
console.error(`❌ Failed to create config file: ${error}`);
process.exit(1);
}
}
async function main() {
if (process.argv[2] === "init") {
let filename = process.argv[3] || "pack-config.ini";
if (filename && !path2.extname(filename)) {
filename = `${filename}.ini`;
}
await createConfigTemplate(filename);
process.exit(0);
}
const parsed = import_mri.default(process.argv.slice(2), {
alias: {
s: "strings",
S: "exclude-strings",
e: "extensions",
x: "exclude-extensions",
f: "file",
l: "lines",
C: "case-sensitive",
h: "help",
v: "version"
},
string: [
"strings",
"s",
"exclude-strings",
"S",
"extensions",
"e",
"exclude-extensions",
"x",
"file",
"f",
"include",
"ignore",
"i"
],
boolean: ["case-sensitive", "C", "preview", "help", "h", "version", "v", "stdout"]
});
if (parsed.help || parsed.h) {
printHelp();
process.exit(0);
}
if (parsed.version || parsed.v) {
console.log("packx v3.0.8");
process.exit(0);
}
let strings = [];
let excludeStrings = [];
let extensions;
let excludePatterns = [];
const caseSensitive = parsed["case-sensitive"] || parsed.C || false;
function toArray(val) {
if (!val)
return [];
return Array.isArray(val) ? val.map(String) : [String(val)];
}
const includeRaw = toArray(parsed.include);
const includeList = includeRaw.flatMap((v) => parseCSV(v));
const ignoreRaw = toArray(parsed.ignore || parsed.i);
const ignoreList = ignoreRaw.flatMap((v) => parseCSV(v));
function hasGlobChars(s) {
return /[\*\?\[\]\{\}!]/.test(s);
}
function expandPattern(p, forInclude = true) {
if (hasGlobChars(p))
return [p];
const norm = p.replace(/^[./]+/, "");
const patterns = [];
patterns.push(norm);
patterns.push(`**/${norm}`);
patterns.push(`${norm}/**`);
patterns.push(`**/${norm}/**`);
return Array.from(new Set(patterns));
}
const positionalArgs = (parsed._ || []).map(String);
const positionalRoots = [];
const positionalFileIncludes = [];
const positionalGlobIncludes = [];
for (const arg of positionalArgs) {
if (!arg)
continue;
if (hasGlobChars(arg)) {
positionalGlobIncludes.push(arg);
continue;
}
try {
const st = await fs.stat(arg);
if (st.isDirectory())
positionalRoots.push(arg);
else if (st.isFile())
positionalFileIncludes.push(path2.resolve(arg));
else
positionalGlobIncludes.push(arg);
} catch {
positionalGlobIncludes.push(arg);
}
}
const positionalFilePatterns = positionalFileIncludes.map((abs) => path2.relative(process.cwd(), abs).replace(/\\/g, "/"));
const combinedIncludeList = [
...includeList,
...positionalGlobIncludes,
...positionalFilePatterns
];
const includeExpanded = combinedIncludeList.flatMap((p) => expandPattern(p, true));
const ignoreExpanded = ignoreList.flatMap((p) => expandPattern(p, false));
const includeMatchers = includeExpanded.map((p) => new Minimatch(p, { dot: true, nocase: !caseSensitive, noglobstar: false }));
const ignoreMatchers = ignoreExpanded.map((p) => new Minimatch(p, { dot: true, nocase: !caseSensitive, noglobstar: false }));
const configFile = parsed.file || parsed.f;
if (configFile) {
const config = await parseConfigFile(configFile);
strings = config.search;
extensions = toExtSet(config.extensions);
excludePatterns = config.exclude;
strings.push(...normalizeStrings(parsed.strings));
strings.push(...normalizeStrings(parsed.s));
excludeStrings = [
...normalizeStrings(parsed["exclude-strings"]),
...normalizeStrings(parsed.S)
].filter(Boolean);
const cliExtensions = parsed.extensions || parsed.e;
const cliExtList = Array.isArray(cliExtensions) ? cliExtensions.flatMap((v) => parseCSV(String(v))) : parseCSV(cliExtensions);
for (const ext2 of toExtSet(cliExtList)) {
extensions.add(ext2);
}
const cliExclude = parsed["exclude-extensions"] || parsed.x;
const cliExcludeList = Array.isArray(cliExclude) ? cliExclude.flatMap((v) => parseCSV(String(v))) : parseCSV(cliExclude);
for (const excl of cliExcludeList) {
if (excl) {
if (!excl.includes("/") && !excl.includes("*")) {
excludePatterns.push(`**/*.${excl.replace(/^\./, "")}`);
} else {
excludePatterns.push(excl);
}
}
}
} else {
strings = [
...normalizeStrings(parsed.strings),
...normalizeStrings(parsed.s)
].filter(Boolean);
excludeStrings = [
...normalizeStrings(parsed["exclude-strings"]),
...normalizeStrings(parsed.S)
].filter(Boolean);
const extensionValues = parsed.extensions || parsed.e;
const extensionsList = Array.isArray(extensionValues) ? extensionValues.flatMap((v) => parseCSV(String(v))) : parseCSV(extensionValues);
extensions = toExtSet(extensionsList);
const excludeValues = parsed["exclude-extensions"] || parsed.x;
const excludeList = Array.isArray(excludeValues) ? excludeValues.flatMap((v) => parseCSV(String(v))) : parseCSV(excludeValues);
for (const excl of excludeList) {
if (excl) {
if (!excl.includes("/") && !excl.includes("*")) {
excludePatterns.push(`**/*.${excl.replace(/^\./, "")}`);
} else {
excludePatterns.push(excl);
}
}
}
}
strings = strings.filter(Boolean);
if (!extensions.size) {
extensions = toExtSet([
"js",
"jsx",
"ts",
"tsx",
"mjs",
"cjs",
"py",
"rb",
"go",
"java",
"cpp",
"c",
"h",
"rs",
"swift",
"kt",
"scala",
"php",
"vue",
"svelte",
"astro",
"css",
"scss",
"less",
"json",
"yaml",
"yml",
"toml",
"xml",
"md",
"mdx",
"txt",
"sh",
"bash",
"zsh",
"fish",
"sql",
"graphql",
"gql"
]);
}
const roots = positionalRoots.length ? positionalRoots : ["."];
const regexFlags = caseSensitive ? "" : "i";
const pattern = strings.length > 0 ? new RegExp(strings.map(escRegex).join("|"), regexFlags) : null;
const excludePattern = excludeStrings.length > 0 ? new RegExp(excludeStrings.map(escRegex).join("|"), regexFlags) : null;
const candidates = new Set;
for (const root of roots) {
const absRoot = path2.resolve(root);
const patterns = [];
for (const ext2 of extensions) {
const cleanExt = ext2.startsWith(".") ? ext2.slice(1) : ext2;
patterns.push(`**/*.${cleanExt}`);
}
for (const pattern2 of patterns) {
const files = await glob(pattern2, {
cwd: absRoot,
ignore: [
"**/node_modules/**",
"**/.git/**",
"**/dist/**",
"**/build/**",
"**/.next/**",
"**/coverage/**",
"**/.cache/**",
"**/tmp/**",
"**/temp/**",
"**/*.log",
"**/.DS_Store",
"**/Thumbs.db",
...excludePatterns
],
absolute: true,
dot: false,
nodir: true
});
for (const file of files) {
candidates.add(file);
}
}
if (includeExpanded.length > 0) {
for (const inc of includeExpanded) {
try {
const isAbs = path2.isAbsolute(inc);
const files = await glob(inc, {
cwd: isAbs ? undefined : absRoot,
ignore: [
"**/node_modules/**",
"**/.git/**",
"**/dist/**",
"**/build/**",
"**/.next/**",
"**/coverage/**",
"**/.cache/**",
"**/tmp/**",
"**/temp/**",
"**/*.log",
"**/.DS_Store",
"**/Thumbs.db"
],
absolute: true,
dot: false,
nodir: true
});
for (const f of files)
candidates.add(f);
} catch {}
}
}
}
for (const f of positionalFileIncludes)
candidates.add(f);
if (!candidates.size) {
console.warn("⚠️ No files found with the specified extensions in the given roots.");
process.exit(2);
}
const filteredCandidates = [];
for (const p of candidates) {
const rel = path2.relative(process.cwd(), p).replace(/\\/g, "/");
if (includeMatchers.length && !includeMatchers.some((mm) => mm.match(rel)))
continue;
if (ignoreMatchers.length && ignoreMatchers.some((mm) => mm.match(rel)))
continue;
filteredCandidates.push(p);
}
const matched = [];
const foundExtensions = new Set;
if (!pattern) {
for (const p of filteredCandidates) {
if (excludePattern) {
try {
const stat = await fs.stat(p);
if (stat.size > 10485760)
continue;
const buf = await fs.readFile(p, "utf8");
if (excludePattern.test(buf))
continue;
} catch {
continue;
}
}
const resolvedPath = path2.resolve(p);
matched.push(resolvedPath);
const ext2 = path2.extname(resolvedPath).toLowerCase();
if (ext2)
foundExtensions.add(ext2);
}
} else {
for (const p of filteredCandidates) {
if (await fileContainsAnyStrings(p, pattern, excludePattern)) {
const resolvedPath = path2.resolve(p);
matched.push(resolvedPath);
const ext2 = path2.extname(resolvedPath).toLowerCase();
if (ext2) {
foundExtensions.add(ext2);
}
}
}
}
if (!matched.length) {
console.warn("⚠️ No files matched the given strings.");
process.exit(3);
}
if (parsed.preview) {
console.log("Matched files:");
for (const m of matched)
console.log(m);
console.log(`
Total: ${matched.length} file(s).`);
process.exit(0);
}
const cwd = process.cwd();
const relativePaths = matched.map((p) => path2.relative(cwd, p));
const rawOutputArg = parsed.output ?? parsed.o;
let toStdout = Boolean(parsed.stdout);
if (rawOutputArg === "-" || parsed.o === true && (parsed._ || []).includes("-")) {
toStdout = true;
}
const outputFile = typeof rawOutputArg === "string" ? rawOutputArg : undefined;
const summaryOnly = !toStdout && !outputFile;
const outputStyle = parsed.style || "xml";
const log = (msg) => toStdout ? console.error(msg) : console.log(msg);
log(`\uD83E\uDDE9 Packing ${matched.length} file(s)...`);
const hasSearchStrings = strings.length > 0;
const contextLines = hasSearchStrings ? parsed.lines || parsed.l : undefined;
if (contextLines) {
log(`\uD83D\uDCDD Extracting ${contextLines} lines of context around matches...`);
} else {
log(`\uD83D\uDCDD Files selected:`);
relativePaths.forEach((p) => log(` • ${p}`));
if (!toStdout && !outputFile) {
log(`(Summary only. Use -o <file> or --stdout to write content)`);
}
}
let output = "";
let totalMatchCount = 0;
let totalWindowCount = 0;
const fileSizes = [];
if (outputStyle === "xml") {
if (!summaryOnly) {
output = `This file is a merged representation of the filtered codebase, combined into a single document by packx.
<file_summary>
This section contains a summary of this file.
<purpose>
This file contains a packed representation of filtered repository contents.
It is designed to be easily consumable by AI systems for analysis, code review,
or other automated processes.
</purpose>
<usage_guidelines>
- Treat this file as a snapshot of the repository's state
- Be aware that this file may contain sensitive information
</usage_guidelines>
<notes>
- Files were filtered by packx based on content and extension matching
- Total files included: ${matched.length}${contextLines ? `
- Context lines: ${contextLines} lines around each match` : ""}
</notes>
</file_summary>
<directory_structure>
${relativePaths.join(`
`)}
</directory_structure>
<files>
This section contains the contents of the repository's files.
`;
}
for (const [index, filePath] of matched.entries()) {
const relPath = relativePaths[index];
try {
const content = await fs.readFile(filePath, "utf8");
let fileOutput = "";
if (contextLines) {
const windows = extractContextWindows(content, pattern, contextLines);
if (windows.length > 0) {
totalWindowCount += windows.length;
totalMatchCount += windows.reduce((sum, w) => sum + w.matches.length, 0);
const formatted = formatContextWindows(windows, relPath);
if (formatted) {
fileOutput = `<file path="${relPath}" matches="${windows.reduce((sum, w) => sum + w.matches.length, 0)}" windows="${windows.length}">
${formatted}</file>
`;
}
}
} else {
fileOutput = `<file path="${relPath}">
${content}
</file>
`;
}
if (fileOutput) {
if (!summaryOnly)
output += fileOutput;
const fileSize = fileOutput.length;
const fileTokens = Math.round(fileSize / 4);
fileSizes.push({ path: relPath, size: fileSize, tokens: fileTokens });
}
} catch (err) {
console.error(`Warning: Could not read file ${relPath}: ${err}`);
}
}
if (!summaryOnly) {
output += `</files>`;
}
} else {
if (!summaryOnly) {
output = `# Packx Output
This file contains ${matched.length} filtered files from the repository.${contextLines ? `
**Context:** ${contextLines} lines around each match` : ""}
## Files
`;
}
for (const [index, filePath] of matched.entries()) {
const relPath = relativePaths[index];
try {
const content = await fs.readFile(filePath, "utf8");
const ext2 = path2.extname(relPath).slice(1) || "txt";
let fileOutput = "";
if (contextLines) {
const windows = extractContextWindows(content, pattern, contextLines);
if (windows.length > 0) {
totalWindowCount += windows.length;
totalMatchCount += windows.reduce((sum, w) => sum + w.matches.length, 0);
fileOutput = `### ${relPath}
**Matches:** ${windows.reduce((sum, w) => sum + w.matches.length, 0)} | **Context windows:** ${windows.length}
\`\`\`${ext2}
${formatContextWindows(windows, relPath)}\`\`\`
`;
}
} else {
fileOutput = `### ${relPath}
\`\`\`${ext2}
${content}
\`\`\`
`;
}
if (fileOutput) {
if (!summaryOnly)
output += fileOutput;
const fileSize = fileOutput.length;
const fileTokens = Math.round(fileSize / 4);
fileSizes.push({ path: relPath, size: fileSize, tokens: fileTokens });
}
} catch (err) {
console.error(`Warning: Could not read file ${relPath}: ${err}`);
}
}
}
if (toStdout) {
process.stdout.write(output);
} else if (outputFile) {
await fs.writeFile(outputFile, output, "utf8");
console.log(`
✅ Successfully packed ${matched.length} file(s) to ${outputFile}`);
}
if (!toStdout && (parsed.copy || parsed.c)) {
try {
const { spawn } = await import("child_process");
const platform = process.platform;
let copyProc;
if (platform === "darwin") {
copyProc = spawn("pbcopy");
} else if (platform === "win32") {
copyProc = spawn("clip");
} else {
copyProc = spawn("xclip", ["-selection", "clipboard"]);
}
copyProc.stdin.write(output);
copyProc.stdin.end();
await new Promise((resolve2, reject) => {
copyProc.on("exit", (code) => {
if (code === 0) {
console.log("\uD83D\uDCCB Copied to clipboard!");
resolve2(code);
} else {
console.log("⚠️ Could not copy to clipboard");
reject(new Error(`Copy process exited with code ${code}`));
}
});
copyProc.on("error", (err) => {
console.log("⚠️ Could not copy to clipboard (clipboard tool not found)");
reject(err);
});
});
} catch (err) {}
}
const totalChars = !toStdout && !outputFile && fileSizes.length ? fileSizes.reduce((sum, f) => sum + f.size, 0) : output.length;
const totalTokens = Math.round(totalChars / 4);
log(`
\uD83D\uDCCA Pack Summary:`);
log(`────────────────`);
log(` Total Files: ${matched.length} files`);
if (contextLines) {
log(` Context Lines: ${contextLines} around each match`);
log(` Total Matches: ${totalMatchCount} matches`);
log(` Context Windows: ${totalWindowCount} windows`);
}
log(` Total Tokens: ~${totalTokens.toLocaleString()} tokens`);
log(` Total Chars: ${totalChars.toLocaleString()} chars`);
log(` Output: ${toStdout ? "-" : outputFile ?? "none"}`);
if (foundExtensions.size > 0) {
const sortedExtensions = Array.from(foundExtensions).sort();
log(`
\uD83D\uDCC1 Extensions Found:`);
log(`────────────────────`);
log(` ${sortedExtensions.join(", ")}`);
}
if (fileSizes.length > 0) {
const topFiles = fileSizes.sort((a, b) => b.tokens - a.tokens).slice(0, 10);
log(`
\uD83D\uDCC2 Top 10 Files (by tokens):`);
log(`──────────────────────────`);
for (const file of topFiles) {
const fileName = path2.basename(file.path);
const dirName = path2.dirname(file.path);
const shortPath = dirName === "." ? fileName : `${dirName}/${fileName}`;
log(` ${file.tokens.toLocaleString().padStart(8)} tokens - ${shortPath}`);
}
}
}
main().catch((err) => {
console.error("Unexpected error:", err);
process.exit(99);
});