All files / src/snapshot async.ts

94.59% Statements 35/37
82.35% Branches 14/17
100% Functions 2/2
96.87% Lines 31/32

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      3x 125x 125x 58x 58x 58x 58x 114x 114x   58x 67x 58x 58x 58x 9x 9x                   3x       45x 45x   21x 21x 21x 21x 42x 21x     21x 21x 21x     3x 3x 3x        
import { SnapshotNodeType } from './constants';
import type { AsyncSnapshotOptions, SnapshotNode } from './types';
 
export const toSnapshot = async ({ fs, path = '/', separator = '/' }: AsyncSnapshotOptions): Promise<SnapshotNode> => {
  const stats = await fs.lstat(path);
  if (stats.isDirectory()) {
    const list = await fs.readdir(path);
    const entries: { [child: string]: SnapshotNode } = {};
    const dir = path.endsWith(separator) ? path : path + separator;
    for (const child of list) {
      const childSnapshot = await toSnapshot({ fs, path: `${dir}${child}`, separator });
      if (childSnapshot) entries['' + child] = childSnapshot;
    }
    return [SnapshotNodeType.Folder, {}, entries];
  } else if (stats.isFile()) {
    const buf = (await fs.readFile(path)) as Buffer;
    const uint8 = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
    return [SnapshotNodeType.File, {}, uint8];
  } else if (stats.isSymbolicLink()) {
    return [
      SnapshotNodeType.Symlink,
      {
        target: (await fs.readlink(path, { encoding: 'utf8' })) as string,
      },
    ];
  }
  return null;
};
 
export const fromSnapshot = async (
  snapshot: SnapshotNode,
  { fs, path = '/', separator = '/' }: AsyncSnapshotOptions,
): Promise<void> => {
  Iif (!snapshot) return;
  switch (snapshot[0]) {
    case SnapshotNodeType.Folder: {
      if (!path.endsWith(separator)) path = path + separator;
      const [, , entries] = snapshot;
      await fs.mkdir(path, { recursive: true });
      for (const [name, child] of Object.entries(entries))
        await fromSnapshot(child, { fs, path: `${path}${name}`, separator });
      break;
    }
    case SnapshotNodeType.File: {
      const [, , data] = snapshot;
      await fs.writeFile(path, data);
      break;
    }
    case SnapshotNodeType.Symlink: {
      const [, { target }] = snapshot;
      await fs.symlink(target, path);
      break;
    }
  }
};