File Explorer

/var/lang/lib/node_modules/npm/node_modules/glob/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 /.

0 dirs
9 files
processor.js10.5 KB · 301 lines
"use strict";// synchronous utility for filtering entries and calculating subwalksObject.defineProperty(exports, "__esModule", { value: true });exports.Processor = exports.SubWalks = exports.MatchRecord = exports.HasWalkedCache = void 0;const minimatch_1 = require("minimatch");/** * A cache of which patterns have been processed for a given Path */class HasWalkedCache {    store;    constructor(store = new Map()) {        this.store = store;    }    copy() {        return new HasWalkedCache(new Map(this.store));    }    hasWalked(target, pattern) {        return this.store.get(target.fullpath())?.has(pattern.globString());    }    storeWalked(target, pattern) {        const fullpath = target.fullpath();        const cached = this.store.get(fullpath);        if (cached)            cached.add(pattern.globString());        else            this.store.set(fullpath, new Set([pattern.globString()]));    }}exports.HasWalkedCache = HasWalkedCache;/** * A record of which paths have been matched in a given walk step, * and whether they only are considered a match if they are a directory, * and whether their absolute or relative path should be returned. */class MatchRecord {    store = new Map();    add(target, absolute, ifDir) {        const n = (absolute ? 2 : 0) | (ifDir ? 1 : 0);        const current = this.store.get(target);        this.store.set(target, current === undefined ? n : n & current);    }    // match, absolute, ifdir    entries() {        return [...this.store.entries()].map(([path, n]) => [            path,            !!(n & 2),            !!(n & 1),        ]);    }}exports.MatchRecord = MatchRecord;/** * A collection of patterns that must be processed in a subsequent step * for a given path. */class SubWalks {    store = new Map();    add(target, pattern) {        if (!target.canReaddir()) {            return;        }        const subs = this.store.get(target);        if (subs) {            if (!subs.find(p => p.globString() === pattern.globString())) {                subs.push(pattern);            }        }        else            this.store.set(target, [pattern]);    }    get(target) {        const subs = this.store.get(target);        /* c8 ignore start */        if (!subs) {            throw new Error('attempting to walk unknown path');        }        /* c8 ignore stop */        return subs;    }    entries() {        return this.keys().map(k => [k, this.store.get(k)]);    }    keys() {        return [...this.store.keys()].filter(t => t.canReaddir());    }}exports.SubWalks = SubWalks;/** * The class that processes patterns for a given path. * * Handles child entry filtering, and determining whether a path's * directory contents must be read. */class Processor {    hasWalkedCache;    matches = new MatchRecord();    subwalks = new SubWalks();    patterns;    follow;    dot;    opts;    constructor(opts, hasWalkedCache) {        this.opts = opts;        this.follow = !!opts.follow;        this.dot = !!opts.dot;        this.hasWalkedCache =            hasWalkedCache ? hasWalkedCache.copy() : new HasWalkedCache();    }    processPatterns(target, patterns) {        this.patterns = patterns;        const processingSet = patterns.map(p => [target, p]);        // map of paths to the magic-starting subwalks they need to walk        // first item in patterns is the filter        for (let [t, pattern] of processingSet) {            this.hasWalkedCache.storeWalked(t, pattern);            const root = pattern.root();            const absolute = pattern.isAbsolute() && this.opts.absolute !== false;            // start absolute patterns at root            if (root) {                t = t.resolve(root === '/' && this.opts.root !== undefined ?                    this.opts.root                    : root);                const rest = pattern.rest();                if (!rest) {                    this.matches.add(t, true, false);                    continue;                }                else {                    pattern = rest;                }            }            if (t.isENOENT())                continue;            let p;            let rest;            let changed = false;            while (typeof (p = pattern.pattern()) === 'string' &&                (rest = pattern.rest())) {                const c = t.resolve(p);                t = c;                pattern = rest;                changed = true;            }            p = pattern.pattern();            rest = pattern.rest();            if (changed) {                if (this.hasWalkedCache.hasWalked(t, pattern))                    continue;                this.hasWalkedCache.storeWalked(t, pattern);            }            // now we have either a final string for a known entry,            // more strings for an unknown entry,            // or a pattern starting with magic, mounted on t.            if (typeof p === 'string') {                // must not be final entry, otherwise we would have                // concatenated it earlier.                const ifDir = p === '..' || p === '' || p === '.';                this.matches.add(t.resolve(p), absolute, ifDir);                continue;            }            else if (p === minimatch_1.GLOBSTAR) {                // if no rest, match and subwalk pattern                // if rest, process rest and subwalk pattern                // if it's a symlink, but we didn't get here by way of a                // globstar match (meaning it's the first time THIS globstar                // has traversed a symlink), then we follow it. Otherwise, stop.                if (!t.isSymbolicLink() ||                    this.follow ||                    pattern.checkFollowGlobstar()) {                    this.subwalks.add(t, pattern);                }                const rp = rest?.pattern();                const rrest = rest?.rest();                if (!rest || ((rp === '' || rp === '.') && !rrest)) {                    // only HAS to be a dir if it ends in **/ or **/.                    // but ending in ** will match files as well.                    this.matches.add(t, absolute, rp === '' || rp === '.');                }                else {                    if (rp === '..') {                        // this would mean you're matching **/.. at the fs root,                        // and no thanks, I'm not gonna test that specific case.                        /* c8 ignore start */                        const tp = t.parent || t;                        /* c8 ignore stop */                        if (!rrest)                            this.matches.add(tp, absolute, true);                        else if (!this.hasWalkedCache.hasWalked(tp, rrest)) {                            this.subwalks.add(tp, rrest);                        }                    }                }            }            else if (p instanceof RegExp) {                this.subwalks.add(t, pattern);            }        }        return this;    }    subwalkTargets() {        return this.subwalks.keys();    }    child() {        return new Processor(this.opts, this.hasWalkedCache);    }    // return a new Processor containing the subwalks for each    // child entry, and a set of matches, and    // a hasWalkedCache that's a copy of this one    // then we're going to call    filterEntries(parent, entries) {        const patterns = this.subwalks.get(parent);        // put matches and entry walks into the results processor        const results = this.child();        for (const e of entries) {            for (const pattern of patterns) {                const absolute = pattern.isAbsolute();                const p = pattern.pattern();                const rest = pattern.rest();                if (p === minimatch_1.GLOBSTAR) {                    results.testGlobstar(e, pattern, rest, absolute);                }                else if (p instanceof RegExp) {                    results.testRegExp(e, p, rest, absolute);                }                else {                    results.testString(e, p, rest, absolute);                }            }        }        return results;    }    testGlobstar(e, pattern, rest, absolute) {        if (this.dot || !e.name.startsWith('.')) {            if (!pattern.hasMore()) {                this.matches.add(e, absolute, false);            }            if (e.canReaddir()) {                // if we're in follow mode or it's not a symlink, just keep                // testing the same pattern. If there's more after the globstar,                // then this symlink consumes the globstar. If not, then we can                // follow at most ONE symlink along the way, so we mark it, which                // also checks to ensure that it wasn't already marked.                if (this.follow || !e.isSymbolicLink()) {                    this.subwalks.add(e, pattern);                }                else if (e.isSymbolicLink()) {                    if (rest && pattern.checkFollowGlobstar()) {                        this.subwalks.add(e, rest);                    }                    else if (pattern.markFollowGlobstar()) {                        this.subwalks.add(e, pattern);                    }                }            }        }        // if the NEXT thing matches this entry, then also add        // the rest.        if (rest) {            const rp = rest.pattern();            if (typeof rp === 'string' &&                // dots and empty were handled already                rp !== '..' &&                rp !== '' &&                rp !== '.') {                this.testString(e, rp, rest.rest(), absolute);            }            else if (rp === '..') {                /* c8 ignore start */                const ep = e.parent || e;                /* c8 ignore stop */                this.subwalks.add(ep, rest);            }            else if (rp instanceof RegExp) {                this.testRegExp(e, rp, rest.rest(), absolute);            }        }    }    testRegExp(e, p, rest, absolute) {        if (!p.test(e.name))            return;        if (!rest) {            this.matches.add(e, absolute, false);        }        else {            this.subwalks.add(e, rest);        }    }    testString(e, p, rest, absolute) {        // should never happen?        if (!e.isNamed(p))            return;        if (!rest) {            this.matches.add(e, absolute, false);        }        else {            this.subwalks.add(e, rest);        }    }}exports.Processor = Processor;//# sourceMappingURL=processor.js.map