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.
		
		
		
		
			
				
					160 lines
				
				3.5 KiB
			
		
		
			
		
	
	
					160 lines
				
				3.5 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 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;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 |