File Explorer

/proc/4/root/var/lang/lib/node_modules/npm/node_modules/path-scurry/dist/commonjs

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

index.js64.7 KB · 2018 lines
"use strict";var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {    if (k2 === undefined) k2 = k;    var desc = Object.getOwnPropertyDescriptor(m, k);    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {      desc = { enumerable: true, get: function() { return m[k]; } };    }    Object.defineProperty(o, k2, desc);}) : (function(o, m, k, k2) {    if (k2 === undefined) k2 = k;    o[k2] = m[k];}));var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {    Object.defineProperty(o, "default", { enumerable: true, value: v });}) : function(o, v) {    o["default"] = v;});var __importStar = (this && this.__importStar) || function (mod) {    if (mod && mod.__esModule) return mod;    var result = {};    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);    __setModuleDefault(result, mod);    return result;};Object.defineProperty(exports, "__esModule", { value: true });exports.PathScurry = exports.Path = exports.PathScurryDarwin = exports.PathScurryPosix = exports.PathScurryWin32 = exports.PathScurryBase = exports.PathPosix = exports.PathWin32 = exports.PathBase = exports.ChildrenCache = exports.ResolveCache = void 0;const lru_cache_1 = require("lru-cache");const node_path_1 = require("node:path");const node_url_1 = require("node:url");const fs_1 = require("fs");const actualFS = __importStar(require("node:fs"));const realpathSync = fs_1.realpathSync.native;// TODO: test perf of fs/promises realpath vs realpathCB,// since the promises one uses realpath.nativeconst promises_1 = require("node:fs/promises");const minipass_1 = require("minipass");const defaultFS = {    lstatSync: fs_1.lstatSync,    readdir: fs_1.readdir,    readdirSync: fs_1.readdirSync,    readlinkSync: fs_1.readlinkSync,    realpathSync,    promises: {        lstat: promises_1.lstat,        readdir: promises_1.readdir,        readlink: promises_1.readlink,        realpath: promises_1.realpath,    },};// if they just gave us require('fs') then use our defaultconst fsFromOption = (fsOption) => !fsOption || fsOption === defaultFS || fsOption === actualFS ?    defaultFS    : {        ...defaultFS,        ...fsOption,        promises: {            ...defaultFS.promises,            ...(fsOption.promises || {}),        },    };// turn something like //?/c:/ into c:\const uncDriveRegexp = /^\\\\\?\\([a-z]:)\\?$/i;const uncToDrive = (rootPath) => rootPath.replace(/\//g, '\\').replace(uncDriveRegexp, '$1\\');// windows paths are separated by either / or \const eitherSep = /[\\\/]/;const UNKNOWN = 0; // may not even exist, for all we knowconst IFIFO = 0b0001;const IFCHR = 0b0010;const IFDIR = 0b0100;const IFBLK = 0b0110;const IFREG = 0b1000;const IFLNK = 0b1010;const IFSOCK = 0b1100;const IFMT = 0b1111;// mask to unset low 4 bitsconst IFMT_UNKNOWN = ~IFMT;// set after successfully calling readdir() and getting entries.const READDIR_CALLED = 0b0000_0001_0000;// set after a successful lstat()const LSTAT_CALLED = 0b0000_0010_0000;// set if an entry (or one of its parents) is definitely not a dirconst ENOTDIR = 0b0000_0100_0000;// set if an entry (or one of its parents) does not exist// (can also be set on lstat errors like EACCES or ENAMETOOLONG)const ENOENT = 0b0000_1000_0000;// cannot have child entries -- also verify &IFMT is either IFDIR or IFLNK// set if we fail to readlinkconst ENOREADLINK = 0b0001_0000_0000;// set if we know realpath() will failconst ENOREALPATH = 0b0010_0000_0000;const ENOCHILD = ENOTDIR | ENOENT | ENOREALPATH;const TYPEMASK = 0b0011_1111_1111;const entToType = (s) => s.isFile() ? IFREG    : s.isDirectory() ? IFDIR        : s.isSymbolicLink() ? IFLNK            : s.isCharacterDevice() ? IFCHR                : s.isBlockDevice() ? IFBLK                    : s.isSocket() ? IFSOCK                        : s.isFIFO() ? IFIFO                            : UNKNOWN;// normalize unicode path namesconst normalizeCache = new lru_cache_1.LRUCache({ max: 2 ** 12 });const normalize = (s) => {    const c = normalizeCache.get(s);    if (c)        return c;    const n = s.normalize('NFKD');    normalizeCache.set(s, n);    return n;};const normalizeNocaseCache = new lru_cache_1.LRUCache({ max: 2 ** 12 });const normalizeNocase = (s) => {    const c = normalizeNocaseCache.get(s);    if (c)        return c;    const n = normalize(s.toLowerCase());    normalizeNocaseCache.set(s, n);    return n;};/** * An LRUCache for storing resolved path strings or Path objects. * @internal */class ResolveCache extends lru_cache_1.LRUCache {    constructor() {        super({ max: 256 });    }}exports.ResolveCache = ResolveCache;// In order to prevent blowing out the js heap by allocating hundreds of// thousands of Path entries when walking extremely large trees, the "children"// in this tree are represented by storing an array of Path entries in an// LRUCache, indexed by the parent.  At any time, Path.children() may return an// empty array, indicating that it doesn't know about any of its children, and// thus has to rebuild that cache.  This is fine, it just means that we don't// benefit as much from having the cached entries, but huge directory walks// don't blow out the stack, and smaller ones are still as fast as possible.////It does impose some complexity when building up the readdir data, because we//need to pass a reference to the children array that we started with./** * an LRUCache for storing child entries. * @internal */class ChildrenCache extends lru_cache_1.LRUCache {    constructor(maxSize = 16 * 1024) {        super({            maxSize,            // parent + children            sizeCalculation: a => a.length + 1,        });    }}exports.ChildrenCache = ChildrenCache;const setAsCwd = Symbol('PathScurry setAsCwd');/** * Path objects are sort of like a super-powered * {@link https://nodejs.org/docs/latest/api/fs.html#class-fsdirent fs.Dirent} * * Each one represents a single filesystem entry on disk, which may or may not * exist. It includes methods for reading various types of information via * lstat, readlink, and readdir, and caches all information to the greatest * degree possible. * * Note that fs operations that would normally throw will instead return an * "empty" value. This is in order to prevent excessive overhead from error * stack traces. */class PathBase {    /**     * the basename of this path     *     * **Important**: *always* test the path name against any test string     * usingthe {@link isNamed} method, and not by directly comparing this     * string. Otherwise, unicode path strings that the system sees as identical     * will not be properly treated as the same path, leading to incorrect     * behavior and possible security issues.     */    name;    /**     * the Path entry corresponding to the path root.     *     * @internal     */    root;    /**     * All roots found within the current PathScurry family     *     * @internal     */    roots;    /**     * a reference to the parent path, or undefined in the case of root entries     *     * @internal     */    parent;    /**     * boolean indicating whether paths are compared case-insensitively     * @internal     */    nocase;    /**     * boolean indicating that this path is the current working directory     * of the PathScurry collection that contains it.     */    isCWD = false;    // potential default fs override    #fs;    // Stats fields    #dev;    get dev() {        return this.#dev;    }    #mode;    get mode() {        return this.#mode;    }    #nlink;    get nlink() {        return this.#nlink;    }    #uid;    get uid() {        return this.#uid;    }    #gid;    get gid() {        return this.#gid;    }    #rdev;    get rdev() {        return this.#rdev;    }    #blksize;    get blksize() {        return this.#blksize;    }    #ino;    get ino() {        return this.#ino;    }    #size;    get size() {        return this.#size;    }    #blocks;    get blocks() {        return this.#blocks;    }    #atimeMs;    get atimeMs() {        return this.#atimeMs;    }    #mtimeMs;    get mtimeMs() {        return this.#mtimeMs;    }    #ctimeMs;    get ctimeMs() {        return this.#ctimeMs;    }    #birthtimeMs;    get birthtimeMs() {        return this.#birthtimeMs;    }    #atime;    get atime() {        return this.#atime;    }    #mtime;    get mtime() {        return this.#mtime;    }    #ctime;    get ctime() {        return this.#ctime;    }    #birthtime;    get birthtime() {        return this.#birthtime;    }    #matchName;    #depth;    #fullpath;    #fullpathPosix;    #relative;    #relativePosix;    #type;    #children;    #linkTarget;    #realpath;    /**     * This property is for compatibility with the Dirent class as of     * Node v20, where Dirent['parentPath'] refers to the path of the     * directory that was passed to readdir. For root entries, it's the path     * to the entry itself.     */    get parentPath() {        return (this.parent || this).fullpath();    }    /* c8 ignore start */    /**     * Deprecated alias for Dirent['parentPath'] Somewhat counterintuitively,     * this property refers to the *parent* path, not the path object itself.     *     * @deprecated     */    get path() {        return this.parentPath;    }    /* c8 ignore stop */    /**     * Do not create new Path objects directly.  They should always be accessed     * via the PathScurry class or other methods on the Path class.     *     * @internal     */    constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) {        this.name = name;        this.#matchName = nocase ? normalizeNocase(name) : normalize(name);        this.#type = type & TYPEMASK;        this.nocase = nocase;        this.roots = roots;        this.root = root || this;        this.#children = children;        this.#fullpath = opts.fullpath;        this.#relative = opts.relative;        this.#relativePosix = opts.relativePosix;        this.parent = opts.parent;        if (this.parent) {            this.#fs = this.parent.#fs;        }        else {            this.#fs = fsFromOption(opts.fs);        }    }    /**     * Returns the depth of the Path object from its root.     *     * For example, a path at `/foo/bar` would have a depth of 2.     */    depth() {        if (this.#depth !== undefined)            return this.#depth;        if (!this.parent)            return (this.#depth = 0);        return (this.#depth = this.parent.depth() + 1);    }    /**     * @internal     */    childrenCache() {        return this.#children;    }    /**     * Get the Path object referenced by the string path, resolved from this Path     */    resolve(path) {        if (!path) {            return this;        }        const rootPath = this.getRootString(path);        const dir = path.substring(rootPath.length);        const dirParts = dir.split(this.splitSep);        const result = rootPath ?            this.getRoot(rootPath).#resolveParts(dirParts)            : this.#resolveParts(dirParts);        return result;    }    #resolveParts(dirParts) {        let p = this;        for (const part of dirParts) {            p = p.child(part);        }        return p;    }    /**     * Returns the cached children Path objects, if still available.  If they     * have fallen out of the cache, then returns an empty array, and resets the     * READDIR_CALLED bit, so that future calls to readdir() will require an fs     * lookup.     *     * @internal     */    children() {        const cached = this.#children.get(this);        if (cached) {            return cached;        }        const children = Object.assign([], { provisional: 0 });        this.#children.set(this, children);        this.#type &= ~READDIR_CALLED;        return children;    }    /**     * Resolves a path portion and returns or creates the child Path.     *     * Returns `this` if pathPart is `''` or `'.'`, or `parent` if pathPart is     * `'..'`.     *     * This should not be called directly.  If `pathPart` contains any path     * separators, it will lead to unsafe undefined behavior.     *     * Use `Path.resolve()` instead.     *     * @internal     */    child(pathPart, opts) {        if (pathPart === '' || pathPart === '.') {            return this;        }        if (pathPart === '..') {            return this.parent || this;        }        // find the child        const children = this.children();        const name = this.nocase ? normalizeNocase(pathPart) : normalize(pathPart);        for (const p of children) {            if (p.#matchName === name) {                return p;            }        }        // didn't find it, create provisional child, since it might not        // actually exist.  If we know the parent isn't a dir, then        // in fact it CAN'T exist.        const s = this.parent ? this.sep : '';        const fullpath = this.#fullpath ? this.#fullpath + s + pathPart : undefined;        const pchild = this.newChild(pathPart, UNKNOWN, {            ...opts,            parent: this,            fullpath,        });        if (!this.canReaddir()) {            pchild.#type |= ENOENT;        }        // don't have to update provisional, because if we have real children,        // then provisional is set to children.length, otherwise a lower number        children.push(pchild);        return pchild;    }    /**     * The relative path from the cwd. If it does not share an ancestor with     * the cwd, then this ends up being equivalent to the fullpath()     */    relative() {        if (this.isCWD)            return '';        if (this.#relative !== undefined) {            return this.#relative;        }        const name = this.name;        const p = this.parent;        if (!p) {            return (this.#relative = this.name);        }        const pv = p.relative();        return pv + (!pv || !p.parent ? '' : this.sep) + name;    }    /**     * The relative path from the cwd, using / as the path separator.     * If it does not share an ancestor with     * the cwd, then this ends up being equivalent to the fullpathPosix()     * On posix systems, this is identical to relative().     */    relativePosix() {        if (this.sep === '/')            return this.relative();        if (this.isCWD)            return '';        if (this.#relativePosix !== undefined)            return this.#relativePosix;        const name = this.name;        const p = this.parent;        if (!p) {            return (this.#relativePosix = this.fullpathPosix());        }        const pv = p.relativePosix();        return pv + (!pv || !p.parent ? '' : '/') + name;    }    /**     * The fully resolved path string for this Path entry     */    fullpath() {        if (this.#fullpath !== undefined) {            return this.#fullpath;        }        const name = this.name;        const p = this.parent;        if (!p) {            return (this.#fullpath = this.name);        }        const pv = p.fullpath();        const fp = pv + (!p.parent ? '' : this.sep) + name;        return (this.#fullpath = fp);    }    /**     * On platforms other than windows, this is identical to fullpath.     *     * On windows, this is overridden to return the forward-slash form of the     * full UNC path.     */    fullpathPosix() {        if (this.#fullpathPosix !== undefined)            return this.#fullpathPosix;        if (this.sep === '/')            return (this.#fullpathPosix = this.fullpath());        if (!this.parent) {            const p = this.fullpath().replace(/\\/g, '/');            if (/^[a-z]:\//i.test(p)) {                return (this.#fullpathPosix = `//?/${p}`);            }            else {                return (this.#fullpathPosix = p);            }        }        const p = this.parent;        const pfpp = p.fullpathPosix();        const fpp = pfpp + (!pfpp || !p.parent ? '' : '/') + this.name;        return (this.#fullpathPosix = fpp);    }    /**     * Is the Path of an unknown type?     *     * Note that we might know *something* about it if there has been a previous     * filesystem operation, for example that it does not exist, or is not a     * link, or whether it has child entries.     */    isUnknown() {        return (this.#type & IFMT) === UNKNOWN;    }    isType(type) {        return this[`is${type}`]();    }    getType() {        return (this.isUnknown() ? 'Unknown'            : this.isDirectory() ? 'Directory'                : this.isFile() ? 'File'                    : this.isSymbolicLink() ? 'SymbolicLink'                        : this.isFIFO() ? 'FIFO'                            : this.isCharacterDevice() ? 'CharacterDevice'                                : this.isBlockDevice() ? 'BlockDevice'                                    : /* c8 ignore start */ this.isSocket() ? 'Socket'                                        : 'Unknown');        /* c8 ignore stop */    }    /**     * Is the Path a regular file?     */    isFile() {        return (this.#type & IFMT) === IFREG;    }    /**     * Is the Path a directory?     */    isDirectory() {        return (this.#type & IFMT) === IFDIR;    }    /**     * Is the path a character device?     */    isCharacterDevice() {        return (this.#type & IFMT) === IFCHR;    }    /**     * Is the path a block device?     */    isBlockDevice() {        return (this.#type & IFMT) === IFBLK;    }    /**     * Is the path a FIFO pipe?     */    isFIFO() {        return (this.#type & IFMT) === IFIFO;    }    /**     * Is the path a socket?     */    isSocket() {        return (this.#type & IFMT) === IFSOCK;    }    /**     * Is the path a symbolic link?     */    isSymbolicLink() {        return (this.#type & IFLNK) === IFLNK;    }    /**     * Return the entry if it has been subject of a successful lstat, or     * undefined otherwise.     *     * Does not read the filesystem, so an undefined result *could* simply     * mean that we haven't called lstat on it.     */    lstatCached() {        return this.#type & LSTAT_CALLED ? this : undefined;    }    /**     * Return the cached link target if the entry has been the subject of a     * successful readlink, or undefined otherwise.     *     * Does not read the filesystem, so an undefined result *could* just mean we     * don't have any cached data. Only use it if you are very sure that a     * readlink() has been called at some point.     */    readlinkCached() {        return this.#linkTarget;    }    /**     * Returns the cached realpath target if the entry has been the subject     * of a successful realpath, or undefined otherwise.     *     * Does not read the filesystem, so an undefined result *could* just mean we     * don't have any cached data. Only use it if you are very sure that a     * realpath() has been called at some point.     */    realpathCached() {        return this.#realpath;    }    /**     * Returns the cached child Path entries array if the entry has been the     * subject of a successful readdir(), or [] otherwise.     *     * Does not read the filesystem, so an empty array *could* just mean we     * don't have any cached data. Only use it if you are very sure that a     * readdir() has been called recently enough to still be valid.     */    readdirCached() {        const children = this.children();        return children.slice(0, children.provisional);    }    /**     * Return true if it's worth trying to readlink.  Ie, we don't (yet) have     * any indication that readlink will definitely fail.     *     * Returns false if the path is known to not be a symlink, if a previous     * readlink failed, or if the entry does not exist.     */    canReadlink() {        if (this.#linkTarget)            return true;        if (!this.parent)            return false;        // cases where it cannot possibly succeed        const ifmt = this.#type & IFMT;        return !((ifmt !== UNKNOWN && ifmt !== IFLNK) ||            this.#type & ENOREADLINK ||            this.#type & ENOENT);    }    /**     * Return true if readdir has previously been successfully called on this     * path, indicating that cachedReaddir() is likely valid.     */    calledReaddir() {        return !!(this.#type & READDIR_CALLED);    }    /**     * Returns true if the path is known to not exist. That is, a previous lstat     * or readdir failed to verify its existence when that would have been     * expected, or a parent entry was marked either enoent or enotdir.     */    isENOENT() {        return !!(this.#type & ENOENT);    }    /**     * Return true if the path is a match for the given path name.  This handles     * case sensitivity and unicode normalization.     *     * Note: even on case-sensitive systems, it is **not** safe to test the     * equality of the `.name` property to determine whether a given pathname     * matches, due to unicode normalization mismatches.     *     * Always use this method instead of testing the `path.name` property     * directly.     */    isNamed(n) {        return !this.nocase ?            this.#matchName === normalize(n)            : this.#matchName === normalizeNocase(n);    }    /**     * Return the Path object corresponding to the target of a symbolic link.     *     * If the Path is not a symbolic link, or if the readlink call fails for any     * reason, `undefined` is returned.     *     * Result is cached, and thus may be outdated if the filesystem is mutated.     */    async readlink() {        const target = this.#linkTarget;        if (target) {            return target;        }        if (!this.canReadlink()) {            return undefined;        }        /* c8 ignore start */        // already covered by the canReadlink test, here for ts grumples        if (!this.parent) {            return undefined;        }        /* c8 ignore stop */        try {            const read = await this.#fs.promises.readlink(this.fullpath());            const linkTarget = (await this.parent.realpath())?.resolve(read);            if (linkTarget) {                return (this.#linkTarget = linkTarget);            }        }        catch (er) {            this.#readlinkFail(er.code);            return undefined;        }    }    /**     * Synchronous {@link PathBase.readlink}     */    readlinkSync() {        const target = this.#linkTarget;        if (target) {            return target;        }        if (!this.canReadlink()) {            return undefined;        }        /* c8 ignore start */        // already covered by the canReadlink test, here for ts grumples        if (!this.parent) {            return undefined;        }        /* c8 ignore stop */        try {            const read = this.#fs.readlinkSync(this.fullpath());            const linkTarget = this.parent.realpathSync()?.resolve(read);            if (linkTarget) {                return (this.#linkTarget = linkTarget);            }        }        catch (er) {            this.#readlinkFail(er.code);            return undefined;        }    }    #readdirSuccess(children) {        // succeeded, mark readdir called bit        this.#type |= READDIR_CALLED;        // mark all remaining provisional children as ENOENT        for (let p = children.provisional; p < children.length; p++) {            const c = children[p];            if (c)                c.#markENOENT();        }    }    #markENOENT() {        // mark as UNKNOWN and ENOENT        if (this.#type & ENOENT)            return;        this.#type = (this.#type | ENOENT) & IFMT_UNKNOWN;        this.#markChildrenENOENT();    }    #markChildrenENOENT() {        // all children are provisional and do not exist        const children = this.children();        children.provisional = 0;        for (const p of children) {            p.#markENOENT();        }    }    #markENOREALPATH() {        this.#type |= ENOREALPATH;        this.#markENOTDIR();    }    // save the information when we know the entry is not a dir    #markENOTDIR() {        // entry is not a directory, so any children can't exist.        // this *should* be impossible, since any children created        // after it's been marked ENOTDIR should be marked ENOENT,        // so it won't even get to this point.        /* c8 ignore start */        if (this.#type & ENOTDIR)            return;        /* c8 ignore stop */        let t = this.#type;        // this could happen if we stat a dir, then delete it,        // then try to read it or one of its children.        if ((t & IFMT) === IFDIR)            t &= IFMT_UNKNOWN;        this.#type = t | ENOTDIR;        this.#markChildrenENOENT();    }    #readdirFail(code = '') {        // markENOTDIR and markENOENT also set provisional=0        if (code === 'ENOTDIR' || code === 'EPERM') {            this.#markENOTDIR();        }        else if (code === 'ENOENT') {            this.#markENOENT();        }        else {            this.children().provisional = 0;        }    }    #lstatFail(code = '') {        // Windows just raises ENOENT in this case, disable for win CI        /* c8 ignore start */        if (code === 'ENOTDIR') {            // already know it has a parent by this point            const p = this.parent;            p.#markENOTDIR();        }        else if (code === 'ENOENT') {            /* c8 ignore stop */            this.#markENOENT();        }    }    #readlinkFail(code = '') {        let ter = this.#type;        ter |= ENOREADLINK;        if (code === 'ENOENT')            ter |= ENOENT;        // windows gets a weird error when you try to readlink a file        if (code === 'EINVAL' || code === 'UNKNOWN') {            // exists, but not a symlink, we don't know WHAT it is, so remove            // all IFMT bits.            ter &= IFMT_UNKNOWN;        }        this.#type = ter;        // windows just gets ENOENT in this case.  We do cover the case,        // just disabled because it's impossible on Windows CI        /* c8 ignore start */        if (code === 'ENOTDIR' && this.parent) {            this.parent.#markENOTDIR();        }        /* c8 ignore stop */    }    #readdirAddChild(e, c) {        return (this.#readdirMaybePromoteChild(e, c) ||            this.#readdirAddNewChild(e, c));    }    #readdirAddNewChild(e, c) {        // alloc new entry at head, so it's never provisional        const type = entToType(e);        const child = this.newChild(e.name, type, { parent: this });        const ifmt = child.#type & IFMT;        if (ifmt !== IFDIR && ifmt !== IFLNK && ifmt !== UNKNOWN) {            child.#type |= ENOTDIR;        }        c.unshift(child);        c.provisional++;        return child;    }    #readdirMaybePromoteChild(e, c) {        for (let p = c.provisional; p < c.length; p++) {            const pchild = c[p];            const name = this.nocase ? normalizeNocase(e.name) : normalize(e.name);            if (name !== pchild.#matchName) {                continue;            }            return this.#readdirPromoteChild(e, pchild, p, c);        }    }    #readdirPromoteChild(e, p, index, c) {        const v = p.name;        // retain any other flags, but set ifmt from dirent        p.#type = (p.#type & IFMT_UNKNOWN) | entToType(e);        // case sensitivity fixing when we learn the true name.        if (v !== e.name)            p.name = e.name;        // just advance provisional index (potentially off the list),        // otherwise we have to splice/pop it out and re-insert at head        if (index !== c.provisional) {            if (index === c.length - 1)                c.pop();            else                c.splice(index, 1);            c.unshift(p);        }        c.provisional++;        return p;    }    /**     * Call lstat() on this Path, and update all known information that can be     * determined.     *     * Note that unlike `fs.lstat()`, the returned value does not contain some     * information, such as `mode`, `dev`, `nlink`, and `ino`.  If that     * information is required, you will need to call `fs.lstat` yourself.     *     * If the Path refers to a nonexistent file, or if the lstat call fails for     * any reason, `undefined` is returned.  Otherwise the updated Path object is     * returned.     *     * Results are cached, and thus may be out of date if the filesystem is     * mutated.     */    async lstat() {        if ((this.#type & ENOENT) === 0) {            try {                this.#applyStat(await this.#fs.promises.lstat(this.fullpath()));                return this;            }            catch (er) {                this.#lstatFail(er.code);            }        }    }    /**     * synchronous {@link PathBase.lstat}     */    lstatSync() {        if ((this.#type & ENOENT) === 0) {            try {                this.#applyStat(this.#fs.lstatSync(this.fullpath()));                return this;            }            catch (er) {                this.#lstatFail(er.code);            }        }    }    #applyStat(st) {        const { atime, atimeMs, birthtime, birthtimeMs, blksize, blocks, ctime, ctimeMs, dev, gid, ino, mode, mtime, mtimeMs, nlink, rdev, size, uid, } = st;        this.#atime = atime;        this.#atimeMs = atimeMs;        this.#birthtime = birthtime;        this.#birthtimeMs = birthtimeMs;        this.#blksize = blksize;        this.#blocks = blocks;        this.#ctime = ctime;        this.#ctimeMs = ctimeMs;        this.#dev = dev;        this.#gid = gid;        this.#ino = ino;        this.#mode = mode;        this.#mtime = mtime;        this.#mtimeMs = mtimeMs;        this.#nlink = nlink;        this.#rdev = rdev;        this.#size = size;        this.#uid = uid;        const ifmt = entToType(st);        // retain any other flags, but set the ifmt        this.#type = (this.#type & IFMT_UNKNOWN) | ifmt | LSTAT_CALLED;        if (ifmt !== UNKNOWN && ifmt !== IFDIR && ifmt !== IFLNK) {            this.#type |= ENOTDIR;        }    }    #onReaddirCB = [];    #readdirCBInFlight = false;    #callOnReaddirCB(children) {        this.#readdirCBInFlight = false;        const cbs = this.#onReaddirCB.slice();        this.#onReaddirCB.length = 0;        cbs.forEach(cb => cb(null, children));    }    /**     * Standard node-style callback interface to get list of directory entries.     *     * If the Path cannot or does not contain any children, then an empty array     * is returned.     *     * Results are cached, and thus may be out of date if the filesystem is     * mutated.     *     * @param cb The callback called with (er, entries).  Note that the `er`     * param is somewhat extraneous, as all readdir() errors are handled and     * simply result in an empty set of entries being returned.     * @param allowZalgo Boolean indicating that immediately known results should     * *not* be deferred with `queueMicrotask`. Defaults to `false`. Release     * zalgo at your peril, the dark pony lord is devious and unforgiving.     */    readdirCB(cb, allowZalgo = false) {        if (!this.canReaddir()) {            if (allowZalgo)                cb(null, []);            else                queueMicrotask(() => cb(null, []));            return;        }        const children = this.children();        if (this.calledReaddir()) {            const c = children.slice(0, children.provisional);            if (allowZalgo)                cb(null, c);            else                queueMicrotask(() => cb(null, c));            return;        }        // don't have to worry about zalgo at this point.        this.#onReaddirCB.push(cb);        if (this.#readdirCBInFlight) {            return;        }        this.#readdirCBInFlight = true;        // else read the directory, fill up children        // de-provisionalize any provisional children.        const fullpath = this.fullpath();        this.#fs.readdir(fullpath, { withFileTypes: true }, (er, entries) => {            if (er) {                this.#readdirFail(er.code);                children.provisional = 0;            }            else {                // if we didn't get an error, we always get entries.                //@ts-ignore                for (const e of entries) {                    this.#readdirAddChild(e, children);                }                this.#readdirSuccess(children);            }            this.#callOnReaddirCB(children.slice(0, children.provisional));            return;        });    }    #asyncReaddirInFlight;    /**     * Return an array of known child entries.     *     * If the Path cannot or does not contain any children, then an empty array     * is returned.     *     * Results are cached, and thus may be out of date if the filesystem is     * mutated.     */    async readdir() {        if (!this.canReaddir()) {            return [];        }        const children = this.children();        if (this.calledReaddir()) {            return children.slice(0, children.provisional);        }        // else read the directory, fill up children        // de-provisionalize any provisional children.        const fullpath = this.fullpath();        if (this.#asyncReaddirInFlight) {            await this.#asyncReaddirInFlight;        }        else {            /* c8 ignore start */            let resolve = () => { };            /* c8 ignore stop */            this.#asyncReaddirInFlight = new Promise(res => (resolve = res));            try {                for (const e of await this.#fs.promises.readdir(fullpath, {                    withFileTypes: true,                })) {                    this.#readdirAddChild(e, children);                }                this.#readdirSuccess(children);            }            catch (er) {                this.#readdirFail(er.code);                children.provisional = 0;            }            this.#asyncReaddirInFlight = undefined;            resolve();        }        return children.slice(0, children.provisional);    }    /**     * synchronous {@link PathBase.readdir}     */    readdirSync() {        if (!this.canReaddir()) {            return [];        }        const children = this.children();        if (this.calledReaddir()) {            return children.slice(0, children.provisional);        }        // else read the directory, fill up children        // de-provisionalize any provisional children.        const fullpath = this.fullpath();        try {            for (const e of this.#fs.readdirSync(fullpath, {                withFileTypes: true,            })) {                this.#readdirAddChild(e, children);            }            this.#readdirSuccess(children);        }        catch (er) {            this.#readdirFail(er.code);            children.provisional = 0;        }        return children.slice(0, children.provisional);    }    canReaddir() {        if (this.#type & ENOCHILD)            return false;        const ifmt = IFMT & this.#type;        // we always set ENOTDIR when setting IFMT, so should be impossible        /* c8 ignore start */        if (!(ifmt === UNKNOWN || ifmt === IFDIR || ifmt === IFLNK)) {            return false;        }        /* c8 ignore stop */        return true;    }    shouldWalk(dirs, walkFilter) {        return ((this.#type & IFDIR) === IFDIR &&            !(this.#type & ENOCHILD) &&            !dirs.has(this) &&            (!walkFilter || walkFilter(this)));    }    /**     * Return the Path object corresponding to path as resolved     * by realpath(3).     *     * If the realpath call fails for any reason, `undefined` is returned.     *     * Result is cached, and thus may be outdated if the filesystem is mutated.     * On success, returns a Path object.     */    async realpath() {        if (this.#realpath)            return this.#realpath;        if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type)            return undefined;        try {            const rp = await this.#fs.promises.realpath(this.fullpath());            return (this.#realpath = this.resolve(rp));        }        catch (_) {            this.#markENOREALPATH();        }    }    /**     * Synchronous {@link realpath}     */    realpathSync() {        if (this.#realpath)            return this.#realpath;        if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type)            return undefined;        try {            const rp = this.#fs.realpathSync(this.fullpath());            return (this.#realpath = this.resolve(rp));        }        catch (_) {            this.#markENOREALPATH();        }    }    /**     * Internal method to mark this Path object as the scurry cwd,     * called by {@link PathScurry#chdir}     *     * @internal     */    [setAsCwd](oldCwd) {        if (oldCwd === this)            return;        oldCwd.isCWD = false;        this.isCWD = true;        const changed = new Set([]);        let rp = [];        let p = this;        while (p && p.parent) {            changed.add(p);            p.#relative = rp.join(this.sep);            p.#relativePosix = rp.join('/');            p = p.parent;            rp.push('..');        }        // now un-memoize parents of old cwd        p = oldCwd;        while (p && p.parent && !changed.has(p)) {            p.#relative = undefined;            p.#relativePosix = undefined;            p = p.parent;        }    }}exports.PathBase = PathBase;/** * Path class used on win32 systems * * Uses `'\\'` as the path separator for returned paths, either `'\\'` or `'/'` * as the path separator for parsing paths. */class PathWin32 extends PathBase {    /**     * Separator for generating path strings.     */    sep = '\\';    /**     * Separator for parsing path strings.     */    splitSep = eitherSep;    /**     * Do not create new Path objects directly.  They should always be accessed     * via the PathScurry class or other methods on the Path class.     *     * @internal     */    constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) {        super(name, type, root, roots, nocase, children, opts);    }    /**     * @internal     */    newChild(name, type = UNKNOWN, opts = {}) {        return new PathWin32(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts);    }    /**     * @internal     */    getRootString(path) {        return node_path_1.win32.parse(path).root;    }    /**     * @internal     */    getRoot(rootPath) {        rootPath = uncToDrive(rootPath.toUpperCase());        if (rootPath === this.root.name) {            return this.root;        }        // ok, not that one, check if it matches another we know about        for (const [compare, root] of Object.entries(this.roots)) {            if (this.sameRoot(rootPath, compare)) {                return (this.roots[rootPath] = root);            }        }        // otherwise, have to create a new one.        return (this.roots[rootPath] = new PathScurryWin32(rootPath, this).root);    }    /**     * @internal     */    sameRoot(rootPath, compare = this.root.name) {        // windows can (rarely) have case-sensitive filesystem, but        // UNC and drive letters are always case-insensitive, and canonically        // represented uppercase.        rootPath = rootPath            .toUpperCase()            .replace(/\//g, '\\')            .replace(uncDriveRegexp, '$1\\');        return rootPath === compare;    }}exports.PathWin32 = PathWin32;/** * Path class used on all posix systems. * * Uses `'/'` as the path separator. */class PathPosix extends PathBase {    /**     * separator for parsing path strings     */    splitSep = '/';    /**     * separator for generating path strings     */    sep = '/';    /**     * Do not create new Path objects directly.  They should always be accessed     * via the PathScurry class or other methods on the Path class.     *     * @internal     */    constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) {        super(name, type, root, roots, nocase, children, opts);    }    /**     * @internal     */    getRootString(path) {        return path.startsWith('/') ? '/' : '';    }    /**     * @internal     */    getRoot(_rootPath) {        return this.root;    }    /**     * @internal     */    newChild(name, type = UNKNOWN, opts = {}) {        return new PathPosix(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts);    }}exports.PathPosix = PathPosix;/** * The base class for all PathScurry classes, providing the interface for path * resolution and filesystem operations. * * Typically, you should *not* instantiate this class directly, but rather one * of the platform-specific classes, or the exported {@link PathScurry} which * defaults to the current platform. */class PathScurryBase {    /**     * The root Path entry for the current working directory of this Scurry     */    root;    /**     * The string path for the root of this Scurry's current working directory     */    rootPath;    /**     * A collection of all roots encountered, referenced by rootPath     */    roots;    /**     * The Path entry corresponding to this PathScurry's current working directory.     */    cwd;    #resolveCache;    #resolvePosixCache;    #children;    /**     * Perform path comparisons case-insensitively.     *     * Defaults true on Darwin and Windows systems, false elsewhere.     */    nocase;    #fs;    /**     * This class should not be instantiated directly.     *     * Use PathScurryWin32, PathScurryDarwin, PathScurryPosix, or PathScurry     *     * @internal     */    constructor(cwd = process.cwd(), pathImpl, sep, { nocase, childrenCacheSize = 16 * 1024, fs = defaultFS, } = {}) {        this.#fs = fsFromOption(fs);        if (cwd instanceof URL || cwd.startsWith('file://')) {            cwd = (0, node_url_1.fileURLToPath)(cwd);        }        // resolve and split root, and then add to the store.        // this is the only time we call path.resolve()        const cwdPath = pathImpl.resolve(cwd);        this.roots = Object.create(null);        this.rootPath = this.parseRootPath(cwdPath);        this.#resolveCache = new ResolveCache();        this.#resolvePosixCache = new ResolveCache();        this.#children = new ChildrenCache(childrenCacheSize);        const split = cwdPath.substring(this.rootPath.length).split(sep);        // resolve('/') leaves '', splits to [''], we don't want that.        if (split.length === 1 && !split[0]) {            split.pop();        }        /* c8 ignore start */        if (nocase === undefined) {            throw new TypeError('must provide nocase setting to PathScurryBase ctor');        }        /* c8 ignore stop */        this.nocase = nocase;        this.root = this.newRoot(this.#fs);        this.roots[this.rootPath] = this.root;        let prev = this.root;        let len = split.length - 1;        const joinSep = pathImpl.sep;        let abs = this.rootPath;        let sawFirst = false;        for (const part of split) {            const l = len--;            prev = prev.child(part, {                relative: new Array(l).fill('..').join(joinSep),                relativePosix: new Array(l).fill('..').join('/'),                fullpath: (abs += (sawFirst ? '' : joinSep) + part),            });            sawFirst = true;        }        this.cwd = prev;    }    /**     * Get the depth of a provided path, string, or the cwd     */    depth(path = this.cwd) {        if (typeof path === 'string') {            path = this.cwd.resolve(path);        }        return path.depth();    }    /**     * Return the cache of child entries.  Exposed so subclasses can create     * child Path objects in a platform-specific way.     *     * @internal     */    childrenCache() {        return this.#children;    }    /**     * Resolve one or more path strings to a resolved string     *     * Same interface as require('path').resolve.     *     * Much faster than path.resolve() when called multiple times for the same     * path, because the resolved Path objects are cached.  Much slower     * otherwise.     */    resolve(...paths) {        // first figure out the minimum number of paths we have to test        // we always start at cwd, but any absolutes will bump the start        let r = '';        for (let i = paths.length - 1; i >= 0; i--) {            const p = paths[i];            if (!p || p === '.')                continue;            r = r ? `${p}/${r}` : p;            if (this.isAbsolute(p)) {                break;            }        }        const cached = this.#resolveCache.get(r);        if (cached !== undefined) {            return cached;        }        const result = this.cwd.resolve(r).fullpath();        this.#resolveCache.set(r, result);        return result;    }    /**     * Resolve one or more path strings to a resolved string, returning     * the posix path.  Identical to .resolve() on posix systems, but on     * windows will return a forward-slash separated UNC path.     *     * Same interface as require('path').resolve.     *     * Much faster than path.resolve() when called multiple times for the same     * path, because the resolved Path objects are cached.  Much slower     * otherwise.     */    resolvePosix(...paths) {        // first figure out the minimum number of paths we have to test        // we always start at cwd, but any absolutes will bump the start        let r = '';        for (let i = paths.length - 1; i >= 0; i--) {            const p = paths[i];            if (!p || p === '.')                continue;            r = r ? `${p}/${r}` : p;            if (this.isAbsolute(p)) {                break;            }        }        const cached = this.#resolvePosixCache.get(r);        if (cached !== undefined) {            return cached;        }        const result = this.cwd.resolve(r).fullpathPosix();        this.#resolvePosixCache.set(r, result);        return result;    }    /**     * find the relative path from the cwd to the supplied path string or entry     */    relative(entry = this.cwd) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        return entry.relative();    }    /**     * find the relative path from the cwd to the supplied path string or     * entry, using / as the path delimiter, even on Windows.     */    relativePosix(entry = this.cwd) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        return entry.relativePosix();    }    /**     * Return the basename for the provided string or Path object     */    basename(entry = this.cwd) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        return entry.name;    }    /**     * Return the dirname for the provided string or Path object     */    dirname(entry = this.cwd) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        return (entry.parent || entry).fullpath();    }    async readdir(entry = this.cwd, opts = {        withFileTypes: true,    }) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        else if (!(entry instanceof PathBase)) {            opts = entry;            entry = this.cwd;        }        const { withFileTypes } = opts;        if (!entry.canReaddir()) {            return [];        }        else {            const p = await entry.readdir();            return withFileTypes ? p : p.map(e => e.name);        }    }    readdirSync(entry = this.cwd, opts = {        withFileTypes: true,    }) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        else if (!(entry instanceof PathBase)) {            opts = entry;            entry = this.cwd;        }        const { withFileTypes = true } = opts;        if (!entry.canReaddir()) {            return [];        }        else if (withFileTypes) {            return entry.readdirSync();        }        else {            return entry.readdirSync().map(e => e.name);        }    }    /**     * Call lstat() on the string or Path object, and update all known     * information that can be determined.     *     * Note that unlike `fs.lstat()`, the returned value does not contain some     * information, such as `mode`, `dev`, `nlink`, and `ino`.  If that     * information is required, you will need to call `fs.lstat` yourself.     *     * If the Path refers to a nonexistent file, or if the lstat call fails for     * any reason, `undefined` is returned.  Otherwise the updated Path object is     * returned.     *     * Results are cached, and thus may be out of date if the filesystem is     * mutated.     */    async lstat(entry = this.cwd) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        return entry.lstat();    }    /**     * synchronous {@link PathScurryBase.lstat}     */    lstatSync(entry = this.cwd) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        return entry.lstatSync();    }    async readlink(entry = this.cwd, { withFileTypes } = {        withFileTypes: false,    }) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        else if (!(entry instanceof PathBase)) {            withFileTypes = entry.withFileTypes;            entry = this.cwd;        }        const e = await entry.readlink();        return withFileTypes ? e : e?.fullpath();    }    readlinkSync(entry = this.cwd, { withFileTypes } = {        withFileTypes: false,    }) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        else if (!(entry instanceof PathBase)) {            withFileTypes = entry.withFileTypes;            entry = this.cwd;        }        const e = entry.readlinkSync();        return withFileTypes ? e : e?.fullpath();    }    async realpath(entry = this.cwd, { withFileTypes } = {        withFileTypes: false,    }) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        else if (!(entry instanceof PathBase)) {            withFileTypes = entry.withFileTypes;            entry = this.cwd;        }        const e = await entry.realpath();        return withFileTypes ? e : e?.fullpath();    }    realpathSync(entry = this.cwd, { withFileTypes } = {        withFileTypes: false,    }) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        else if (!(entry instanceof PathBase)) {            withFileTypes = entry.withFileTypes;            entry = this.cwd;        }        const e = entry.realpathSync();        return withFileTypes ? e : e?.fullpath();    }    async walk(entry = this.cwd, opts = {}) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        else if (!(entry instanceof PathBase)) {            opts = entry;            entry = this.cwd;        }        const { withFileTypes = true, follow = false, filter, walkFilter, } = opts;        const results = [];        if (!filter || filter(entry)) {            results.push(withFileTypes ? entry : entry.fullpath());        }        const dirs = new Set();        const walk = (dir, cb) => {            dirs.add(dir);            dir.readdirCB((er, entries) => {                /* c8 ignore start */                if (er) {                    return cb(er);                }                /* c8 ignore stop */                let len = entries.length;                if (!len)                    return cb();                const next = () => {                    if (--len === 0) {                        cb();                    }                };                for (const e of entries) {                    if (!filter || filter(e)) {                        results.push(withFileTypes ? e : e.fullpath());                    }                    if (follow && e.isSymbolicLink()) {                        e.realpath()                            .then(r => (r?.isUnknown() ? r.lstat() : r))                            .then(r => r?.shouldWalk(dirs, walkFilter) ? walk(r, next) : next());                    }                    else {                        if (e.shouldWalk(dirs, walkFilter)) {                            walk(e, next);                        }                        else {                            next();                        }                    }                }            }, true); // zalgooooooo        };        const start = entry;        return new Promise((res, rej) => {            walk(start, er => {                /* c8 ignore start */                if (er)                    return rej(er);                /* c8 ignore stop */                res(results);            });        });    }    walkSync(entry = this.cwd, opts = {}) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        else if (!(entry instanceof PathBase)) {            opts = entry;            entry = this.cwd;        }        const { withFileTypes = true, follow = false, filter, walkFilter, } = opts;        const results = [];        if (!filter || filter(entry)) {            results.push(withFileTypes ? entry : entry.fullpath());        }        const dirs = new Set([entry]);        for (const dir of dirs) {            const entries = dir.readdirSync();            for (const e of entries) {                if (!filter || filter(e)) {                    results.push(withFileTypes ? e : e.fullpath());                }                let r = e;                if (e.isSymbolicLink()) {                    if (!(follow && (r = e.realpathSync())))                        continue;                    if (r.isUnknown())                        r.lstatSync();                }                if (r.shouldWalk(dirs, walkFilter)) {                    dirs.add(r);                }            }        }        return results;    }    /**     * Support for `for await`     *     * Alias for {@link PathScurryBase.iterate}     *     * Note: As of Node 19, this is very slow, compared to other methods of     * walking.  Consider using {@link PathScurryBase.stream} if memory overhead     * and backpressure are concerns, or {@link PathScurryBase.walk} if not.     */    [Symbol.asyncIterator]() {        return this.iterate();    }    iterate(entry = this.cwd, options = {}) {        // iterating async over the stream is significantly more performant,        // especially in the warm-cache scenario, because it buffers up directory        // entries in the background instead of waiting for a yield for each one.        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        else if (!(entry instanceof PathBase)) {            options = entry;            entry = this.cwd;        }        return this.stream(entry, options)[Symbol.asyncIterator]();    }    /**     * Iterating over a PathScurry performs a synchronous walk.     *     * Alias for {@link PathScurryBase.iterateSync}     */    [Symbol.iterator]() {        return this.iterateSync();    }    *iterateSync(entry = this.cwd, opts = {}) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        else if (!(entry instanceof PathBase)) {            opts = entry;            entry = this.cwd;        }        const { withFileTypes = true, follow = false, filter, walkFilter, } = opts;        if (!filter || filter(entry)) {            yield withFileTypes ? entry : entry.fullpath();        }        const dirs = new Set([entry]);        for (const dir of dirs) {            const entries = dir.readdirSync();            for (const e of entries) {                if (!filter || filter(e)) {                    yield withFileTypes ? e : e.fullpath();                }                let r = e;                if (e.isSymbolicLink()) {                    if (!(follow && (r = e.realpathSync())))                        continue;                    if (r.isUnknown())                        r.lstatSync();                }                if (r.shouldWalk(dirs, walkFilter)) {                    dirs.add(r);                }            }        }    }    stream(entry = this.cwd, opts = {}) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        else if (!(entry instanceof PathBase)) {            opts = entry;            entry = this.cwd;        }        const { withFileTypes = true, follow = false, filter, walkFilter, } = opts;        const results = new minipass_1.Minipass({ objectMode: true });        if (!filter || filter(entry)) {            results.write(withFileTypes ? entry : entry.fullpath());        }        const dirs = new Set();        const queue = [entry];        let processing = 0;        const process = () => {            let paused = false;            while (!paused) {                const dir = queue.shift();                if (!dir) {                    if (processing === 0)                        results.end();                    return;                }                processing++;                dirs.add(dir);                const onReaddir = (er, entries, didRealpaths = false) => {                    /* c8 ignore start */                    if (er)                        return results.emit('error', er);                    /* c8 ignore stop */                    if (follow && !didRealpaths) {                        const promises = [];                        for (const e of entries) {                            if (e.isSymbolicLink()) {                                promises.push(e                                    .realpath()                                    .then((r) => r?.isUnknown() ? r.lstat() : r));                            }                        }                        if (promises.length) {                            Promise.all(promises).then(() => onReaddir(null, entries, true));                            return;                        }                    }                    for (const e of entries) {                        if (e && (!filter || filter(e))) {                            if (!results.write(withFileTypes ? e : e.fullpath())) {                                paused = true;                            }                        }                    }                    processing--;                    for (const e of entries) {                        const r = e.realpathCached() || e;                        if (r.shouldWalk(dirs, walkFilter)) {                            queue.push(r);                        }                    }                    if (paused && !results.flowing) {                        results.once('drain', process);                    }                    else if (!sync) {                        process();                    }                };                // zalgo containment                let sync = true;                dir.readdirCB(onReaddir, true);                sync = false;            }        };        process();        return results;    }    streamSync(entry = this.cwd, opts = {}) {        if (typeof entry === 'string') {            entry = this.cwd.resolve(entry);        }        else if (!(entry instanceof PathBase)) {            opts = entry;            entry = this.cwd;        }        const { withFileTypes = true, follow = false, filter, walkFilter, } = opts;        const results = new minipass_1.Minipass({ objectMode: true });        const dirs = new Set();        if (!filter || filter(entry)) {            results.write(withFileTypes ? entry : entry.fullpath());        }        const queue = [entry];        let processing = 0;        const process = () => {            let paused = false;            while (!paused) {                const dir = queue.shift();                if (!dir) {                    if (processing === 0)                        results.end();                    return;                }                processing++;                dirs.add(dir);                const entries = dir.readdirSync();                for (const e of entries) {                    if (!filter || filter(e)) {                        if (!results.write(withFileTypes ? e : e.fullpath())) {                            paused = true;                        }                    }                }                processing--;                for (const e of entries) {                    let r = e;                    if (e.isSymbolicLink()) {                        if (!(follow && (r = e.realpathSync())))                            continue;                        if (r.isUnknown())                            r.lstatSync();                    }                    if (r.shouldWalk(dirs, walkFilter)) {                        queue.push(r);                    }                }            }            if (paused && !results.flowing)                results.once('drain', process);        };        process();        return results;    }    chdir(path = this.cwd) {        const oldCwd = this.cwd;        this.cwd = typeof path === 'string' ? this.cwd.resolve(path) : path;        this.cwd[setAsCwd](oldCwd);    }}exports.PathScurryBase = PathScurryBase;/** * Windows implementation of {@link PathScurryBase} * * Defaults to case insensitve, uses `'\\'` to generate path strings.  Uses * {@link PathWin32} for Path objects. */class PathScurryWin32 extends PathScurryBase {    /**     * separator for generating path strings     */    sep = '\\';    constructor(cwd = process.cwd(), opts = {}) {        const { nocase = true } = opts;        super(cwd, node_path_1.win32, '\\', { ...opts, nocase });        this.nocase = nocase;        for (let p = this.cwd; p; p = p.parent) {            p.nocase = this.nocase;        }    }    /**     * @internal     */    parseRootPath(dir) {        // if the path starts with a single separator, it's not a UNC, and we'll        // just get separator as the root, and driveFromUNC will return \        // In that case, mount \ on the root from the cwd.        return node_path_1.win32.parse(dir).root.toUpperCase();    }    /**     * @internal     */    newRoot(fs) {        return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs });    }    /**     * Return true if the provided path string is an absolute path     */    isAbsolute(p) {        return (p.startsWith('/') || p.startsWith('\\') || /^[a-z]:(\/|\\)/i.test(p));    }}exports.PathScurryWin32 = PathScurryWin32;/** * {@link PathScurryBase} implementation for all posix systems other than Darwin. * * Defaults to case-sensitive matching, uses `'/'` to generate path strings. * * Uses {@link PathPosix} for Path objects. */class PathScurryPosix extends PathScurryBase {    /**     * separator for generating path strings     */    sep = '/';    constructor(cwd = process.cwd(), opts = {}) {        const { nocase = false } = opts;        super(cwd, node_path_1.posix, '/', { ...opts, nocase });        this.nocase = nocase;    }    /**     * @internal     */    parseRootPath(_dir) {        return '/';    }    /**     * @internal     */    newRoot(fs) {        return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs });    }    /**     * Return true if the provided path string is an absolute path     */    isAbsolute(p) {        return p.startsWith('/');    }}exports.PathScurryPosix = PathScurryPosix;/** * {@link PathScurryBase} implementation for Darwin (macOS) systems. * * Defaults to case-insensitive matching, uses `'/'` for generating path * strings. * * Uses {@link PathPosix} for Path objects. */class PathScurryDarwin extends PathScurryPosix {    constructor(cwd = process.cwd(), opts = {}) {        const { nocase = true } = opts;        super(cwd, { ...opts, nocase });    }}exports.PathScurryDarwin = PathScurryDarwin;/** * Default {@link PathBase} implementation for the current platform. * * {@link PathWin32} on Windows systems, {@link PathPosix} on all others. */exports.Path = process.platform === 'win32' ? PathWin32 : PathPosix;/** * Default {@link PathScurryBase} implementation for the current platform. * * {@link PathScurryWin32} on Windows systems, {@link PathScurryDarwin} on * Darwin (macOS) systems, {@link PathScurryPosix} on all others. */exports.PathScurry = process.platform === 'win32' ? PathScurryWin32    : process.platform === 'darwin' ? PathScurryDarwin        : PathScurryPosix;//# sourceMappingURL=index.js.map