All files / src/lib/helpers fsCopy.ts

90.69% Statements 39/43
81.48% Branches 22/27
83.33% Functions 5/6
90.69% Lines 39/43

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 8516x 16x                 16x         209x 209x 11x   198x 198x 16x 16x 16x 16x             16x 16x     182x 182x 182x 182x       182x 182x   182x       16x         63x 63x     63x 63x 63x 234x 234x 46x   188x         16x   38x 38x   38x 38x 17x   21x       16x  
import fs from "fs-extra";
import Path from "path";
 
interface CopyOptions {
  overwrite?: boolean;
  errorOnExist?: boolean;
  mode?: number | undefined;
  ignore?: (path: string) => boolean;
}
 
const copyFile = async (
  src: string,
  dest: string,
  options: CopyOptions = {},
) => {
  const { overwrite = true, errorOnExist = false, mode, ignore } = options;
  if (ignore?.(src)) {
    return;
  }
  let throwAlreadyExists = false;
  if (!overwrite) {
    try {
      await fs.lstat(dest);
      if (errorOnExist) {
        throwAlreadyExists = true;
      } else E{
        return;
      }
    } catch {
      // Didn't exist so copy it
    }
    Eif (throwAlreadyExists) {
      throw new Error(`File already exists ${dest}`);
    }
  }
  await new Promise<void>((resolve, reject) => {
    const inputStream = fs.createReadStream(src);
    const outputStream = fs.createWriteStream(dest, { mode });
    inputStream.once("error", (err) => {
      outputStream.close();
      reject(new Error(`Could not write file ${dest}: ${err}`));
    });
    inputStream.once("end", () => {
      resolve();
    });
    inputStream.pipe(outputStream);
  });
};
 
const copyDir = async (
  src: string,
  dest: string,
  options: CopyOptions = {},
) => {
  const { ignore } = options;
  Iif (ignore?.(src)) {
    return;
  }
  const filePaths = await fs.readdir(src);
  await fs.ensureDir(dest);
  for (const fileName of filePaths) {
    const fileStat = await fs.lstat(`${src}/${fileName}`);
    if (fileStat.isDirectory()) {
      await copyDir(`${src}/${fileName}`, `${dest}/${fileName}`, options);
    } else {
      await copyFile(`${src}/${fileName}`, `${dest}/${fileName}`, options);
    }
  }
};
 
const copy = async (src: string, dest: string, options: CopyOptions = {}) => {
  // Ensure parent folder exists first
  const parentDir = Path.dirname(dest);
  await fs.ensureDir(parentDir);
 
  const fileStat = await fs.lstat(src);
  if (fileStat.isDirectory()) {
    await copyDir(src, dest, options);
  } else {
    await copyFile(src, dest, options);
  }
};
 
export default copy;