UNPKG

opfs-worker

Version:

A robust TypeScript library for working with Origin Private File System (OPFS) through Web Workers

1,290 lines (1,289 loc) 43.9 kB
class x extends Error { constructor(t, e, n, i) { super(t, { cause: i }), this.code = e, this.path = n, this.name = "OPFSError"; } } class rt extends x { constructor(t) { super("OPFS is not supported in this browser", "OPFS_NOT_SUPPORTED", void 0, t); } } class me extends x { constructor(t) { super("OPFS is not mounted", "OPFS_NOT_MOUNTED", void 0, t); } } class we extends x { constructor(t, e, n) { super(t, "INVALID_PATH", e, n); } } class ye extends x { constructor(t, e) { super(`File not found: ${t}`, "FILE_NOT_FOUND", t, e); } } class Ee extends x { constructor(t, e) { super(`Directory not found: ${t}`, "DIRECTORY_NOT_FOUND", t, e); } } class xe extends x { constructor(t, e, n) { super(`Permission denied for ${e} on: ${t}`, "PERMISSION_DENIED", t, n); } } class Se extends x { constructor(t, e, n) { super(t, "STORAGE_ERROR", e, n); } } class be extends x { constructor(t, e, n) { super(`Operation timed out: ${t}`, "TIMEOUT_ERROR", e, n); } } const H = (s, t, e) => { const n = s instanceof RegExp ? W(s, e) : s, i = t instanceof RegExp ? W(t, e) : t, r = n !== null && i != null && ot(n, i, e); return r && { start: r[0], end: r[1], pre: e.slice(0, r[0]), body: e.slice(r[0] + n.length, r[1]), post: e.slice(r[1] + i.length) }; }, W = (s, t) => { const e = t.match(s); return e ? e[0] : null; }, ot = (s, t, e) => { let n, i, r, o, a, h = e.indexOf(s), l = e.indexOf(t, h + 1), c = h; if (h >= 0 && l > 0) { if (s === t) return [h, l]; for (n = [], r = e.length; c >= 0 && !a; ) { if (c === h) n.push(c), h = e.indexOf(s, c + 1); else if (n.length === 1) { const p = n.pop(); p !== void 0 && (a = [p, l]); } else i = n.pop(), i !== void 0 && i < r && (r = i, o = l), l = e.indexOf(t, c + 1); c = h < l && h >= 0 ? h : l; } n.length && o !== void 0 && (a = [r, o]); } return a; }, Z = "\0SLASH" + Math.random() + "\0", J = "\0OPEN" + Math.random() + "\0", F = "\0CLOSE" + Math.random() + "\0", V = "\0COMMA" + Math.random() + "\0", X = "\0PERIOD" + Math.random() + "\0", ct = new RegExp(Z, "g"), at = new RegExp(J, "g"), ht = new RegExp(F, "g"), lt = new RegExp(V, "g"), ut = new RegExp(X, "g"), ft = /\\\\/g, pt = /\\{/g, dt = /\\}/g, gt = /\\,/g, mt = /\\./g; function L(s) { return isNaN(s) ? s.charCodeAt(0) : parseInt(s, 10); } function wt(s) { return s.replace(ft, Z).replace(pt, J).replace(dt, F).replace(gt, V).replace(mt, X); } function yt(s) { return s.replace(ct, "\\").replace(at, "{").replace(ht, "}").replace(lt, ",").replace(ut, "."); } function Y(s) { if (!s) return [""]; const t = [], e = H("{", "}", s); if (!e) return s.split(","); const { pre: n, body: i, post: r } = e, o = n.split(","); o[o.length - 1] += "{" + i + "}"; const a = Y(r); return r.length && (o[o.length - 1] += a.shift(), o.push.apply(o, a)), t.push.apply(t, o), t; } function Et(s) { return s ? (s.slice(0, 2) === "{}" && (s = "\\{\\}" + s.slice(2)), T(wt(s), !0).map(yt)) : []; } function xt(s) { return "{" + s + "}"; } function St(s) { return /^-?0\d/.test(s); } function bt(s, t) { return s <= t; } function Ot(s, t) { return s >= t; } function T(s, t) { const e = [], n = H("{", "}", s); if (!n) return [s]; const i = n.pre, r = n.post.length ? T(n.post, !1) : [""]; if (/\$$/.test(n.pre)) for (let o = 0; o < r.length; o++) { const a = i + "{" + n.body + "}" + r[o]; e.push(a); } else { const o = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(n.body), a = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(n.body), h = o || a, l = n.body.indexOf(",") >= 0; if (!h && !l) return n.post.match(/,(?!,).*\}/) ? (s = n.pre + "{" + n.body + F + n.post, T(s)) : [s]; let c; if (h) c = n.body.split(/\.\./); else if (c = Y(n.body), c.length === 1 && c[0] !== void 0 && (c = T(c[0], !1).map(xt), c.length === 1)) return r.map((f) => n.pre + c[0] + f); let p; if (h && c[0] !== void 0 && c[1] !== void 0) { const f = L(c[0]), u = L(c[1]), g = Math.max(c[0].length, c[1].length); let d = c.length === 3 && c[2] !== void 0 ? Math.abs(L(c[2])) : 1, E = bt; u < f && (d *= -1, E = Ot); const A = c.some(St); p = []; for (let S = f; E(S, u); S += d) { let m; if (a) m = String.fromCharCode(S), m === "\\" && (m = ""); else if (m = String(S), A) { const N = g - m.length; if (N > 0) { const P = new Array(N + 1).join("0"); S < 0 ? m = "-" + P + m.slice(1) : m = P + m; } } p.push(m); } } else { p = []; for (let f = 0; f < c.length; f++) p.push.apply(p, T(c[f], !1)); } for (let f = 0; f < p.length; f++) for (let u = 0; u < r.length; u++) { const g = i + p[f] + r[u]; (!t || h || g) && e.push(g); } } return e; } const vt = 1024 * 64, C = (s) => { if (typeof s != "string") throw new TypeError("invalid pattern"); if (s.length > vt) throw new TypeError("pattern is too long"); }, At = { "[:alnum:]": ["\\p{L}\\p{Nl}\\p{Nd}", !0], "[:alpha:]": ["\\p{L}\\p{Nl}", !0], "[:ascii:]": ["\\x00-\\x7f", !1], "[:blank:]": ["\\p{Zs}\\t", !0], "[:cntrl:]": ["\\p{Cc}", !0], "[:digit:]": ["\\p{Nd}", !0], "[:graph:]": ["\\p{Z}\\p{C}", !0, !0], "[:lower:]": ["\\p{Ll}", !0], "[:print:]": ["\\p{C}", !0], "[:punct:]": ["\\p{P}", !0], "[:space:]": ["\\p{Z}\\t\\r\\n\\v\\f", !0], "[:upper:]": ["\\p{Lu}", !0], "[:word:]": ["\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}", !0], "[:xdigit:]": ["A-Fa-f0-9", !1] }, $ = (s) => s.replace(/[[\]\\-]/g, "\\$&"), Nt = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), k = (s) => s.join(""), $t = (s, t) => { const e = t; if (s.charAt(e) !== "[") throw new Error("not in a brace expression"); const n = [], i = []; let r = e + 1, o = !1, a = !1, h = !1, l = !1, c = e, p = ""; t: for (; r < s.length; ) { const d = s.charAt(r); if ((d === "!" || d === "^") && r === e + 1) { l = !0, r++; continue; } if (d === "]" && o && !h) { c = r + 1; break; } if (o = !0, d === "\\" && !h) { h = !0, r++; continue; } if (d === "[" && !h) { for (const [E, [v, A, S]] of Object.entries(At)) if (s.startsWith(E, r)) { if (p) return ["$.", !1, s.length - e, !0]; r += E.length, S ? i.push(v) : n.push(v), a = a || A; continue t; } } if (h = !1, p) { d > p ? n.push($(p) + "-" + $(d)) : d === p && n.push($(d)), p = "", r++; continue; } if (s.startsWith("-]", r + 1)) { n.push($(d + "-")), r += 2; continue; } if (s.startsWith("-", r + 1)) { p = d, r += 2; continue; } n.push($(d)), r++; } if (c < r) return ["", !1, 0, !1]; if (!n.length && !i.length) return ["$.", !1, s.length - e, !0]; if (i.length === 0 && n.length === 1 && /^\\?.$/.test(n[0]) && !l) { const d = n[0].length === 2 ? n[0].slice(-1) : n[0]; return [Nt(d), !1, c - e, !1]; } const f = "[" + (l ? "^" : "") + k(n) + "]", u = "[" + (l ? "" : "^") + k(i) + "]"; return [n.length && i.length ? "(" + f + "|" + u + ")" : n.length ? f : u, a, c - e, !0]; }, M = (s, { windowsPathsNoEscape: t = !1 } = {}) => t ? s.replace(/\[([^\/\\])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, "$1$2").replace(/\\([^\/])/g, "$1"), Tt = /* @__PURE__ */ new Set(["!", "?", "+", "*", "@"]), z = (s) => Tt.has(s), Mt = "(?!(?:^|/)\\.\\.?(?:$|/))", R = "(?!\\.)", Pt = /* @__PURE__ */ new Set(["[", "."]), Rt = /* @__PURE__ */ new Set(["..", "."]), Ct = new Set("().*{}+?[]^$\\!"), Dt = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), j = "[^/]", _ = j + "*?", B = j + "+?"; class y { type; #s; #n; #r = !1; #t = []; #e; #o; #a; #c = !1; #i; #h; // set to true if it's an extglob with no children // (which really means one child of '') #u = !1; constructor(t, e, n = {}) { this.type = t, t && (this.#n = !0), this.#e = e, this.#s = this.#e ? this.#e.#s : this, this.#i = this.#s === this ? n : this.#s.#i, this.#a = this.#s === this ? [] : this.#s.#a, t === "!" && !this.#s.#c && this.#a.push(this), this.#o = this.#e ? this.#e.#t.length : 0; } get hasMagic() { if (this.#n !== void 0) return this.#n; for (const t of this.#t) if (typeof t != "string" && (t.type || t.hasMagic)) return this.#n = !0; return this.#n; } // reconstructs the pattern toString() { return this.#h !== void 0 ? this.#h : this.type ? this.#h = this.type + "(" + this.#t.map((t) => String(t)).join("|") + ")" : this.#h = this.#t.map((t) => String(t)).join(""); } #p() { if (this !== this.#s) throw new Error("should only call on root"); if (this.#c) return this; this.toString(), this.#c = !0; let t; for (; t = this.#a.pop(); ) { if (t.type !== "!") continue; let e = t, n = e.#e; for (; n; ) { for (let i = e.#o + 1; !n.type && i < n.#t.length; i++) for (const r of t.#t) { if (typeof r == "string") throw new Error("string part in extglob AST??"); r.copyIn(n.#t[i]); } e = n, n = e.#e; } } return this; } push(...t) { for (const e of t) if (e !== "") { if (typeof e != "string" && !(e instanceof y && e.#e === this)) throw new Error("invalid part: " + e); this.#t.push(e); } } toJSON() { const t = this.type === null ? this.#t.slice().map((e) => typeof e == "string" ? e : e.toJSON()) : [this.type, ...this.#t.map((e) => e.toJSON())]; return this.isStart() && !this.type && t.unshift([]), this.isEnd() && (this === this.#s || this.#s.#c && this.#e?.type === "!") && t.push({}), t; } isStart() { if (this.#s === this) return !0; if (!this.#e?.isStart()) return !1; if (this.#o === 0) return !0; const t = this.#e; for (let e = 0; e < this.#o; e++) { const n = t.#t[e]; if (!(n instanceof y && n.type === "!")) return !1; } return !0; } isEnd() { if (this.#s === this || this.#e?.type === "!") return !0; if (!this.#e?.isEnd()) return !1; if (!this.type) return this.#e?.isEnd(); const t = this.#e ? this.#e.#t.length : 0; return this.#o === t - 1; } copyIn(t) { typeof t == "string" ? this.push(t) : this.push(t.clone(this)); } clone(t) { const e = new y(this.type, t); for (const n of this.#t) e.copyIn(n); return e; } static #l(t, e, n, i) { let r = !1, o = !1, a = -1, h = !1; if (e.type === null) { let u = n, g = ""; for (; u < t.length; ) { const d = t.charAt(u++); if (r || d === "\\") { r = !r, g += d; continue; } if (o) { u === a + 1 ? (d === "^" || d === "!") && (h = !0) : d === "]" && !(u === a + 2 && h) && (o = !1), g += d; continue; } else if (d === "[") { o = !0, a = u, h = !1, g += d; continue; } if (!i.noext && z(d) && t.charAt(u) === "(") { e.push(g), g = ""; const E = new y(d, e); u = y.#l(t, E, u, i), e.push(E); continue; } g += d; } return e.push(g), u; } let l = n + 1, c = new y(null, e); const p = []; let f = ""; for (; l < t.length; ) { const u = t.charAt(l++); if (r || u === "\\") { r = !r, f += u; continue; } if (o) { l === a + 1 ? (u === "^" || u === "!") && (h = !0) : u === "]" && !(l === a + 2 && h) && (o = !1), f += u; continue; } else if (u === "[") { o = !0, a = l, h = !1, f += u; continue; } if (z(u) && t.charAt(l) === "(") { c.push(f), f = ""; const g = new y(u, c); c.push(g), l = y.#l(t, g, l, i); continue; } if (u === "|") { c.push(f), f = "", p.push(c), c = new y(null, e); continue; } if (u === ")") return f === "" && e.#t.length === 0 && (e.#u = !0), c.push(f), f = "", e.push(...p, c), l; f += u; } return e.type = null, e.#n = void 0, e.#t = [t.substring(n - 1)], l; } static fromGlob(t, e = {}) { const n = new y(null, void 0, e); return y.#l(t, n, 0, e), n; } // returns the regular expression if there's magic, or the unescaped // string if not. toMMPattern() { if (this !== this.#s) return this.#s.toMMPattern(); const t = this.toString(), [e, n, i, r] = this.toRegExpSource(); if (!(i || this.#n || this.#i.nocase && !this.#i.nocaseMagicOnly && t.toUpperCase() !== t.toLowerCase())) return n; const a = (this.#i.nocase ? "i" : "") + (r ? "u" : ""); return Object.assign(new RegExp(`^${e}$`, a), { _src: e, _glob: t }); } get options() { return this.#i; } // returns the string match, the regexp source, whether there's magic // in the regexp (so a regular expression is required) and whether or // not the uflag is needed for the regular expression (for posix classes) // TODO: instead of injecting the start/end at this point, just return // the BODY of the regexp, along with the start/end portions suitable // for binding the start/end in either a joined full-path makeRe context // (where we bind to (^|/), or a standalone matchPart context (where // we bind to ^, and not /). Otherwise slashes get duped! // // In part-matching mode, the start is: // - if not isStart: nothing // - if traversal possible, but not allowed: ^(?!\.\.?$) // - if dots allowed or not possible: ^ // - if dots possible and not allowed: ^(?!\.) // end is: // - if not isEnd(): nothing // - else: $ // // In full-path matching mode, we put the slash at the START of the // pattern, so start is: // - if first pattern: same as part-matching mode // - if not isStart(): nothing // - if traversal possible, but not allowed: /(?!\.\.?(?:$|/)) // - if dots allowed or not possible: / // - if dots possible and not allowed: /(?!\.) // end is: // - if last pattern, same as part-matching mode // - else nothing // // Always put the (?:$|/) on negated tails, though, because that has to be // there to bind the end of the negated pattern portion, and it's easier to // just stick it in now rather than try to inject it later in the middle of // the pattern. // // We can just always return the same end, and leave it up to the caller // to know whether it's going to be used joined or in parts. // And, if the start is adjusted slightly, can do the same there: // - if not isStart: nothing // - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$) // - if dots allowed or not possible: (?:/|^) // - if dots possible and not allowed: (?:/|^)(?!\.) // // But it's better to have a simpler binding without a conditional, for // performance, so probably better to return both start options. // // Then the caller just ignores the end if it's not the first pattern, // and the start always gets applied. // // But that's always going to be $ if it's the ending pattern, or nothing, // so the caller can just attach $ at the end of the pattern when building. // // So the todo is: // - better detect what kind of start is needed // - return both flavors of starting pattern // - attach $ at the end of the pattern when creating the actual RegExp // // Ah, but wait, no, that all only applies to the root when the first pattern // is not an extglob. If the first pattern IS an extglob, then we need all // that dot prevention biz to live in the extglob portions, because eg // +(*|.x*) can match .xy but not .yx. // // So, return the two flavors if it's #root and the first child is not an // AST, otherwise leave it to the child AST to handle it, and there, // use the (?:^|/) style of start binding. // // Even simplified further: // - Since the start for a join is eg /(?!\.) and the start for a part // is ^(?!\.), we can just prepend (?!\.) to the pattern (either root // or start or whatever) and prepend ^ or / at the Regexp construction. toRegExpSource(t) { const e = t ?? !!this.#i.dot; if (this.#s === this && this.#p(), !this.type) { const h = this.isStart() && this.isEnd(), l = this.#t.map((u) => { const [g, d, E, v] = typeof u == "string" ? y.#d(u, this.#n, h) : u.toRegExpSource(t); return this.#n = this.#n || E, this.#r = this.#r || v, g; }).join(""); let c = ""; if (this.isStart() && typeof this.#t[0] == "string" && !(this.#t.length === 1 && Rt.has(this.#t[0]))) { const g = Pt, d = ( // dots are allowed, and the pattern starts with [ or . e && g.has(l.charAt(0)) || // the pattern starts with \., and then [ or . l.startsWith("\\.") && g.has(l.charAt(2)) || // the pattern starts with \.\., and then [ or . l.startsWith("\\.\\.") && g.has(l.charAt(4)) ), E = !e && !t && g.has(l.charAt(0)); c = d ? Mt : E ? R : ""; } let p = ""; return this.isEnd() && this.#s.#c && this.#e?.type === "!" && (p = "(?:$|\\/)"), [ c + l + p, M(l), this.#n = !!this.#n, this.#r ]; } const n = this.type === "*" || this.type === "+", i = this.type === "!" ? "(?:(?!(?:" : "(?:"; let r = this.#f(e); if (this.isStart() && this.isEnd() && !r && this.type !== "!") { const h = this.toString(); return this.#t = [h], this.type = null, this.#n = void 0, [h, M(this.toString()), !1, !1]; } let o = !n || t || e || !R ? "" : this.#f(!0); o === r && (o = ""), o && (r = `(?:${r})(?:${o})*?`); let a = ""; if (this.type === "!" && this.#u) a = (this.isStart() && !e ? R : "") + B; else { const h = this.type === "!" ? ( // !() must match something,but !(x) can match '' "))" + (this.isStart() && !e && !t ? R : "") + _ + ")" ) : this.type === "@" ? ")" : this.type === "?" ? ")?" : this.type === "+" && o ? ")" : this.type === "*" && o ? ")?" : `)${this.type}`; a = i + r + h; } return [ a, M(r), this.#n = !!this.#n, this.#r ]; } #f(t) { return this.#t.map((e) => { if (typeof e == "string") throw new Error("string type in extglob ast??"); const [n, i, r, o] = e.toRegExpSource(t); return this.#r = this.#r || o, n; }).filter((e) => !(this.isStart() && this.isEnd()) || !!e).join("|"); } static #d(t, e, n = !1) { let i = !1, r = "", o = !1; for (let a = 0; a < t.length; a++) { const h = t.charAt(a); if (i) { i = !1, r += (Ct.has(h) ? "\\" : "") + h; continue; } if (h === "\\") { a === t.length - 1 ? r += "\\\\" : i = !0; continue; } if (h === "[") { const [l, c, p, f] = $t(t, a); if (p) { r += l, o = o || c, a += p - 1, e = e || f; continue; } } if (h === "*") { n && t === "*" ? r += B : r += _, e = !0; continue; } if (h === "?") { r += j, e = !0; continue; } r += Dt(h); } return [r, M(t), !!e, o]; } } const Lt = (s, { windowsPathsNoEscape: t = !1 } = {}) => t ? s.replace(/[?*()[\]]/g, "[$&]") : s.replace(/[?*()[\]\\]/g, "\\$&"), w = (s, t, e = {}) => (C(t), !e.nocomment && t.charAt(0) === "#" ? !1 : new D(t, e).match(s)), Ft = /^\*+([^+@!?\*\[\(]*)$/, jt = (s) => (t) => !t.startsWith(".") && t.endsWith(s), It = (s) => (t) => t.endsWith(s), Ut = (s) => (s = s.toLowerCase(), (t) => !t.startsWith(".") && t.toLowerCase().endsWith(s)), Wt = (s) => (s = s.toLowerCase(), (t) => t.toLowerCase().endsWith(s)), kt = /^\*+\.\*+$/, zt = (s) => !s.startsWith(".") && s.includes("."), _t = (s) => s !== "." && s !== ".." && s.includes("."), Bt = /^\.\*+$/, qt = (s) => s !== "." && s !== ".." && s.startsWith("."), Gt = /^\*+$/, Ht = (s) => s.length !== 0 && !s.startsWith("."), Zt = (s) => s.length !== 0 && s !== "." && s !== "..", Jt = /^\?+([^+@!?\*\[\(]*)?$/, Vt = ([s, t = ""]) => { const e = K([s]); return t ? (t = t.toLowerCase(), (n) => e(n) && n.toLowerCase().endsWith(t)) : e; }, Xt = ([s, t = ""]) => { const e = Q([s]); return t ? (t = t.toLowerCase(), (n) => e(n) && n.toLowerCase().endsWith(t)) : e; }, Yt = ([s, t = ""]) => { const e = Q([s]); return t ? (n) => e(n) && n.endsWith(t) : e; }, Kt = ([s, t = ""]) => { const e = K([s]); return t ? (n) => e(n) && n.endsWith(t) : e; }, K = ([s]) => { const t = s.length; return (e) => e.length === t && !e.startsWith("."); }, Q = ([s]) => { const t = s.length; return (e) => e.length === t && e !== "." && e !== ".."; }, tt = typeof process == "object" && process ? typeof process.env == "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix", q = { win32: { sep: "\\" }, posix: { sep: "/" } }, Qt = tt === "win32" ? q.win32.sep : q.posix.sep; w.sep = Qt; const O = Symbol("globstar **"); w.GLOBSTAR = O; const te = "[^/]", ee = te + "*?", se = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?", ne = "(?:(?!(?:\\/|^)\\.).)*?", ie = (s, t = {}) => (e) => w(e, s, t); w.filter = ie; const b = (s, t = {}) => Object.assign({}, s, t), re = (s) => { if (!s || typeof s != "object" || !Object.keys(s).length) return w; const t = w; return Object.assign((n, i, r = {}) => t(n, i, b(s, r)), { Minimatch: class extends t.Minimatch { constructor(i, r = {}) { super(i, b(s, r)); } static defaults(i) { return t.defaults(b(s, i)).Minimatch; } }, AST: class extends t.AST { /* c8 ignore start */ constructor(i, r, o = {}) { super(i, r, b(s, o)); } /* c8 ignore stop */ static fromGlob(i, r = {}) { return t.AST.fromGlob(i, b(s, r)); } }, unescape: (n, i = {}) => t.unescape(n, b(s, i)), escape: (n, i = {}) => t.escape(n, b(s, i)), filter: (n, i = {}) => t.filter(n, b(s, i)), defaults: (n) => t.defaults(b(s, n)), makeRe: (n, i = {}) => t.makeRe(n, b(s, i)), braceExpand: (n, i = {}) => t.braceExpand(n, b(s, i)), match: (n, i, r = {}) => t.match(n, i, b(s, r)), sep: t.sep, GLOBSTAR: O }); }; w.defaults = re; const et = (s, t = {}) => (C(s), t.nobrace || !/\{(?:(?!\{).)*\}/.test(s) ? [s] : Et(s)); w.braceExpand = et; const oe = (s, t = {}) => new D(s, t).makeRe(); w.makeRe = oe; const ce = (s, t, e = {}) => { const n = new D(t, e); return s = s.filter((i) => n.match(i)), n.options.nonull && !s.length && s.push(t), s; }; w.match = ce; const G = /[?*]|[+@!]\(.*?\)|\[|\]/, ae = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); class D { options; set; pattern; windowsPathsNoEscape; nonegate; negate; comment; empty; preserveMultipleSlashes; partial; globSet; globParts; nocase; isWindows; platform; windowsNoMagicRoot; regexp; constructor(t, e = {}) { C(t), e = e || {}, this.options = e, this.pattern = t, this.platform = e.platform || tt, this.isWindows = this.platform === "win32", this.windowsPathsNoEscape = !!e.windowsPathsNoEscape || e.allowWindowsEscape === !1, this.windowsPathsNoEscape && (this.pattern = this.pattern.replace(/\\/g, "/")), this.preserveMultipleSlashes = !!e.preserveMultipleSlashes, this.regexp = null, this.negate = !1, this.nonegate = !!e.nonegate, this.comment = !1, this.empty = !1, this.partial = !!e.partial, this.nocase = !!this.options.nocase, this.windowsNoMagicRoot = e.windowsNoMagicRoot !== void 0 ? e.windowsNoMagicRoot : !!(this.isWindows && this.nocase), this.globSet = [], this.globParts = [], this.set = [], this.make(); } hasMagic() { if (this.options.magicalBraces && this.set.length > 1) return !0; for (const t of this.set) for (const e of t) if (typeof e != "string") return !0; return !1; } debug(...t) { } make() { const t = this.pattern, e = this.options; if (!e.nocomment && t.charAt(0) === "#") { this.comment = !0; return; } if (!t) { this.empty = !0; return; } this.parseNegate(), this.globSet = [...new Set(this.braceExpand())], e.debug && (this.debug = (...r) => console.error(...r)), this.debug(this.pattern, this.globSet); const n = this.globSet.map((r) => this.slashSplit(r)); this.globParts = this.preprocess(n), this.debug(this.pattern, this.globParts); let i = this.globParts.map((r, o, a) => { if (this.isWindows && this.windowsNoMagicRoot) { const h = r[0] === "" && r[1] === "" && (r[2] === "?" || !G.test(r[2])) && !G.test(r[3]), l = /^[a-z]:/i.test(r[0]); if (h) return [...r.slice(0, 4), ...r.slice(4).map((c) => this.parse(c))]; if (l) return [r[0], ...r.slice(1).map((c) => this.parse(c))]; } return r.map((h) => this.parse(h)); }); if (this.debug(this.pattern, i), this.set = i.filter((r) => r.indexOf(!1) === -1), this.isWindows) for (let r = 0; r < this.set.length; r++) { const o = this.set[r]; o[0] === "" && o[1] === "" && this.globParts[r][2] === "?" && typeof o[3] == "string" && /^[a-z]:$/i.test(o[3]) && (o[2] = "?"); } this.debug(this.pattern, this.set); } // various transforms to equivalent pattern sets that are // faster to process in a filesystem walk. The goal is to // eliminate what we can, and push all ** patterns as far // to the right as possible, even if it increases the number // of patterns that we have to process. preprocess(t) { if (this.options.noglobstar) for (let n = 0; n < t.length; n++) for (let i = 0; i < t[n].length; i++) t[n][i] === "**" && (t[n][i] = "*"); const { optimizationLevel: e = 1 } = this.options; return e >= 2 ? (t = this.firstPhasePreProcess(t), t = this.secondPhasePreProcess(t)) : e >= 1 ? t = this.levelOneOptimize(t) : t = this.adjascentGlobstarOptimize(t), t; } // just get rid of adjascent ** portions adjascentGlobstarOptimize(t) { return t.map((e) => { let n = -1; for (; (n = e.indexOf("**", n + 1)) !== -1; ) { let i = n; for (; e[i + 1] === "**"; ) i++; i !== n && e.splice(n, i - n); } return e; }); } // get rid of adjascent ** and resolve .. portions levelOneOptimize(t) { return t.map((e) => (e = e.reduce((n, i) => { const r = n[n.length - 1]; return i === "**" && r === "**" ? n : i === ".." && r && r !== ".." && r !== "." && r !== "**" ? (n.pop(), n) : (n.push(i), n); }, []), e.length === 0 ? [""] : e)); } levelTwoFileOptimize(t) { Array.isArray(t) || (t = this.slashSplit(t)); let e = !1; do { if (e = !1, !this.preserveMultipleSlashes) { for (let i = 1; i < t.length - 1; i++) { const r = t[i]; i === 1 && r === "" && t[0] === "" || (r === "." || r === "") && (e = !0, t.splice(i, 1), i--); } t[0] === "." && t.length === 2 && (t[1] === "." || t[1] === "") && (e = !0, t.pop()); } let n = 0; for (; (n = t.indexOf("..", n + 1)) !== -1; ) { const i = t[n - 1]; i && i !== "." && i !== ".." && i !== "**" && (e = !0, t.splice(n - 1, 2), n -= 2); } } while (e); return t.length === 0 ? [""] : t; } // First phase: single-pattern processing // <pre> is 1 or more portions // <rest> is 1 or more portions // <p> is any portion other than ., .., '', or ** // <e> is . or '' // // **/.. is *brutal* for filesystem walking performance, because // it effectively resets the recursive walk each time it occurs, // and ** cannot be reduced out by a .. pattern part like a regexp // or most strings (other than .., ., and '') can be. // // <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>} // <pre>/<e>/<rest> -> <pre>/<rest> // <pre>/<p>/../<rest> -> <pre>/<rest> // **/**/<rest> -> **/<rest> // // **/*/<rest> -> */**/<rest> <== not valid because ** doesn't follow // this WOULD be allowed if ** did follow symlinks, or * didn't firstPhasePreProcess(t) { let e = !1; do { e = !1; for (let n of t) { let i = -1; for (; (i = n.indexOf("**", i + 1)) !== -1; ) { let o = i; for (; n[o + 1] === "**"; ) o++; o > i && n.splice(i + 1, o - i); let a = n[i + 1]; const h = n[i + 2], l = n[i + 3]; if (a !== ".." || !h || h === "." || h === ".." || !l || l === "." || l === "..") continue; e = !0, n.splice(i, 1); const c = n.slice(0); c[i] = "**", t.push(c), i--; } if (!this.preserveMultipleSlashes) { for (let o = 1; o < n.length - 1; o++) { const a = n[o]; o === 1 && a === "" && n[0] === "" || (a === "." || a === "") && (e = !0, n.splice(o, 1), o--); } n[0] === "." && n.length === 2 && (n[1] === "." || n[1] === "") && (e = !0, n.pop()); } let r = 0; for (; (r = n.indexOf("..", r + 1)) !== -1; ) { const o = n[r - 1]; if (o && o !== "." && o !== ".." && o !== "**") { e = !0; const h = r === 1 && n[r + 1] === "**" ? ["."] : []; n.splice(r - 1, 2, ...h), n.length === 0 && n.push(""), r -= 2; } } } } while (e); return t; } // second phase: multi-pattern dedupes // {<pre>/*/<rest>,<pre>/<p>/<rest>} -> <pre>/*/<rest> // {<pre>/<rest>,<pre>/<rest>} -> <pre>/<rest> // {<pre>/**/<rest>,<pre>/<rest>} -> <pre>/**/<rest> // // {<pre>/**/<rest>,<pre>/**/<p>/<rest>} -> <pre>/**/<rest> // ^-- not valid because ** doens't follow symlinks secondPhasePreProcess(t) { for (let e = 0; e < t.length - 1; e++) for (let n = e + 1; n < t.length; n++) { const i = this.partsMatch(t[e], t[n], !this.preserveMultipleSlashes); if (i) { t[e] = [], t[n] = i; break; } } return t.filter((e) => e.length); } partsMatch(t, e, n = !1) { let i = 0, r = 0, o = [], a = ""; for (; i < t.length && r < e.length; ) if (t[i] === e[r]) o.push(a === "b" ? e[r] : t[i]), i++, r++; else if (n && t[i] === "**" && e[r] === t[i + 1]) o.push(t[i]), i++; else if (n && e[r] === "**" && t[i] === e[r + 1]) o.push(e[r]), r++; else if (t[i] === "*" && e[r] && (this.options.dot || !e[r].startsWith(".")) && e[r] !== "**") { if (a === "b") return !1; a = "a", o.push(t[i]), i++, r++; } else if (e[r] === "*" && t[i] && (this.options.dot || !t[i].startsWith(".")) && t[i] !== "**") { if (a === "a") return !1; a = "b", o.push(e[r]), i++, r++; } else return !1; return t.length === e.length && o; } parseNegate() { if (this.nonegate) return; const t = this.pattern; let e = !1, n = 0; for (let i = 0; i < t.length && t.charAt(i) === "!"; i++) e = !e, n++; n && (this.pattern = t.slice(n)), this.negate = e; } // set partial to true to test if, for example, // "/a/b" matches the start of "/*/b/*/d" // Partial means, if you run out of file before you run // out of pattern, then that's fine, as long as all // the parts match. matchOne(t, e, n = !1) { const i = this.options; if (this.isWindows) { const d = typeof t[0] == "string" && /^[a-z]:$/i.test(t[0]), E = !d && t[0] === "" && t[1] === "" && t[2] === "?" && /^[a-z]:$/i.test(t[3]), v = typeof e[0] == "string" && /^[a-z]:$/i.test(e[0]), A = !v && e[0] === "" && e[1] === "" && e[2] === "?" && typeof e[3] == "string" && /^[a-z]:$/i.test(e[3]), S = E ? 3 : d ? 0 : void 0, m = A ? 3 : v ? 0 : void 0; if (typeof S == "number" && typeof m == "number") { const [N, P] = [t[S], e[m]]; N.toLowerCase() === P.toLowerCase() && (e[m] = N, m > S ? e = e.slice(m) : S > m && (t = t.slice(S))); } } const { optimizationLevel: r = 1 } = this.options; r >= 2 && (t = this.levelTwoFileOptimize(t)), this.debug("matchOne", this, { file: t, pattern: e }), this.debug("matchOne", t.length, e.length); for (var o = 0, a = 0, h = t.length, l = e.length; o < h && a < l; o++, a++) { this.debug("matchOne loop"); var c = e[a], p = t[o]; if (this.debug(e, c, p), c === !1) return !1; if (c === O) { this.debug("GLOBSTAR", [e, c, p]); var f = o, u = a + 1; if (u === l) { for (this.debug("** at the end"); o < h; o++) if (t[o] === "." || t[o] === ".." || !i.dot && t[o].charAt(0) === ".") return !1; return !0; } for (; f < h; ) { var g = t[f]; if (this.debug(` globstar while`, t, f, e, u, g), this.matchOne(t.slice(f), e.slice(u), n)) return this.debug("globstar found match!", f, h, g), !0; if (g === "." || g === ".." || !i.dot && g.charAt(0) === ".") { this.debug("dot detected!", t, f, e, u); break; } this.debug("globstar swallow a segment, and continue"), f++; } return !!(n && (this.debug(` >>> no match, partial?`, t, f, e, u), f === h)); } let d; if (typeof c == "string" ? (d = p === c, this.debug("string match", c, p, d)) : (d = c.test(p), this.debug("pattern match", c, p, d)), !d) return !1; } if (o === h && a === l) return !0; if (o === h) return n; if (a === l) return o === h - 1 && t[o] === ""; throw new Error("wtf?"); } braceExpand() { return et(this.pattern, this.options); } parse(t) { C(t); const e = this.options; if (t === "**") return O; if (t === "") return ""; let n, i = null; (n = t.match(Gt)) ? i = e.dot ? Zt : Ht : (n = t.match(Ft)) ? i = (e.nocase ? e.dot ? Wt : Ut : e.dot ? It : jt)(n[1]) : (n = t.match(Jt)) ? i = (e.nocase ? e.dot ? Xt : Vt : e.dot ? Yt : Kt)(n) : (n = t.match(kt)) ? i = e.dot ? _t : zt : (n = t.match(Bt)) && (i = qt); const r = y.fromGlob(t, this.options).toMMPattern(); return i && typeof r == "object" && Reflect.defineProperty(r, "test", { value: i }), r; } makeRe() { if (this.regexp || this.regexp === !1) return this.regexp; const t = this.set; if (!t.length) return this.regexp = !1, this.regexp; const e = this.options, n = e.noglobstar ? ee : e.dot ? se : ne, i = new Set(e.nocase ? ["i"] : []); let r = t.map((h) => { const l = h.map((c) => { if (c instanceof RegExp) for (const p of c.flags.split("")) i.add(p); return typeof c == "string" ? ae(c) : c === O ? O : c._src; }); return l.forEach((c, p) => { const f = l[p + 1], u = l[p - 1]; c !== O || u === O || (u === void 0 ? f !== void 0 && f !== O ? l[p + 1] = "(?:\\/|" + n + "\\/)?" + f : l[p] = n : f === void 0 ? l[p - 1] = u + "(?:\\/|" + n + ")?" : f !== O && (l[p - 1] = u + "(?:\\/|\\/" + n + "\\/)" + f, l[p + 1] = O)); }), l.filter((c) => c !== O).join("/"); }).join("|"); const [o, a] = t.length > 1 ? ["(?:", ")"] : ["", ""]; r = "^" + o + r + a + "$", this.negate && (r = "^(?!" + r + ").+$"); try { this.regexp = new RegExp(r, [...i].join("")); } catch { this.regexp = !1; } return this.regexp; } slashSplit(t) { return this.preserveMultipleSlashes ? t.split("/") : this.isWindows && /^\/\/[^\/]+/.test(t) ? ["", ...t.split(/\/+/)] : t.split(/\/+/); } match(t, e = this.partial) { if (this.debug("match", t, this.pattern), this.comment) return !1; if (this.empty) return t === ""; if (t === "/" && e) return !0; const n = this.options; this.isWindows && (t = t.split("\\").join("/")); const i = this.slashSplit(t); this.debug(this.pattern, "split", i); const r = this.set; this.debug(this.pattern, "set", r); let o = i[i.length - 1]; if (!o) for (let a = i.length - 2; !o && a >= 0; a--) o = i[a]; for (let a = 0; a < r.length; a++) { const h = r[a]; let l = i; if (n.matchBase && h.length === 1 && (l = [o]), this.matchOne(l, h, e)) return n.flipNegate ? !0 : !this.negate; } return n.flipNegate ? !1 : this.negate; } static defaults(t) { return w.defaults(t).Minimatch; } } w.AST = y; w.Minimatch = D; w.escape = Lt; w.unescape = M; function he(s, t = "utf-8") { switch (t) { case "utf8": case "utf-8": return new TextEncoder().encode(s); case "utf16le": case "ucs2": case "ucs-2": return le(s); case "ascii": return pe(s); case "latin1": return fe(s); case "binary": return Uint8Array.from(s, (e) => e.charCodeAt(0)); case "base64": return Uint8Array.from(atob(s), (e) => e.charCodeAt(0)); case "hex": if (!/^[\da-f]+$/i.test(s) || s.length % 2 !== 0) throw new x("Invalid hex string", "INVALID_HEX_FORMAT"); return Uint8Array.from(s.match(/.{1,2}/g).map((e) => parseInt(e, 16))); default: return console.warn("Encoding not supported, falling back to UTF-8"), new TextEncoder().encode(s); } } function Ae(s, t = "utf-8") { switch (t) { case "utf8": case "utf-8": return new TextDecoder().decode(s); case "utf16le": case "utf-16le": case "ucs2": case "ucs-2": return ue(s); case "latin1": return String.fromCharCode(...s); case "ascii": return String.fromCharCode(...s.map((e) => e & 127)); case "base64": return btoa(String.fromCharCode(...s)); case "hex": return Array.from(s).map((e) => e.toString(16).padStart(2, "0")).join(""); default: return console.warn("Unsupported encoding, falling back to UTF-8"), new TextDecoder().decode(s); } } function le(s) { const t = new Uint8Array(s.length * 2); for (let e = 0; e < s.length; e++) { const n = s.charCodeAt(e); t[e * 2] = n & 255, t[e * 2 + 1] = n >> 8; } return t; } function ue(s) { s.length % 2 !== 0 && (console.warn("Invalid UTF-16LE buffer length, truncating last byte"), s = s.slice(0, s.length - 1)); const t = new Uint16Array(s.buffer, s.byteOffset, s.byteLength / 2); return String.fromCharCode(...t); } function fe(s) { const t = new Uint8Array(s.length); for (let e = 0; e < s.length; e++) t[e] = s.charCodeAt(e) & 255; return t; } function pe(s) { const t = new Uint8Array(s.length); for (let e = 0; e < s.length; e++) t[e] = s.charCodeAt(e) & 127; return t; } const de = [ // Images ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp", ".svg", ".ico", ".tiff", ".tga", // Audio ".mp3", ".wav", ".ogg", ".flac", ".aac", ".wma", ".m4a", // Video ".mp4", ".avi", ".mov", ".wmv", ".flv", ".webm", ".mkv", ".m4v", // Documents ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", // Archives ".zip", ".rar", ".7z", ".tar", ".gz", ".bz2", // Executables ".exe", ".dll", ".so", ".dylib", ".bin", // Other binary formats ".dat", ".db", ".sqlite", ".bin", ".obj", ".fbx", ".3ds" ]; function Ne(s) { const t = s.toLowerCase().substring(s.lastIndexOf(".")); return de.includes(t); } function $e() { if (!("storage" in navigator) || !("getDirectory" in navigator.storage)) throw new rt(); } async function I(s, t, e) { return typeof navigator < "u" && navigator.locks?.request ? navigator.locks.request(`opfs:${s.replace(/\/+/g, "/").toLowerCase()}`, { mode: t }, e) : e(); } function U(s) { return Array.isArray(s) ? s : (s.startsWith("~/") ? s.slice(2) : s).split("/").filter(Boolean); } function st(s) { return typeof s == "string" ? s ?? "/" : `/${s.join("/")}`; } function nt(s) { const t = U(s); return t[t.length - 1] || ""; } function Te(s) { const t = U(s); return t.pop(), st(t); } function it(s) { return !s || s === "/" ? "/" : s.startsWith("~/") ? `/${s.slice(2)}` : s.startsWith("/") ? s : `/${s}`; } function Me(s, t = !1) { return s = s.replace(/\/$/, ""), t && !s.includes("*") ? `${s}/**` : s; } function Pe(s, t) { return w(s, t, { dot: !0, matchBase: !0 }); } function Re(s, t) { if (!t || Array.isArray(t) && t.length === 0) return !1; const e = it(s); return (Array.isArray(t) ? t : [t]).some((i) => w(e, i, { dot: !0 })); } function Ce(s) { const t = it(s), e = U(t), n = []; for (const i of e) if (!(i === "." || i === "")) if (i === "..") { if (n.length === 0) continue; n.pop(); } else n.push(i); return st(n); } function De(s) { const t = nt(s), e = t.lastIndexOf("."); return e <= 0 || e === t.length - 1 ? "" : t.slice(e); } function ge(s, t = "utf-8") { return typeof s == "string" ? he(s, t) : s instanceof Uint8Array ? s : new Uint8Array(s); } async function Le(s, t) { return I(t, "shared", async () => { const n = await (await s.getFile()).arrayBuffer(); return new Uint8Array(n); }); } async function Fe(s, t, e, n, i = {}) { const r = async () => { let o = null; const a = i.append || !1, h = !a && (i.truncate ?? !0); try { o = await s.createSyncAccessHandle(); const l = ge(t, e), c = a ? o.getSize() : 0; o.write(l, { at: c }), h && o.truncate(l.byteLength), o.flush(); } catch (l) { console.error(l); const c = a ? "append" : "write"; throw new x(`Failed to ${c} file`, `${c.toUpperCase()}_FAILED`, void 0, l); } finally { try { o?.close(); } catch { } } }; return n ? I(n, "exclusive", r) : r(); } async function je(s, t = "SHA-1", e = 50 * 1024 * 1024) { if (s instanceof File && (s = await s.arrayBuffer()), s.byteLength > e) throw new Error(`File size ${s.byteLength} bytes exceeds maximum allowed size ${e} bytes`); const n = new Uint8Array(s), i = await crypto.subtle.digest(t, n); return Array.from(new Uint8Array(i)).map((o) => o.toString(16).padStart(2, "0")).join(""); } function Ie(s, t) { if (s.length !== t.length) return !1; for (let e = 0; e < s.length; e++) if (s[e] !== t[e]) return !1; return !0; } async function Ue(s) { const t = await s.arrayBuffer(); return new Uint8Array(t); } async function We(s, t, e = {}) { const n = nt(t); return I(t, "exclusive", async () => { const i = e.recursive ?? !1, r = e.force ?? !1; e.useTrash; try { await s.removeEntry(n, { recursive: i }); } catch (o) { if (o.name === "NotFoundError") { if (!r) throw new x(`No such file or directory: ${t}`, "ENOENT", void 0, o); } else throw o.name === "InvalidModificationError" ? new x(`Directory not empty: ${t}. Use recursive option to force removal.`, "ENOTEMPTY", void 0, o) : o.name === "TypeMismatchError" && !i ? new x(`Cannot remove directory without recursive option: ${t}`, "EISDIR", void 0, o) : new x(`Failed to remove entry: ${t}`, "RM_FAILED", void 0, o); } }); } export { de as B, Ee as D, ye as F, x as O, we as P, Se as S, be as T, rt as a, me as b, xe as c, $e as d, nt as e, Te as f, Me as g, Re as h, Ne as i, st as j, De as k, ge as l, Pe as m, it as n, Le as o, Fe as p, je as q, Ce as r, U as s, Ie as t, Ue as u, We as v, I as w, he as x, Ae as y }; //# sourceMappingURL=helpers-CTCvNFs1.js.map