All files / transformer find-relative-path.ts

87.23% Statements 41/47
50% Branches 6/12
100% Functions 1/1
87.23% Lines 41/47

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 481x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x       16x 16x 16x 16x 16x 16x 16x 28x 28x 28x 16x 16x 16x 16x       16x 16x 8x 8x 8x 8x 16x 16x 16x 16x  
 
export function findRelativePathToFile(fromFile: string, toFile: string) {
    fromFile = fromFile.replace(/\\/g, '/');
    toFile = toFile.replace(/\\/g, '/');
 
    if (fromFile.startsWith('./'))
        fromFile = fromFile.slice(2);
    if (toFile.startsWith('./'))
        toFile = toFile.slice(2);
 
    let fromAbsolute = /^[A-Za-z]:/.test(fromFile) || /^\//.test(fromFile);
    let toAbsolute = /^[A-Za-z]:/.test(toFile) || /^\//.test(toFile);
 
    if (fromAbsolute !== toAbsolute)
        throw new Error(`Cannot determine relationship between an absolute and a relative path!`);
 
    if (!fromAbsolute && !toAbsolute) {
        fromFile = `/${fromFile}`;
        toFile = `/${toFile}`;
    }
 
    let from = fromFile.split('/');
    let to = toFile.split('/');
    let parents = 0;
    let toFileName = to.pop();
 
    while (from.length > 0 && !(to.join('/') + '/').startsWith(from.join('/') + '/')) {
        parents += 1;
        from.pop();
    }
 
    let result: string;
 
    if (from.length === 0) {
        // Could be different drive letters, ie C:/ vs D:/ -- in that case, we just have to
        // use the absolute path
        return undefined;
    } else {
        if (parents > 1) {
            result = [...Array(parents - 1).fill('..'), ...to.slice(from.length), toFileName].join('/');
        } else {
            result = ['.', ...to.slice(from.length), toFileName].join('/');
        }
    }
 
    return result;
}