UNPKG

ipfs-car

Version:

Convert files to content-addressed archives (.car) and back

68 lines (61 loc) 2.04 kB
import fs from 'fs' import { pipeline } from 'stream/promises' import { CarIndexedReader } from '@ipld/car/indexed-reader' import { recursive as exporter } from 'ipfs-unixfs-exporter' import { validateBlock } from '@web3-storage/car-block-validator' import { tmpPath } from './lib/tmp.js' import { getRoots } from './lib/car.js' /** * @param {string} carPath * @param {object} [opts] * @param {string} [opts.root] * @param {boolean} [opts.verify] * @param {string} [opts.output] */ export default async function unpack (carPath, opts = {}) { if (!carPath) { carPath = tmpPath() await pipeline(process.stdin, fs.createWriteStream(carPath)) } const reader = await CarIndexedReader.fromFile(carPath) const roots = await getRoots(reader, opts) // @ts-expect-error blockstore not got `has` or `put` but they are unused const entries = exporter(roots[0], { async get (cid) { const block = await reader.get(cid) if (!block) { console.error(`Missing block: ${cid}`) process.exit(1) } /* c8 ignore next */ if (opts.verify || opts.verify == null) { // @ts-expect-error await validateBlock(block) } return block.bytes } }) for await (const entry of entries) { if (!opts.output) { if (entry.type === 'file' || entry.type === 'raw') { await pipeline(entry.content, process.stdout) break } console.error('Not a file - specify output path with --output') process.exit(1) } let filePath = entry.path const parts = entry.path.split('/') parts[0] = opts.output filePath = parts.join('/') if (entry.type === 'file' || entry.type === 'raw') { await pipeline(entry.content, fs.createWriteStream(filePath)) } else if (entry.type === 'directory') { await fs.promises.mkdir(filePath, { recursive: true }) /* c8 ignore next 4 */ } else { console.error(`Unsupported UnixFS type ${entry.type} for path: ${entry.path}`) process.exit(1) } } }