You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							159 lines
						
					
					
						
							3.5 KiB
						
					
					
				
			
		
		
	
	
							159 lines
						
					
					
						
							3.5 KiB
						
					
					
				/* | 
						|
 Copyright 2012-2015, Yahoo Inc. | 
						|
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. | 
						|
 */ | 
						|
'use strict'; | 
						|
 | 
						|
const path = require('path'); | 
						|
let parsePath = path.parse; | 
						|
let SEP = path.sep || /* istanbul ignore next */ '/'; | 
						|
const origParser = parsePath; | 
						|
const origSep = SEP; | 
						|
 | 
						|
function makeRelativeNormalizedPath(str, sep) { | 
						|
    const parsed = parsePath(str); | 
						|
    let root = parsed.root; | 
						|
    let dir; | 
						|
    let file = parsed.base; | 
						|
    let quoted; | 
						|
    let pos; | 
						|
 | 
						|
    // handle a weird windows case separately | 
						|
    if (sep === '\\') { | 
						|
        pos = root.indexOf(':\\'); | 
						|
        if (pos >= 0) { | 
						|
            root = root.substring(0, pos + 2); | 
						|
        } | 
						|
    } | 
						|
    dir = parsed.dir.substring(root.length); | 
						|
 | 
						|
    if (str === '') { | 
						|
        return []; | 
						|
    } | 
						|
 | 
						|
    if (sep !== '/') { | 
						|
        quoted = new RegExp(sep.replace(/\W/g, '\\$&'), 'g'); | 
						|
        dir = dir.replace(quoted, '/'); | 
						|
        file = file.replace(quoted, '/'); // excessively paranoid? | 
						|
    } | 
						|
 | 
						|
    if (dir !== '') { | 
						|
        dir = dir + '/' + file; | 
						|
    } else { | 
						|
        dir = file; | 
						|
    } | 
						|
    if (dir.substring(0, 1) === '/') { | 
						|
        dir = dir.substring(1); | 
						|
    } | 
						|
    dir = dir.split(/\/+/); | 
						|
    return dir; | 
						|
} | 
						|
 | 
						|
function Path(strOrArray) { | 
						|
    if (Array.isArray(strOrArray)) { | 
						|
        this.v = strOrArray; | 
						|
    } else if (typeof strOrArray === 'string') { | 
						|
        this.v = makeRelativeNormalizedPath(strOrArray, SEP); | 
						|
    } else { | 
						|
        throw new Error( | 
						|
            'Invalid Path argument must be string or array:' + strOrArray | 
						|
        ); | 
						|
    } | 
						|
} | 
						|
 | 
						|
Path.prototype.toString = function() { | 
						|
    return this.v.join('/'); | 
						|
}; | 
						|
 | 
						|
Path.prototype.hasParent = function() { | 
						|
    return this.v.length > 0; | 
						|
}; | 
						|
 | 
						|
Path.prototype.parent = function() { | 
						|
    if (!this.hasParent()) { | 
						|
        throw new Error('Unable to get parent for 0 elem path'); | 
						|
    } | 
						|
    const p = this.v.slice(); | 
						|
    p.pop(); | 
						|
    return new Path(p); | 
						|
}; | 
						|
 | 
						|
Path.prototype.elements = function() { | 
						|
    return this.v.slice(); | 
						|
}; | 
						|
 | 
						|
Path.prototype.contains = function(other) { | 
						|
    let i; | 
						|
    if (other.length > this.length) { | 
						|
        return false; | 
						|
    } | 
						|
    for (i = 0; i < other.length; i += 1) { | 
						|
        if (this.v[i] !== other.v[i]) { | 
						|
            return false; | 
						|
        } | 
						|
    } | 
						|
    return true; | 
						|
}; | 
						|
 | 
						|
Path.prototype.ancestorOf = function(other) { | 
						|
    return other.contains(this) && other.length !== this.length; | 
						|
}; | 
						|
 | 
						|
Path.prototype.descendantOf = function(other) { | 
						|
    return this.contains(other) && other.length !== this.length; | 
						|
}; | 
						|
 | 
						|
Path.prototype.commonPrefixPath = function(other) { | 
						|
    const len = this.length > other.length ? other.length : this.length; | 
						|
    let i; | 
						|
    const ret = []; | 
						|
 | 
						|
    for (i = 0; i < len; i += 1) { | 
						|
        if (this.v[i] === other.v[i]) { | 
						|
            ret.push(this.v[i]); | 
						|
        } else { | 
						|
            break; | 
						|
        } | 
						|
    } | 
						|
    return new Path(ret); | 
						|
}; | 
						|
 | 
						|
['push', 'pop', 'shift', 'unshift', 'splice'].forEach(f => { | 
						|
    Path.prototype[f] = function(...args) { | 
						|
        const v = this.v; | 
						|
        return v[f](...args); | 
						|
    }; | 
						|
}); | 
						|
 | 
						|
Path.compare = function(a, b) { | 
						|
    const al = a.length; | 
						|
    const bl = b.length; | 
						|
    if (al < bl) { | 
						|
        return -1; | 
						|
    } | 
						|
    if (al > bl) { | 
						|
        return 1; | 
						|
    } | 
						|
    const astr = a.toString(); | 
						|
    const bstr = b.toString(); | 
						|
    return astr < bstr ? -1 : astr > bstr ? 1 : 0; | 
						|
}; | 
						|
 | 
						|
Object.defineProperty(Path.prototype, 'length', { | 
						|
    enumerable: true, | 
						|
    get() { | 
						|
        return this.v.length; | 
						|
    } | 
						|
}); | 
						|
 | 
						|
module.exports = Path; | 
						|
Path.tester = { | 
						|
    setParserAndSep(p, sep) { | 
						|
        parsePath = p; | 
						|
        SEP = sep; | 
						|
    }, | 
						|
    reset() { | 
						|
        parsePath = origParser; | 
						|
        SEP = origSep; | 
						|
    } | 
						|
};
 | 
						|
 |