All files path.ts

100% Statements 74/74
100% Branches 40/40
100% Functions 17/17
100% Lines 55/55

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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 941x 1x   1x 1x 1x 1x     1x   137x                         219x 219x 115x 115x 105x 103x   2x   115x   1x 139x 106x 106x   1x 6x 5x 5x   1x 8x 4x 4x   1x 10x   1x 35x 32x 32x   1x 21x 18x 18x   13x 13x 13x 10x   10x 5x           5x     10x 10x     8x 8x 8x     1x 5x 5x 5x   1x  
import * as fs from 'fs-extra';
import * as nodePath from 'path';
 
export enum PathType {
  file = 'file',
  directory = 'directory',
  missing = 'missing',
}
 
export class Path {
  constructor(
    public props?: {
      basename?: string;
      cwd?: string;
      path?: string;
    }
  ) {}
  cacheBasename?: string;
  cachePath?: string;
  cacheCwd?: string;
  cacheDirname?: string;
  cacheExtname?: string;
  cacheType?: PathType;
  cacheCoreBasename?: string;
  get path() {
    if (this.cachePath) return this.cachePath;
    this.cachePath = (() => {
      if (this.props?.path) return this.props.path;
      if (this.props?.basename) {
        return nodePath.join(this.cwd, this.props.basename);
      }
      return this.cwd;
    })();
    return this.cachePath;
  }
  get cwd(): string {
    if (this.cacheCwd) return this.cacheCwd;
    this.cacheCwd = this.props?.cwd ?? process.cwd();
    return this.cacheCwd;
  }
  get basename(): string {
    if (this.cacheBasename) return this.cacheBasename;
    this.cacheBasename = nodePath.basename(this.path);
    return this.cacheBasename;
  }
  get coreBasename(): string {
    if (this.cacheCoreBasename) return this.cacheCoreBasename;
    this.cacheCoreBasename = nodePath.basename(this.path, this.extname);
    return this.cacheCoreBasename;
  }
  get relativePath() {
    return this.path.replace(new RegExp('^' + this.cwd), '.');
  }
  get dirname(): string {
    if (this.cacheDirname) return this.cacheDirname;
    this.cacheDirname = nodePath.dirname(this.path);
    return this.cacheDirname;
  }
  get extname(): string {
    if (this.cacheExtname) return this.cacheExtname;
    this.cacheExtname = nodePath.extname(this.path);
    return this.cacheExtname;
  }
  get type(): Promise<PathType> {
    return (async () => {
      if (this.cacheType) return this.cacheType;
      const type = await (async () => {
        try {
          const stat = await fs.stat(this.path);
          if (stat.isDirectory()) return PathType.directory;
          /* istanbul ignore next */
          if (stat.isFile()) return PathType.file;
          /* istanbul ignore next */
          throw new Error('File type not recognized.');
        } catch (e) {
          return PathType.missing;
        }
      })();
      this.cacheType = type;
      return type;
    })();
  }
  get exists(): Promise<boolean> {
    return (async () => {
      return (await this.type) !== PathType.missing;
    })();
  }
  replaceExt(ext: string) {
    const currentExt = this.extname;
    this.cachePath = this.path.replace(new RegExp(currentExt + '$'), ext);
    return this;
  }
}