Skip to content

Latest commit

 

History

History
244 lines (165 loc) · 7.28 KB

README.md

File metadata and controls

244 lines (165 loc) · 7.28 KB

snapshot-fs

Create a snapshot of a directory for use with memfs

snapshot-fs logo

About

I wanted something to help convert directories of test fixtures on-disk to a format usable by an in-memory filesystem (memfs).

To that end, the snapshot-fs package ships a CLI, snapshot-fs, which converts a directory tree to a Compact JSON, CBOR or DirectoryJSON snapshot for use with memfs.

🎁 New in v5.0.0

  • The command-line options have changed; see Usage below.
  • The default input/output format is now CJSON.
  • CBOR snapshots are now supported.
  • The export subcommand got a --dry-run flag.

🎁 New in v2.0.0

  • The command-line options have changed; see Usage below.
  • snapshot-fs can now re-create a directory on the filesystem from a JSON snapshot.
  • loadSnapshot() is now readSnapshot()
  • Export functionality exposed via exportSnapshot()

Install

snapshot-fs requires Node.js v22.13.0 or newer.

snapshot-fs can be run via npx snapshot-fs or installed globally via npm install -g snapshot-fs. Or however else you want to consume it.

snapshot-fs exports both CommonJS and ES modules.

Usage

snapshot-fs [dest]

Create memfs snapshot from filesystem

Commands:
  snapshot-fs create [dest]             Create memfs snapshot from filesystem
                                                                       [default]
  snapshot-fs export <snapshot> [dest]  Export a JSON snapshot to the filesystem

Output:
      --separator, --sep  Path separator
                                  [choices: "posix", "win32"] [default: "posix"]
  -f, --format            Snapshot format
                  [string] [choices: "cbor", "cjson", "json"] [default: "cjson"]

Positionals:
  dest  Path to output file

Input:
  -s, --source  File or directory to snapshot
                                         [string] [default: (current directory)]

Options:
      --version  Show version number                                   [boolean]
      --help     Show help                                             [boolean]

For more information, visit https://github.com/boneskull/snapshot-fs

When run without a subcommand, create will be invoked.

create w/ Compact JSON Snapshots

By default (as of v5.0.0), snapshot-fs will create a snapshot in CJSON/Compact JSON format.

snapshot-fs --source /some/dir /path/to/output.json

This is equivalent to:

snapshot-fs create --source /some/dir /path/to/output.json --format=cjson

In your code, you can use the resulting file using memfs directly:

import { type JsonUint8Array, type SnapshotNode, fromJsonSnapshot } from 'memfs/lib/snapshot/index.js';
import { memfs } from 'memfs';

const data = (await readFile(
  '/path/to/output.json',
)) as unknown as JsonUint8Array<SnapshotNode>;

const {vol} = memfs()
await fromJsonSnapshot(data, fs: vol.promises);

console.log(vol.toTree());

// ... do your thing

...or you can use the readCJSONSnapshot() helper from snapshot-fs:

import type { JsonUint8Array, SnapshotNode } from 'memfs/lib/snapshot/index.js';
import { readCJSONSnapshot } from 'snapshot-fs';

const data = (await readFile(
  '/path/to/output.json',
)) as unknown as JsonUint8Array<SnapshotNode>;

const vol = await readCJSONSnapshot(data);

console.log(vol.toTree());

This is fast; JSON.parse() is never called!

(but we can get faster...)

create w/ CBOR Snapshots

Similar to the above, you can create a CBOR-formatted snapshot this way:

snapshot-fs --source /some/dir /path/to/output.json --format=cbor

In your code, you can use the resulting file using memfs directly:

import { type SnapshotNode, fromBinarySnapshot } from 'memfs/lib/snapshot/index.js';
import type { CborUint8Array } from '@jsonjoy.com/json-pack/lib/cbor/types.js';
import { memfs } from 'memfs';

const data = (await readFile(
  '/path/to/output.json',
)) as unknown as CborUint8Array<SnapshotNode>;

const {vol} = memfs()
await fromBinarySnapshot(data, fs: vol.promises);

console.log(vol.toTree());

// ... do your thing

...or you can use the readCBORSnapshot() helper from snapshot-fs:

import {
  type SnapshotNode,
  fromBinarySnapshot,
} from 'memfs/lib/snapshot/index.js';
import type { CborUint8Array } from '@jsonjoy.com/json-pack/lib/cbor/types.js';
import { readCBORSnapshot } from 'snapshot-fs';

const data = (await readFile(
  '/path/to/output.json',
)) as unknown as CborUint8Array<SnapshotNode>;

const vol = await readCBORSnapshot(data);

console.log(vol.toTree());

create w/ DirectoryJSON Snapshots

Caution

DirectoryJSON is somewhat lossy and should be avoided if you ever want to re-create snapshots on your real filesystem (e.g., using export). For a directory full of text files, this is fine; for anything else, use CJSON or CBOR.

snapshot-fs --source /some/dir /path/to/output.json --format=json

This can be read into a memfs Volume like so:

import { readFile } from 'node:fs/promises';
import { memfs } from 'memfs';

const directoryJson = JSON.parse(
  await readFile('/path/to/output.json', 'utf8'),
);

const { vol } = memfs();
vol.fromJSON(directoryJson);

export

This allows you to re-create a directory on the filesystem from a snapshot. Handy!

snapshot-fs export <snapshot> [dest]

Export a JSON snapshot to the filesystem

Positionals:
  snapshot  Path to snapshot file (CBOR/CJSON/DirectoryJSON)          [required]
  dest      Destination directory           [default: Current working directory]

Output:
      --separator, --sep  Path separator
                                  [choices: "posix", "win32"] [default: "posix"]

Options:
      --version  Show version number                                   [boolean]
      --help     Show help                                             [boolean]
  -D, --dry-run  Print what would be written to the filesystem         [boolean]
  -f, --format   Snapshot format
                  [string] [choices: "cbor", "cjson", "json"] [default: "cjson"]

If you have a snapshot (either format) and you want to re-create snapshot on the filesystem, use the export subcommand:

snapshot-fs export /path/to/snapshot.json /path/to/output

The destination directory will be created if it doesn't exist.

Tip

Use the --dry-run flag with export to see what would be written to the filesystem.

API

Some potentially-useful stuff exported from snapshot-fs:

  • createSnapshot()/createDirectoryJSONSnapshot()/createCJSONSnapshot()/createCBORSNapshot() - Create a JSON snapshot from a real or virtual FS
  • readSnapshot()/readDirectoryJSONSnapshot()/readCBORSnapshot()/readCJSONSnapshot() - Read a snapshot from a file and load it into a real or virtual FS
  • exportSnapshot() - Alias for readSnapshot() defaulting to the real FS

See the typings for more information.

License

Copyright 2024 Christopher Hiller. Licensed Apache-2.0