diff --git a/packages/ipfs-unixfs-importer/README.md b/packages/ipfs-unixfs-importer/README.md index 00abe7c0..e76fed1a 100644 --- a/packages/ipfs-unixfs-importer/README.md +++ b/packages/ipfs-unixfs-importer/README.md @@ -14,7 +14,8 @@ - [Example](#example) - [API](#api) - [const stream = importer(source, blockstore \[, options\])](#const-stream--importersource-blockstore--options) - - [const result = await importContent(content, blockstore \[, options\])](#const-result--await-importcontentcontent-blockstore--options) + - [const result = await importFile(content, blockstore \[, options\])](#const-result--await-importfilecontent-blockstore--options) + - [const result = await importDirectory(content, blockstore \[, options\])](#const-result--await-importdirectorycontent-blockstore--options) - [const result = await importBytes(buf, blockstore \[, options\])](#const-result--await-importbytesbuf-blockstore--options) - [const result = await importByteStream(source, blockstore \[, options\])](#const-result--await-importbytestreamsource-blockstore--options) - [API Docs](#api-docs) @@ -97,7 +98,7 @@ When run, metadata about DAGNodes in the created tree is printed until the root: ## API ```js -import { importer, importContent, importBytes } from 'ipfs-unixfs-importer' +import { importer, importFile, importDir, importBytes, importByteStream } from 'ipfs-unixfs-importer' ``` ### const stream = importer(source, blockstore \[, options]) @@ -119,10 +120,14 @@ The `importer` function returns an async iterator takes a source async iterator The input's file paths and directory structure will be preserved in the [`dag-pb`](https://github.com/ipld/js-dag-pb) created nodes. -### const result = await importContent(content, blockstore \[, options]) +### const result = await importFile(content, blockstore \[, options]) A convenience function for importing a single file or directory. +### const result = await importDirectory(content, blockstore \[, options]) + +A convenience function for importing a directory - note this is non-recursive, to import recursively use the [importer](#const-stream--importersource-blockstore--options) function. + ### const result = await importBytes(buf, blockstore \[, options]) A convenience function for importing a single Uint8Array. diff --git a/packages/ipfs-unixfs-importer/src/dag-builder/index.ts b/packages/ipfs-unixfs-importer/src/dag-builder/index.ts index d5cba6e6..3ef84010 100644 --- a/packages/ipfs-unixfs-importer/src/dag-builder/index.ts +++ b/packages/ipfs-unixfs-importer/src/dag-builder/index.ts @@ -1,7 +1,7 @@ import { dirBuilder, DirBuilderOptions } from './dir.js' import { fileBuilder, FileBuilderOptions } from './file.js' import errCode from 'err-code' -import type { Directory, File, ImportCandidate, InProgressImportResult } from '../index.js' +import type { Directory, File, FileCandidate, ImportCandidate, InProgressImportResult } from '../index.js' import type { Blockstore } from 'interface-blockstore' import type { ChunkValidator } from './validate-chunks.js' import type { Chunker } from '../chunker/index.js' @@ -59,7 +59,7 @@ export function defaultDagBuilder (options: DagBuilderOptions): DAGBuilder { .join('/') } - if (entry.content != null) { + if (isFileCandidate(entry)) { const file: File = { path: entry.path, mtime: entry.mtime, @@ -84,3 +84,7 @@ export function defaultDagBuilder (options: DagBuilderOptions): DAGBuilder { } } } + +function isFileCandidate (entry: any): entry is FileCandidate { + return entry.content != null +} diff --git a/packages/ipfs-unixfs-importer/src/index.ts b/packages/ipfs-unixfs-importer/src/index.ts index e14950ba..691c05f1 100644 --- a/packages/ipfs-unixfs-importer/src/index.ts +++ b/packages/ipfs-unixfs-importer/src/index.ts @@ -16,13 +16,21 @@ import type { AwaitIterable } from 'blockstore-core/base' export type ByteStream = AwaitIterable export type ImportContent = ByteStream | Uint8Array -export interface ImportCandidate { +export interface FileCandidate { path?: string - content?: ImportContent + content: ImportContent mtime?: Mtime mode?: number } +export interface DirectoryCandidate { + path: string + mtime?: Mtime + mode?: number +} + +export type ImportCandidate = FileCandidate | DirectoryCandidate + export interface File { content: AsyncIterable path?: string @@ -180,7 +188,7 @@ export interface ImporterOptions { chunkValidator?: ChunkValidator } -export type ImportCandidateStream = AsyncIterable | Iterable +export type ImportCandidateStream = AsyncIterable | Iterable /** * The importer creates UnixFS DAGs and stores the blocks that make @@ -210,7 +218,7 @@ export type ImportCandidateStream = AsyncIterable | Iterable { - let candidates: AsyncIterable | Iterable + let candidates: AsyncIterable | Iterable if (Symbol.asyncIterator in source || Symbol.iterator in source) { candidates = source @@ -261,28 +269,59 @@ export async function * importer (source: ImportCandidateStream, blockstore: Blo } /** - * `importContent` is similar to `importer` except it accepts a single - * `ImportCandidate` and returns a promise of a single `ImportResult` + * `importFile` is similar to `importer` except it accepts a single + * `FileCandidate` and returns a promise of a single `ImportResult` * instead of a stream of results. * * @example * * ```typescript - * import { importOne } from 'ipfs-unixfs-importer' + * import { importFile } from 'ipfs-unixfs-importer' * import { MemoryBlockstore } from 'blockstore-core' * * // store blocks in memory, other blockstores are available * const blockstore = new MemoryBlockstore() * - * const input = { + * const input: FileCandidate = { * path: './foo.txt', * content: Uint8Array.from([0, 1, 2, 3, 4]) * } * - * const entry = await importContent(input, blockstore) + * const entry = await importFile(input, blockstore) + * ``` + */ +export async function importFile (content: FileCandidate, blockstore: Blockstore, options: ImporterOptions = {}): Promise { + const result = await first(importer([content], blockstore, options)) + + if (result == null) { + throw errcode(new Error('Nothing imported'), 'ERR_INVALID_PARAMS') + } + + return result +} + +/** + * `importDir` is similar to `importer` except it accepts a single + * `DirectoryCandidate` and returns a promise of a single `ImportResult` + * instead of a stream of results. + * + * @example + * + * ```typescript + * import { importDirectory } from 'ipfs-unixfs-importer' + * import { MemoryBlockstore } from 'blockstore-core' + * + * // store blocks in memory, other blockstores are available + * const blockstore = new MemoryBlockstore() + * + * const input: DirectoryCandidate = { + * path: './foo.txt' + * } + * + * const entry = await importDirectory(input, blockstore) * ``` */ -export async function importContent (content: ImportCandidate, blockstore: Blockstore, options: ImporterOptions = {}): Promise { +export async function importDirectory (content: DirectoryCandidate, blockstore: Blockstore, options: ImporterOptions = {}): Promise { const result = await first(importer([content], blockstore, options)) if (result == null) { @@ -299,7 +338,7 @@ export async function importContent (content: ImportCandidate, blockstore: Block * @example * * ```typescript - * import { importOne } from 'ipfs-unixfs-importer' + * import { importBytes } from 'ipfs-unixfs-importer' * import { MemoryBlockstore } from 'blockstore-core' * * // store blocks in memory, other blockstores are available @@ -311,7 +350,7 @@ export async function importContent (content: ImportCandidate, blockstore: Block * ``` */ export async function importBytes (buf: ImportContent, blockstore: Blockstore, options: ImporterOptions = {}): Promise { - return await importContent({ + return await importFile({ content: buf }, blockstore, options) } @@ -323,7 +362,7 @@ export async function importBytes (buf: ImportContent, blockstore: Blockstore, o * @example * * ```typescript - * import { importOne } from 'ipfs-unixfs-importer' + * import { importByteStream } from 'ipfs-unixfs-importer' * import { MemoryBlockstore } from 'blockstore-core' * * // store blocks in memory, other blockstores are available @@ -338,7 +377,7 @@ export async function importBytes (buf: ImportContent, blockstore: Blockstore, o * ``` */ export async function importByteStream (bufs: ByteStream, blockstore: Blockstore, options: ImporterOptions = {}): Promise { - return await importContent({ + return await importFile({ content: bufs }, blockstore, options) }