123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- "use strict";
- var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.GlobStream = exports.GlobWalker = exports.GlobUtil = void 0;
- /**
- * Single-use utility classes to provide functionality to the {@link Glob}
- * methods.
- *
- * @module
- */
- const minipass_1 = __importDefault(require("minipass"));
- const ignore_js_1 = require("./ignore.js");
- const processor_js_1 = require("./processor.js");
- const makeIgnore = (ignore, opts) => typeof ignore === 'string'
- ? new ignore_js_1.Ignore([ignore], opts)
- : Array.isArray(ignore)
- ? new ignore_js_1.Ignore(ignore, opts)
- : /* c8 ignore start */
- ignore;
- /* c8 ignore stop */
- /**
- * basic walking utilities that all the glob walker types use
- */
- class GlobUtil {
- path;
- patterns;
- opts;
- seen = new Set();
- paused = false;
- aborted = false;
- #onResume = [];
- #ignore;
- #sep;
- signal;
- constructor(patterns, path, opts) {
- this.patterns = patterns;
- this.path = path;
- this.opts = opts;
- this.#sep = opts.platform === 'win32' ? '\\' : '/';
- if (opts.ignore) {
- this.#ignore = makeIgnore(opts.ignore, opts);
- }
- if (opts.signal) {
- this.signal = opts.signal;
- this.signal.addEventListener('abort', () => {
- this.#onResume.length = 0;
- });
- }
- }
- #ignored(path) {
- return this.seen.has(path) || !!this.#ignore?.ignored(path);
- }
- #childrenIgnored(path) {
- return !!this.#ignore?.childrenIgnored(path);
- }
- // backpressure mechanism
- pause() {
- this.paused = true;
- }
- resume() {
- /* c8 ignore start */
- if (this.signal?.aborted)
- return;
- /* c8 ignore stop */
- this.paused = false;
- let fn = undefined;
- while (!this.paused && (fn = this.#onResume.shift())) {
- fn();
- }
- }
- onResume(fn) {
- if (this.signal?.aborted)
- return;
- /* c8 ignore start */
- if (!this.paused) {
- fn();
- }
- else {
- /* c8 ignore stop */
- this.#onResume.push(fn);
- }
- }
- // do the requisite realpath/stat checking, and return the path
- // to add or undefined to filter it out.
- async matchCheck(e, ifDir) {
- if (ifDir && this.opts.nodir)
- return undefined;
- let rpc;
- if (this.opts.realpath) {
- rpc = e.realpathCached() || (await e.realpath());
- if (!rpc)
- return undefined;
- e = rpc;
- }
- const needStat = e.isUnknown();
- return this.matchCheckTest(needStat ? await e.lstat() : e, ifDir);
- }
- matchCheckTest(e, ifDir) {
- return e &&
- !this.#ignored(e) &&
- (!ifDir || e.canReaddir()) &&
- (!this.opts.nodir || !e.isDirectory())
- ? e
- : undefined;
- }
- matchCheckSync(e, ifDir) {
- if (ifDir && this.opts.nodir)
- return undefined;
- let rpc;
- if (this.opts.realpath) {
- rpc = e.realpathCached() || e.realpathSync();
- if (!rpc)
- return undefined;
- e = rpc;
- }
- const needStat = e.isUnknown();
- return this.matchCheckTest(needStat ? e.lstatSync() : e, ifDir);
- }
- matchFinish(e, absolute) {
- if (this.#ignored(e))
- return;
- this.seen.add(e);
- const mark = this.opts.mark && e.isDirectory() ? this.#sep : '';
- // ok, we have what we need!
- if (this.opts.withFileTypes) {
- this.matchEmit(e);
- }
- else if (this.opts.absolute || absolute) {
- this.matchEmit(e.fullpath() + mark);
- }
- else {
- const rel = e.relative();
- this.matchEmit(!rel && mark ? './' : rel + mark);
- }
- }
- async match(e, absolute, ifDir) {
- const p = await this.matchCheck(e, ifDir);
- if (p)
- this.matchFinish(p, absolute);
- }
- matchSync(e, absolute, ifDir) {
- const p = this.matchCheckSync(e, ifDir);
- if (p)
- this.matchFinish(p, absolute);
- }
- walkCB(target, patterns, cb) {
- /* c8 ignore start */
- if (this.signal?.aborted)
- cb();
- /* c8 ignore stop */
- this.walkCB2(target, patterns, new processor_js_1.Processor(this.opts), cb);
- }
- walkCB2(target, patterns, processor, cb) {
- if (this.#childrenIgnored(target))
- return cb();
- if (this.signal?.aborted)
- cb();
- if (this.paused) {
- this.onResume(() => this.walkCB2(target, patterns, processor, cb));
- return;
- }
- processor.processPatterns(target, patterns);
- // done processing. all of the above is sync, can be abstracted out.
- // subwalks is a map of paths to the entry filters they need
- // matches is a map of paths to [absolute, ifDir] tuples.
- let tasks = 1;
- const next = () => {
- if (--tasks === 0)
- cb();
- };
- for (const [m, absolute, ifDir] of processor.matches.entries()) {
- if (this.#ignored(m))
- continue;
- tasks++;
- this.match(m, absolute, ifDir).then(() => next());
- }
- for (const t of processor.subwalkTargets()) {
- tasks++;
- const childrenCached = t.readdirCached();
- if (t.calledReaddir())
- this.walkCB3(t, childrenCached, processor, next);
- else {
- t.readdirCB((_, entries) => this.walkCB3(t, entries, processor, next), true);
- }
- }
- next();
- }
- walkCB3(target, entries, processor, cb) {
- processor = processor.filterEntries(target, entries);
- let tasks = 1;
- const next = () => {
- if (--tasks === 0)
- cb();
- };
- for (const [m, absolute, ifDir] of processor.matches.entries()) {
- if (this.#ignored(m))
- continue;
- tasks++;
- this.match(m, absolute, ifDir).then(() => next());
- }
- for (const [target, patterns] of processor.subwalks.entries()) {
- tasks++;
- this.walkCB2(target, patterns, processor.child(), next);
- }
- next();
- }
- walkCBSync(target, patterns, cb) {
- /* c8 ignore start */
- if (this.signal?.aborted)
- cb();
- /* c8 ignore stop */
- this.walkCB2Sync(target, patterns, new processor_js_1.Processor(this.opts), cb);
- }
- walkCB2Sync(target, patterns, processor, cb) {
- if (this.#childrenIgnored(target))
- return cb();
- if (this.signal?.aborted)
- cb();
- if (this.paused) {
- this.onResume(() => this.walkCB2Sync(target, patterns, processor, cb));
- return;
- }
- processor.processPatterns(target, patterns);
- // done processing. all of the above is sync, can be abstracted out.
- // subwalks is a map of paths to the entry filters they need
- // matches is a map of paths to [absolute, ifDir] tuples.
- let tasks = 1;
- const next = () => {
- if (--tasks === 0)
- cb();
- };
- for (const [m, absolute, ifDir] of processor.matches.entries()) {
- if (this.#ignored(m))
- continue;
- this.matchSync(m, absolute, ifDir);
- }
- for (const t of processor.subwalkTargets()) {
- tasks++;
- const children = t.readdirSync();
- this.walkCB3Sync(t, children, processor, next);
- }
- next();
- }
- walkCB3Sync(target, entries, processor, cb) {
- processor = processor.filterEntries(target, entries);
- let tasks = 1;
- const next = () => {
- if (--tasks === 0)
- cb();
- };
- for (const [m, absolute, ifDir] of processor.matches.entries()) {
- if (this.#ignored(m))
- continue;
- this.matchSync(m, absolute, ifDir);
- }
- for (const [target, patterns] of processor.subwalks.entries()) {
- tasks++;
- this.walkCB2Sync(target, patterns, processor.child(), next);
- }
- next();
- }
- }
- exports.GlobUtil = GlobUtil;
- class GlobWalker extends GlobUtil {
- matches;
- constructor(patterns, path, opts) {
- super(patterns, path, opts);
- this.matches = new Set();
- }
- matchEmit(e) {
- this.matches.add(e);
- }
- async walk() {
- if (this.signal?.aborted)
- throw this.signal.reason;
- const t = this.path.isUnknown() ? await this.path.lstat() : this.path;
- if (t) {
- await new Promise((res, rej) => {
- this.walkCB(t, this.patterns, () => {
- if (this.signal?.aborted) {
- rej(this.signal.reason);
- }
- else {
- res(this.matches);
- }
- });
- });
- }
- return this.matches;
- }
- walkSync() {
- if (this.signal?.aborted)
- throw this.signal.reason;
- const t = this.path.isUnknown() ? this.path.lstatSync() : this.path;
- // nothing for the callback to do, because this never pauses
- if (t) {
- this.walkCBSync(t, this.patterns, () => {
- if (this.signal?.aborted)
- throw this.signal.reason;
- });
- }
- return this.matches;
- }
- }
- exports.GlobWalker = GlobWalker;
- class GlobStream extends GlobUtil {
- results;
- constructor(patterns, path, opts) {
- super(patterns, path, opts);
- this.results = new minipass_1.default({
- signal: this.signal,
- objectMode: true,
- });
- this.results.on('drain', () => this.resume());
- this.results.on('resume', () => this.resume());
- }
- matchEmit(e) {
- this.results.write(e);
- if (!this.results.flowing)
- this.pause();
- }
- stream() {
- const target = this.path;
- if (target.isUnknown()) {
- target.lstat().then(e => {
- if (e) {
- this.walkCB(target, this.patterns, () => this.results.end());
- }
- else {
- this.results.end();
- }
- });
- }
- else {
- this.walkCB(target, this.patterns, () => this.results.end());
- }
- return this.results;
- }
- streamSync() {
- const target = this.path.isUnknown()
- ? this.path.lstatSync()
- : this.path;
- if (target) {
- this.walkCBSync(target, this.patterns, () => this.results.end());
- }
- else {
- this.results.end();
- }
- return this.results;
- }
- }
- exports.GlobStream = GlobStream;
- //# sourceMappingURL=walker.js.map
|