All files / src path.ts

100% Statements 33/33
100% Branches 26/26
100% Functions 6/6
100% Lines 33/33

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  1x 33887x 33887x 56554x 56554x 6x 4x 4x 4x 53372x 53372x 33885x 33885x   1x 180x 180x   1x 599x 599x 599x   1x 656x 656x 656x     1x 74x 74x 68x 68x   1x 264430x 262551x 264430x  
/** Normalise to POSIX, drop leading/trailing slashes and `.` segments. */
export function normalizePath(path: string): string {
  const parts: string[] = [];
  for (const segment of path.replace(/\\/g, '/').split('/')) {
    if (!segment || segment === '.') continue;
    if (segment === '..') {
      if (parts.length === 0) throw new Error(`path escapes the root: ${path}`);
      parts.pop();
      continue;
    }
    parts.push(segment);
  }
  return parts.join('/');
}
 
export function joinPath(...parts: string[]): string {
  return normalizePath(parts.join('/'));
}
 
export function dirname(path: string): string {
  const i = path.lastIndexOf('/');
  return i === -1 ? '' : path.slice(0, i);
}
 
export function basename(path: string): string {
  const i = path.lastIndexOf('/');
  return i === -1 ? path : path.slice(i + 1);
}
 
/** `['name', '.ext']` — a leading dot is part of the name, not an extension. */
export function splitExtension(name: string): [string, string] {
  const i = name.lastIndexOf('.');
  if (i <= 0) return [name, ''];
  return [name.slice(0, i), name.slice(i)];
}
 
export function isInside(path: string, dir: string): boolean {
  if (!dir) return true;
  return path === dir || path.startsWith(`${dir}/`);
}