This repository has been archived by the owner on Feb 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: do not accept single items for ipfs.add
The types allow passing single items to `ipfs.addAll` and multiple items to `ipfs.add`. Instead, only accept single items to `ipfs.add` and streams of item to `ipfs.addAll` and fail with a more helpful error message if you do not do this.
- Loading branch information
1 parent
7806091
commit 8ca99b0
Showing
29 changed files
with
496 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
packages/ipfs-core-utils/src/files/normalise-candidate-multiple.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import errCode from 'err-code' | ||
import browserStreamToIt from 'browser-readablestream-to-it' | ||
import itPeekable from 'it-peekable' | ||
import map from 'it-map' | ||
import { | ||
isBytes, | ||
isBlob, | ||
isReadableStream, | ||
isFileObject | ||
} from './utils.js' | ||
import { | ||
parseMtime, | ||
parseMode | ||
} from 'ipfs-unixfs' | ||
|
||
/** | ||
* @typedef {import('ipfs-core-types/src/utils').ImportCandidate} ImportCandidate | ||
* @typedef {import('ipfs-core-types/src/utils').ToContent} ToContent | ||
* @typedef {import('ipfs-unixfs-importer').ImportCandidate} ImporterImportCandidate | ||
* @typedef {import('ipfs-core-types/src/utils').ImportCandidateStream} ImportCandidateStream | ||
*/ | ||
|
||
/** | ||
* @param {ImportCandidateStream} input | ||
* @param {(content:ToContent) => Promise<AsyncIterable<Uint8Array>>} normaliseContent | ||
*/ | ||
// eslint-disable-next-line complexity | ||
export async function * normaliseCandidateMultiple (input, normaliseContent) { | ||
// String | ||
// Uint8Array|ArrayBuffer|TypedArray | ||
// Blob|File | ||
if (typeof input === 'string' || input instanceof String || isBytes(input) || isBlob(input)) { | ||
throw errCode(new Error('Unexpected input: single item passed'), 'ERR_UNEXPECTED_INPUT') | ||
} | ||
|
||
// Browser ReadableStream | ||
if (isReadableStream(input)) { | ||
input = browserStreamToIt(input) | ||
} | ||
|
||
// Iterable<?> | ||
if (Symbol.iterator in input || Symbol.asyncIterator in input) { | ||
/** @type {any} */ | ||
// @ts-ignore it's (async)interable | ||
const peekable = itPeekable(input) | ||
|
||
/** @type {any} value **/ | ||
const { value, done } = await peekable.peek() | ||
|
||
if (done) { | ||
// make sure empty iterators result in empty files | ||
yield * [] | ||
return | ||
} | ||
|
||
peekable.push(value) | ||
|
||
// (Async)Iterable<Number> | ||
// (Async)Iterable<Bytes> | ||
if (Number.isInteger(value) || isBytes(value)) { | ||
throw errCode(new Error('Unexpected input: single item passed'), 'ERR_UNEXPECTED_INPUT') | ||
} | ||
|
||
// (Async)Iterable<fs.ReadStream> | ||
if (value._readableState) { | ||
// @ts-ignore Node fs.ReadStreams have a `.path` property so we need to pass it as the content | ||
yield * map(peekable, (/** @type {ImportCandidate} */ value) => toFileObject({ content: value }, normaliseContent)) | ||
return | ||
} | ||
|
||
// (Async)Iterable<(Async)Iterable<?>> | ||
// (Async)Iterable<ReadableStream<?>> | ||
// ReadableStream<(Async)Iterable<?>> | ||
// ReadableStream<ReadableStream<?>> | ||
if (isFileObject(value) || value[Symbol.iterator] || value[Symbol.asyncIterator] || isReadableStream(value)) { | ||
yield * map(peekable, (/** @type {ImportCandidate} */ value) => toFileObject(value, normaliseContent)) | ||
return | ||
} | ||
} | ||
|
||
// { path, content: ? } | ||
// Note: Detected _after_ (Async)Iterable<?> because Node.js fs.ReadStreams have a | ||
// `path` property that passes this check. | ||
if (isFileObject(input)) { | ||
throw errCode(new Error('Unexpected input: single item passed'), 'ERR_UNEXPECTED_INPUT') | ||
} | ||
|
||
throw errCode(new Error('Unexpected input: ' + typeof input), 'ERR_UNEXPECTED_INPUT') | ||
} | ||
|
||
/** | ||
* @param {ImportCandidate} input | ||
* @param {(content:ToContent) => Promise<AsyncIterable<Uint8Array>>} normaliseContent | ||
*/ | ||
async function toFileObject (input, normaliseContent) { | ||
// @ts-ignore - Those properties don't exist on most input types | ||
const { path, mode, mtime, content } = input | ||
|
||
/** @type {ImporterImportCandidate} */ | ||
const file = { | ||
path: path || '', | ||
mode: parseMode(mode), | ||
mtime: parseMtime(mtime) | ||
} | ||
|
||
if (content) { | ||
file.content = await normaliseContent(content) | ||
} else if (!path) { // Not already a file object with path or content prop | ||
// @ts-ignore - input still can be different ToContent | ||
file.content = await normaliseContent(input) | ||
} | ||
|
||
return file | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 5 additions & 6 deletions
11
...tils/src/files/normalise-input.browser.js → ...files/normalise-input-multiple.browser.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,24 @@ | ||
import { normaliseContent } from './normalise-content.browser.js' | ||
import { normalise } from './normalise.js' | ||
import { normaliseCandidateMultiple } from './normalise-candidate-multiple.js' | ||
|
||
/** | ||
* @typedef {import('ipfs-core-types/src/utils').ImportCandidateStream} ImportCandidateStream | ||
* @typedef {import('ipfs-core-types/src/utils').ImportCandidate} ImportCandidate | ||
* @typedef {import('ipfs-core-types/src/utils').BrowserImportCandidate} BrowserImportCandidate | ||
*/ | ||
|
||
/** | ||
* Transforms any of the `ipfs.add` input types into | ||
* Transforms any of the `ipfs.addAll` input types into | ||
* | ||
* ``` | ||
* AsyncIterable<{ path, mode, mtime, content: Blob }> | ||
* ``` | ||
* | ||
* See https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/FILES.md#ipfsadddata-options | ||
* | ||
* @param {ImportCandidate | ImportCandidateStream} input | ||
* @param {ImportCandidateStream} input | ||
* @returns {AsyncGenerator<BrowserImportCandidate, void, undefined>} | ||
*/ | ||
export function normaliseInput (input) { | ||
// @ts-ignore normaliseContent returns Blob and not AsyncIterator | ||
return normalise(input, normaliseContent) | ||
// @ts-expect-error browser normaliseContent returns a Blob not an AsyncIterable<Uint8Array> | ||
return normaliseCandidateMultiple(input, normaliseContent, true) | ||
} |
21 changes: 21 additions & 0 deletions
21
packages/ipfs-core-utils/src/files/normalise-input-multiple.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { normaliseContent } from './normalise-content.js' | ||
import { normaliseCandidateMultiple } from './normalise-candidate-multiple.js' | ||
|
||
/** | ||
* @typedef {import('ipfs-core-types/src/utils').ImportCandidateStream} ImportCandidateStream | ||
*/ | ||
|
||
/** | ||
* Transforms any of the `ipfs.addAll` input types into | ||
* | ||
* ``` | ||
* AsyncIterable<{ path, mode, mtime, content: AsyncIterable<Uint8Array> }> | ||
* ``` | ||
* | ||
* See https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/FILES.md#ipfsadddata-options | ||
* | ||
* @param {ImportCandidateStream} input | ||
*/ | ||
export function normaliseInput (input) { | ||
return normaliseCandidateMultiple(input, normaliseContent) | ||
} |
Oops, something went wrong.