Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

fix: files.add with pull streams + ability to seek #1319

Merged
merged 10 commits into from
May 6, 2018
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -459,8 +459,18 @@ A set of data types are exposed directly from the IPFS instance under `ipfs.type
- [`ipfs.types.PeerId`](https://github.com/libp2p/js-peer-id)
- [`ipfs.types.PeerInfo`](https://github.com/libp2p/js-peer-info)
- [`ipfs.types.multiaddr`](https://github.com/multiformats/js-multiaddr)
- [`ipfs.types.multibase`](https://github.com/multiformats/multibase)
- [`ipfs.types.multihash`](https://github.com/multiformats/js-multihash)
- [`ipfs.types.CID`](https://github.com/ipld/js-cid)
- [`ipfs.types.dagPB`](https://github.com/ipld/js-ipld-dag-pb)
- [`ipfs.types.dagCBOR`](https://github.com/ipld/js-ipld-dag-cbor)

#### `Util`

A set of utils are exposed directly from the IPFS instance under `ipfs.util`. That way you're not required to import/require the following:

- [`ipfs.util.crypto`](https://github.com/libp2p/js-libp2p-crypto)
- [`ipfs.util.isIPFS`](https://github.com/ipfs-shipyard/is-ipfs)

## FAQ

Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"expose-loader": "^0.7.5",
"form-data": "^2.3.2",
"hat": "0.0.3",
"interface-ipfs-core": "^0.61.0",
"interface-ipfs-core": "^0.64.2",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alanshaw something might have changed here

"ipfsd-ctl": "^0.32.1",
"lodash": "^4.17.10",
"mocha": "^5.1.1",
Expand Down Expand Up @@ -113,9 +113,12 @@
"ipfs-multipart": "~0.1.0",
"ipfs-repo": "~0.20.0",
"ipfs-unixfs": "~0.1.14",
"ipld-dag-cbor": "^0.12.0",
"ipld-dag-pb": "^0.14.4",
"ipfs-unixfs-engine": "~0.29.0",
"ipld": "^0.17.0",
"is-ipfs": "^0.3.2",
"is-pull-stream": "0.0.0",
"is-stream": "^1.1.0",
"joi": "^13.2.0",
"joi-browser": "^13.0.1",
Expand All @@ -140,6 +143,7 @@
"mafmt": "^6.0.0",
"mime-types": "^2.1.18",
"mkdirp": "~0.5.1",
"multibase": "^0.4.0",
"multiaddr": "^5.0.0",
"multihashes": "~0.4.13",
"once": "^1.4.0",
Expand All @@ -161,7 +165,6 @@
"pull-zip": "^2.0.1",
"read-pkg-up": "^3.0.0",
"readable-stream": "2.3.6",
"safe-buffer": "^5.1.2",
"stream-to-pull-stream": "^1.7.2",
"tar-stream": "^1.6.0",
"temp": "~0.8.3",
Expand Down
81 changes: 51 additions & 30 deletions src/core/components/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const toPull = require('stream-to-pull-stream')
const deferred = require('pull-defer')
const waterfall = require('async/waterfall')
const isStream = require('is-stream')
const isSource = require('is-pull-stream').isSource
const Duplex = require('readable-stream').Duplex
const OtherBuffer = require('buffer').Buffer
const CID = require('cids')
Expand Down Expand Up @@ -60,6 +61,10 @@ function normalizeContent (opts, content) {
data = { path: '', content: toPull.source(data) }
}

if (isSource(data)) {
data = { path: '', content: data }
}

if (data && data.content && typeof data.content !== 'function') {
if (Buffer.isBuffer(data.content)) {
data.content = pull.values([data.content])
Expand Down Expand Up @@ -196,40 +201,56 @@ module.exports = function files (self) {
}

return {
add: promisify((data, options = {}, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
} else if (!callback || typeof callback !== 'function') {
callback = noop
}
add: (() => {
const add = promisify((data, options = {}, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
} else if (!callback || typeof callback !== 'function') {
callback = noop
}

const ok = Buffer.isBuffer(data) ||
isStream.readable(data) ||
Array.isArray(data) ||
OtherBuffer.isBuffer(data) ||
typeof data === 'object'
const ok = Buffer.isBuffer(data) ||
isStream.readable(data) ||
Array.isArray(data) ||
OtherBuffer.isBuffer(data) ||
typeof data === 'object' ||
isSource(data)

if (!ok) {
return callback(new Error('first arg must be a buffer, readable stream, an object or array of objects'))
}
if (!ok) {
return callback(new Error('first arg must be a buffer, readable stream, pull stream, an object or array of objects'))
}

// CID v0 is for multihashes encoded with sha2-256
if (options.hashAlg && options.cidVersion !== 1) {
options.cidVersion = 1
}
// CID v0 is for multihashes encoded with sha2-256
if (options.hashAlg && options.cidVersion !== 1) {
options.cidVersion = 1
}

pull(
pull.values([data]),
_addPullStream(options),
sort((a, b) => {
if (a.path < b.path) return 1
if (a.path > b.path) return -1
return 0
}),
pull.collect(callback)
)
}),
pull(
pull.values([data]),
_addPullStream(options),
sort((a, b) => {
if (a.path < b.path) return 1
if (a.path > b.path) return -1
return 0
}),
pull.collect(callback)
)
})

return function () {
const args = Array.from(arguments)

// If we files.add(<pull stream>), then promisify thinks the pull stream
// is a callback! Add an empty options object in this case so that a
// promise is returned.
if (args.length === 1 && isSource(args[0])) {
args.push({})
}

return add.apply(null, args)
}
})(),

addReadableStream: (options) => {
options = options || {}
Expand Down
16 changes: 15 additions & 1 deletion src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ const BlockService = require('ipfs-block-service')
const Ipld = require('ipld')
const PeerId = require('peer-id')
const PeerInfo = require('peer-info')
const dagCBOR = require('ipld-dag-cbor')
const dagPB = require('ipld-dag-pb')
const crypto = require('libp2p-crypto')
const isIPFS = require('is-ipfs')
const multiaddr = require('multiaddr')
const multihash = require('multihashes')
const PeerBook = require('peer-book')
const multibase = require('multibase')
const CID = require('cids')
const debug = require('debug')
const extend = require('deep-extend')
Expand Down Expand Up @@ -58,8 +63,11 @@ class IPFS extends EventEmitter {
PeerId: PeerId,
PeerInfo: PeerInfo,
multiaddr: multiaddr,
multibase: multibase,
multihash: multihash,
CID: CID
CID: CID,
dagPB: dagPB,
dagCBOR: dagCBOR
}

// IPFS Core Internals
Expand Down Expand Up @@ -120,6 +128,12 @@ class IPFS extends EventEmitter {
this.lsReadableStream = this.files.lsReadableStreamImmutable
this.lsPullStream = this.files.lsPullStreamImmutable

// ipfs.util
this.util = {
crypto: crypto,
isIPFS: isIPFS
}

boot(this)
}
}
Expand Down
17 changes: 16 additions & 1 deletion test/core/init.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ const isNode = require('detect-node')
const hat = require('hat')
const PeerId = require('peer-id')
const PeerInfo = require('peer-info')
const dagCBOR = require('ipld-dag-cbor')
const dagPB = require('ipld-dag-pb')
const crypto = require('libp2p-crypto')
const isIPFS = require('is-ipfs')
const multiaddr = require('multiaddr')
const multibase = require('multibase')
const multihash = require('multihashes')
const CID = require('cids')
const IPFS = require('../../src/core')
Expand Down Expand Up @@ -101,8 +106,18 @@ describe('init', () => {
PeerId: PeerId,
PeerInfo: PeerInfo,
multiaddr: multiaddr,
multibase: multibase,
multihash: multihash,
CID: CID
CID: CID,
dagPB: dagPB,
dagCBOR: dagCBOR
})
})

it('util', () => {
expect(ipfs.util).to.be.deep.equal({
crypto: crypto,
isIPFS: isIPFS
})
})
})