mirror of
				https://scm.univ-tours.fr/22107988t/rappaurio-sae501_502.git
				synced 2025-11-04 12:05:21 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			215 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			215 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// this is just a very light wrapper around 2 arrays with an offset index
 | 
						|
import { GLOBSTAR } from 'minimatch';
 | 
						|
const isPatternList = (pl) => pl.length >= 1;
 | 
						|
const isGlobList = (gl) => gl.length >= 1;
 | 
						|
/**
 | 
						|
 * An immutable-ish view on an array of glob parts and their parsed
 | 
						|
 * results
 | 
						|
 */
 | 
						|
export class Pattern {
 | 
						|
    #patternList;
 | 
						|
    #globList;
 | 
						|
    #index;
 | 
						|
    length;
 | 
						|
    #platform;
 | 
						|
    #rest;
 | 
						|
    #globString;
 | 
						|
    #isDrive;
 | 
						|
    #isUNC;
 | 
						|
    #isAbsolute;
 | 
						|
    #followGlobstar = true;
 | 
						|
    constructor(patternList, globList, index, platform) {
 | 
						|
        if (!isPatternList(patternList)) {
 | 
						|
            throw new TypeError('empty pattern list');
 | 
						|
        }
 | 
						|
        if (!isGlobList(globList)) {
 | 
						|
            throw new TypeError('empty glob list');
 | 
						|
        }
 | 
						|
        if (globList.length !== patternList.length) {
 | 
						|
            throw new TypeError('mismatched pattern list and glob list lengths');
 | 
						|
        }
 | 
						|
        this.length = patternList.length;
 | 
						|
        if (index < 0 || index >= this.length) {
 | 
						|
            throw new TypeError('index out of range');
 | 
						|
        }
 | 
						|
        this.#patternList = patternList;
 | 
						|
        this.#globList = globList;
 | 
						|
        this.#index = index;
 | 
						|
        this.#platform = platform;
 | 
						|
        // normalize root entries of absolute patterns on initial creation.
 | 
						|
        if (this.#index === 0) {
 | 
						|
            // c: => ['c:/']
 | 
						|
            // C:/ => ['C:/']
 | 
						|
            // C:/x => ['C:/', 'x']
 | 
						|
            // //host/share => ['//host/share/']
 | 
						|
            // //host/share/ => ['//host/share/']
 | 
						|
            // //host/share/x => ['//host/share/', 'x']
 | 
						|
            // /etc => ['/', 'etc']
 | 
						|
            // / => ['/']
 | 
						|
            if (this.isUNC()) {
 | 
						|
                // '' / '' / 'host' / 'share'
 | 
						|
                const [p0, p1, p2, p3, ...prest] = this.#patternList;
 | 
						|
                const [g0, g1, g2, g3, ...grest] = this.#globList;
 | 
						|
                if (prest[0] === '') {
 | 
						|
                    // ends in /
 | 
						|
                    prest.shift();
 | 
						|
                    grest.shift();
 | 
						|
                }
 | 
						|
                const p = [p0, p1, p2, p3, ''].join('/');
 | 
						|
                const g = [g0, g1, g2, g3, ''].join('/');
 | 
						|
                this.#patternList = [p, ...prest];
 | 
						|
                this.#globList = [g, ...grest];
 | 
						|
                this.length = this.#patternList.length;
 | 
						|
            }
 | 
						|
            else if (this.isDrive() || this.isAbsolute()) {
 | 
						|
                const [p1, ...prest] = this.#patternList;
 | 
						|
                const [g1, ...grest] = this.#globList;
 | 
						|
                if (prest[0] === '') {
 | 
						|
                    // ends in /
 | 
						|
                    prest.shift();
 | 
						|
                    grest.shift();
 | 
						|
                }
 | 
						|
                const p = p1 + '/';
 | 
						|
                const g = g1 + '/';
 | 
						|
                this.#patternList = [p, ...prest];
 | 
						|
                this.#globList = [g, ...grest];
 | 
						|
                this.length = this.#patternList.length;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * The first entry in the parsed list of patterns
 | 
						|
     */
 | 
						|
    pattern() {
 | 
						|
        return this.#patternList[this.#index];
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * true of if pattern() returns a string
 | 
						|
     */
 | 
						|
    isString() {
 | 
						|
        return typeof this.#patternList[this.#index] === 'string';
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * true of if pattern() returns GLOBSTAR
 | 
						|
     */
 | 
						|
    isGlobstar() {
 | 
						|
        return this.#patternList[this.#index] === GLOBSTAR;
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * true if pattern() returns a regexp
 | 
						|
     */
 | 
						|
    isRegExp() {
 | 
						|
        return this.#patternList[this.#index] instanceof RegExp;
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * The /-joined set of glob parts that make up this pattern
 | 
						|
     */
 | 
						|
    globString() {
 | 
						|
        return (this.#globString =
 | 
						|
            this.#globString ||
 | 
						|
                (this.#index === 0
 | 
						|
                    ? this.isAbsolute()
 | 
						|
                        ? this.#globList[0] + this.#globList.slice(1).join('/')
 | 
						|
                        : this.#globList.join('/')
 | 
						|
                    : this.#globList.slice(this.#index).join('/')));
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * true if there are more pattern parts after this one
 | 
						|
     */
 | 
						|
    hasMore() {
 | 
						|
        return this.length > this.#index + 1;
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * The rest of the pattern after this part, or null if this is the end
 | 
						|
     */
 | 
						|
    rest() {
 | 
						|
        if (this.#rest !== undefined)
 | 
						|
            return this.#rest;
 | 
						|
        if (!this.hasMore())
 | 
						|
            return (this.#rest = null);
 | 
						|
        this.#rest = new Pattern(this.#patternList, this.#globList, this.#index + 1, this.#platform);
 | 
						|
        this.#rest.#isAbsolute = this.#isAbsolute;
 | 
						|
        this.#rest.#isUNC = this.#isUNC;
 | 
						|
        this.#rest.#isDrive = this.#isDrive;
 | 
						|
        return this.#rest;
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * true if the pattern represents a //unc/path/ on windows
 | 
						|
     */
 | 
						|
    isUNC() {
 | 
						|
        const pl = this.#patternList;
 | 
						|
        return this.#isUNC !== undefined
 | 
						|
            ? this.#isUNC
 | 
						|
            : (this.#isUNC =
 | 
						|
                this.#platform === 'win32' &&
 | 
						|
                    this.#index === 0 &&
 | 
						|
                    pl[0] === '' &&
 | 
						|
                    pl[1] === '' &&
 | 
						|
                    typeof pl[2] === 'string' &&
 | 
						|
                    !!pl[2] &&
 | 
						|
                    typeof pl[3] === 'string' &&
 | 
						|
                    !!pl[3]);
 | 
						|
    }
 | 
						|
    // pattern like C:/...
 | 
						|
    // split = ['C:', ...]
 | 
						|
    // XXX: would be nice to handle patterns like `c:*` to test the cwd
 | 
						|
    // in c: for *, but I don't know of a way to even figure out what that
 | 
						|
    // cwd is without actually chdir'ing into it?
 | 
						|
    /**
 | 
						|
     * True if the pattern starts with a drive letter on Windows
 | 
						|
     */
 | 
						|
    isDrive() {
 | 
						|
        const pl = this.#patternList;
 | 
						|
        return this.#isDrive !== undefined
 | 
						|
            ? this.#isDrive
 | 
						|
            : (this.#isDrive =
 | 
						|
                this.#platform === 'win32' &&
 | 
						|
                    this.#index === 0 &&
 | 
						|
                    this.length > 1 &&
 | 
						|
                    typeof pl[0] === 'string' &&
 | 
						|
                    /^[a-z]:$/i.test(pl[0]));
 | 
						|
    }
 | 
						|
    // pattern = '/' or '/...' or '/x/...'
 | 
						|
    // split = ['', ''] or ['', ...] or ['', 'x', ...]
 | 
						|
    // Drive and UNC both considered absolute on windows
 | 
						|
    /**
 | 
						|
     * True if the pattern is rooted on an absolute path
 | 
						|
     */
 | 
						|
    isAbsolute() {
 | 
						|
        const pl = this.#patternList;
 | 
						|
        return this.#isAbsolute !== undefined
 | 
						|
            ? this.#isAbsolute
 | 
						|
            : (this.#isAbsolute =
 | 
						|
                (pl[0] === '' && pl.length > 1) ||
 | 
						|
                    this.isDrive() ||
 | 
						|
                    this.isUNC());
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * consume the root of the pattern, and return it
 | 
						|
     */
 | 
						|
    root() {
 | 
						|
        const p = this.#patternList[0];
 | 
						|
        return typeof p === 'string' && this.isAbsolute() && this.#index === 0
 | 
						|
            ? p
 | 
						|
            : '';
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * Check to see if the current globstar pattern is allowed to follow
 | 
						|
     * a symbolic link.
 | 
						|
     */
 | 
						|
    checkFollowGlobstar() {
 | 
						|
        return !(this.#index === 0 ||
 | 
						|
            !this.isGlobstar() ||
 | 
						|
            !this.#followGlobstar);
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * Mark that the current globstar pattern is following a symbolic link
 | 
						|
     */
 | 
						|
    markFollowGlobstar() {
 | 
						|
        if (this.#index === 0 || !this.isGlobstar() || !this.#followGlobstar)
 | 
						|
            return false;
 | 
						|
        this.#followGlobstar = false;
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
}
 | 
						|
//# sourceMappingURL=pattern.js.map
 |