UNPKG

snapshot-fs

Version:

Create a filesystem snapshot for use with memfs

1 lines 10.5 kB
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\n/**\n * Writes a DirectoryJSON object or snapshot (with --binary flag) to file.\n *\n * For use with memfs.\n *\n * @module snapshot-fs/cli\n * @see {@link https://npm.im/memfs}\n */\n\nimport { bargs, opt, pos } from '@boneskull/bargs';\nimport { type JsonUint8Array } from 'memfs/lib/snapshot/json.js';\nimport { type SnapshotNode } from 'memfs/lib/snapshot/types.js';\nimport nodeFs, { readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport {\n CBOR_KIND,\n CJSON_KIND,\n createCBORSnapshot,\n createCJSONSnapshot,\n createJSONSnapshot,\n exportSnapshot,\n JSON_KIND,\n} from './index.js';\nimport { type CborUint8Array } from './types.js';\n\n// Extract version from package.json\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(\n readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'),\n) as { version: string };\n\n// Shared format choices for both commands\nconst FORMAT_CHOICES = [CBOR_KIND, CJSON_KIND, JSON_KIND] as const;\n\nasync function main(): Promise<void> {\n // Create command parser: options + positional\n const createOptions = opt.options({\n format: opt.enum(FORMAT_CHOICES, {\n aliases: ['f'],\n default: CJSON_KIND,\n description: 'Snapshot format',\n }),\n separator: opt.enum(['posix', 'win32'], {\n aliases: ['sep'],\n default: 'posix',\n description: 'Path separator',\n }),\n source: opt.string({\n aliases: ['s'],\n default: process.cwd(),\n description: 'File or directory to snapshot',\n }),\n });\n\n const createPositionals = pos.positionals(\n pos.string({ description: 'Path to output file', name: 'dest' }),\n );\n\n const createParser = createPositionals(createOptions);\n\n // Export command parser: options + positionals\n const exportOptions = opt.options({\n 'dry-run': opt.boolean({\n aliases: ['D'],\n description: 'Print what would be written to the filesystem',\n }),\n format: opt.enum(FORMAT_CHOICES, {\n aliases: ['f'],\n default: CJSON_KIND,\n description: 'Snapshot format',\n }),\n separator: opt.enum(['posix', 'win32'], {\n aliases: ['sep'],\n default: 'posix',\n description: 'Path separator',\n }),\n });\n\n const exportPositionals = pos.positionals(\n pos.string({\n description: 'Path to snapshot file (CBOR/CJSON/DirectoryJSON)',\n name: 'snapshot',\n required: true,\n }),\n pos.string({\n default: process.cwd(),\n description: 'Destination directory',\n name: 'dest',\n }),\n );\n\n const exportParser = exportPositionals(exportOptions);\n\n await bargs\n .create('snapshot-fs', {\n epilog:\n 'For more information, visit https://github.com/boneskull/snapshot-fs',\n version: pkg.version,\n })\n .command(\n 'create',\n createParser,\n async ({ positionals, values }) => {\n const [destRaw] = positionals;\n const dest = destRaw ? path.resolve(destRaw) : undefined;\n const kind = values.format;\n const source = path.resolve(values.source);\n // Transform separator string to actual path separator\n const pathSep =\n values.separator === 'posix' ? path.posix.sep : path.win32.sep;\n\n if (kind === JSON_KIND) {\n console.error(\n '[WARN] DirectoryJSON output is lossy and should be avoided',\n );\n }\n\n const output =\n kind === CBOR_KIND\n ? await createCBORSnapshot({ separator: pathSep, source })\n : kind === JSON_KIND\n ? await createJSONSnapshot({ separator: pathSep, source })\n : await createCJSONSnapshot({ separator: pathSep, source });\n\n if (dest) {\n await mkdir(path.dirname(dest), { recursive: true });\n await writeFile(dest, output);\n console.error(\n '[INFO] Wrote %s snapshot of %s to %s',\n kind.toUpperCase(),\n source,\n dest,\n );\n } else {\n console.log(output);\n }\n },\n 'Create memfs snapshot from filesystem',\n )\n .command(\n 'export',\n exportParser,\n async ({ positionals, values }) => {\n const [snapshotRaw, destRaw] = positionals;\n const snapshot = path.resolve(snapshotRaw);\n const dest = path.resolve(destRaw);\n const dryRun = values['dry-run'];\n const kind = values.format;\n\n const data = (await nodeFs.promises.readFile(snapshot)) as unknown;\n\n switch (kind) {\n case CBOR_KIND: {\n await exportSnapshot(kind, data as CborUint8Array<SnapshotNode>, {\n dest,\n dryRun,\n });\n break;\n }\n case CJSON_KIND: {\n await exportSnapshot(kind, data as JsonUint8Array<SnapshotNode>, {\n dest,\n dryRun,\n });\n break;\n }\n case JSON_KIND: {\n await exportSnapshot(kind, data as Uint8Array, {\n dest,\n dryRun,\n });\n break;\n }\n\n /* c8 ignore next */\n default: {\n throw new TypeError('Invalid format');\n }\n }\n\n if (!dryRun) {\n console.error(\n '[INFO] Exported %s snapshot of %s to %s',\n kind.toUpperCase(),\n snapshot,\n dest,\n );\n }\n },\n 'Export a JSON snapshot to the filesystem',\n )\n .defaultCommand('create')\n .parseAsync();\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exitCode = 1;\n});\n"]}