diff --git a/README.md b/README.md index fd25760249..bf3750f73c 100644 --- a/README.md +++ b/README.md @@ -25,13 +25,13 @@

-### Project status +### Project status - `Alpha` We've come a long way, but this project is still in Alpha, lots of development is happening, API might change, beware of the Dragons 🐉.. **Want to get started?** Check our [examples folder](/examples) to learn how to spawn an IPFS node in Node.js and in the Browser. -You can check the development status at the [Waffle Board](https://waffle.io/ipfs/js-ipfs). +You can check the development status at the [Kanban Board](https://waffle.io/ipfs/js-ipfs). [![Throughput Graph](https://graphs.waffle.io/ipfs/js-ipfs/throughput.svg)](https://waffle.io/ipfs/js-ipfs/metrics/throughput) @@ -494,36 +494,35 @@ The core API is grouped into several areas: #### Files -- [files](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md) - - [`ipfs.files.add(data, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesadd). - - [`ipfs.files.addPullStream([options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesaddpullstream) - - [`ipfs.files.addReadableStream([options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesaddreadablestream) - - [`ipfs.files.cat(ipfsPath, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filescat). - - [`ipfs.files.catPullStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filescatpullstream) - - [`ipfs.files.catReadableStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filescatreadablestream) - - [`ipfs.files.get(ipfsPath, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesget). - - [`ipfs.files.getPullStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesgetpullstream) - - [`ipfs.files.getReadableStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesgetreadablestream) +- [Regular Files API](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md) + - [`ipfs.add(data, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#add) + - [`ipfs.addPullStream([options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addpullstream) + - [`ipfs.addReadableStream([options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addreadablestream) + - [`ipfs.addFromStream(stream, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addfromstream) + - [`ipfs.addFromFs(path, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addfromfs) + - [`ipfs.addFromUrl(url, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addfromurl) + - [`ipfs.cat(ipfsPath, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#cat) + - [`ipfs.catPullStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#catpullstream) + - [`ipfs.catReadableStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#catreadablestream) + - [`ipfs.get(ipfsPath, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#get) + - [`ipfs.getPullStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#getpullstream) + - [`ipfs.getReadableStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#getreadablestream) - [`ipfs.ls(ipfsPath, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#ls) - [`ipfs.lsPullStream(ipfsPath)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#lspullstream) - [`ipfs.lsReadableStream(ipfsPath)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#lsreadablestream) - - [MFS (mutable file system) specific](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#mutable-file-system) - - [`ipfs.files.cp([from, to], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filescp) - - [`ipfs.files.flush([path], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesflush) - - [`ipfs.files.ls([path], [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesls) - - [`ipfs.files.mkdir(path, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesmkdir) - - [`ipfs.files.mv([from, to], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesmv) - - [`ipfs.files.read(path, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesread) - - [`ipfs.files.readPullStream(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesreadpullstream) - - [`ipfs.files.readReadableStream(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesreadreadablestream) - - [`ipfs.files.rm(path, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesrm) - - [`ipfs.files.stat(path, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesstat) - - [`ipfs.files.write(path, content, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#fileswrite) +- [MFS (mutable file system) specific](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#mutable-file-system) + - [`ipfs.files.cp([from, to], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filescp) + - [`ipfs.files.flush([path], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesflush) + - [`ipfs.files.ls([path], [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesls) + - [`ipfs.files.mkdir(path, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesmkdir) + - [`ipfs.files.mv([from, to], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesmv) + - [`ipfs.files.read(path, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesread) + - [`ipfs.files.readPullStream(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesreadpullstream) + - [`ipfs.files.readReadableStream(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesreadreadablestream) + - [`ipfs.files.rm(path, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesrm) + - [`ipfs.files.stat(path, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesstat) + - [`ipfs.files.write(path, content, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#fileswrite) -- [block](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md) - - [`ipfs.block.get(cid, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md#blockget) - - [`ipfs.block.put(block, cid, [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md#blockput) - - [`ipfs.block.stat(cid, [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md#blockstat) #### Graph @@ -532,7 +531,12 @@ The core API is grouped into several areas: - [`ipfs.dag.get(cid, [path], [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/DAG.md#dagget) - [`ipfs.dag.tree(cid, [path], [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/DAG.md#dagtree) -- [object](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md) +- [pin](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md) + - [`ipfs.pin.add(hash, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md#pinadd) + - [`ipfs.pin.ls([hash], [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md#pinls) + - [`ipfs.pin.rm(hash, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md#pinrm) + +- [object (legacy)](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md) - [`ipfs.object.new([template], [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectnew) - [`ipfs.object.put(obj, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectput) - [`ipfs.object.get(multihash, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectget) @@ -544,10 +548,15 @@ The core API is grouped into several areas: - [`ipfs.object.patch.appendData(multihash, data, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectpatchappenddata) - [`ipfs.object.patch.setData(multihash, data, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectpatchsetdata) -- [pin](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md) - - [`ipfs.pin.add(hash, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md#pinadd) - - [`ipfs.pin.ls([hash], [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md#pinls) - - [`ipfs.pin.rm(hash, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md#pinrm) +#### Block + +- [block](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md) + - [`ipfs.block.get(cid, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md#blockget) + - [`ipfs.block.put(block, cid, [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md#blockput) + - [`ipfs.block.stat(cid, [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md#blockstat) +- [bitswap](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BITSWAP.md) + - [`ipfs.bitswap.wantlist([peerId], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BITSWAP.md#bitswapwantlist) + - [`ipfs.bitswap.stat([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BITSWAP.md#bitswapstat) #### Name @@ -574,10 +583,6 @@ The core API is grouped into several areas: - [`ipfs.bootstrap.add(addr, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BOOTSTRAP.md#bootstrapadd) - [`ipfs.bootstrap.rm(peer, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BOOTSTRAP.md#bootstraprm) -- [bitswap](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BITSWAP.md) - - [`ipfs.bitswap.wantlist([peerId], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BITSWAP.md#bitswapwantlist) - - [`ipfs.bitswap.stat([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BITSWAP.md#bitswapstat) - - dht (not implemented yet) - [pubsub](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PUBSUB.md) @@ -1007,10 +1012,10 @@ What does this image explain? IPFS implementation in JavaScript is a work in progress. As such, there's a few things you can do right now to help out: - * Go through the modules below and **check out existing issues**. This would be especially useful for modules in active development. Some knowledge of IPFS may be required, as well as the infrastructure behind it - for instance, you may need to read up on p2p and more complex operations like muxing to be able to help technically. - * **Perform code reviews**. More eyes will help (a) speed the project along, (b) ensure quality, and (c) reduce possible future bugs. - * Take a look at go-ipfs and some of the planning repositories or issues: for instance, the [libp2p spec](https://github.com/ipfs/specs/pull/19). Contributions here that would be most helpful are **top-level comments** about how it should look based on our understanding. Again, the more eyes the better. - * **Add tests**. There can never be enough tests. +- Go through the modules below and **check out existing issues**. This would be especially useful for modules in active development. Some knowledge of IPFS may be required, as well as the infrastructure behind it - for instance, you may need to read up on p2p and more complex operations like muxing to be able to help technically. +- **Perform code reviews**. More eyes will help (a) speed the project along, (b) ensure quality, and (c) reduce possible future bugs. +- Take a look at go-ipfs and some of the planning repositories or issues: for instance, the [libp2p spec](https://github.com/ipfs/specs/pull/19). Contributions here that would be most helpful are **top-level comments** about how it should look based on our understanding. Again, the more eyes the better. +- **Add tests**. There can never be enough tests. ### Want to hack on IPFS? diff --git a/package.json b/package.json index 54e9d491d9..1d9aad43a9 100644 --- a/package.json +++ b/package.json @@ -69,8 +69,8 @@ "execa": "^1.0.0", "form-data": "^2.3.3", "hat": "0.0.3", - "interface-ipfs-core": "~0.84.2", - "ipfsd-ctl": "~0.39.5", + "interface-ipfs-core": "~0.86.0", + "ipfsd-ctl": "~0.40.0", "ncp": "^2.0.0", "qs": "^6.5.2", "rimraf": "^2.6.2", @@ -100,17 +100,17 @@ "hoek": "^5.0.4", "human-to-milliseconds": "^1.0.0", "interface-datastore": "~0.6.0", - "ipfs-api": "^26.1.0", + "ipfs-api": "ipfs/js-ipfs-api", "ipfs-bitswap": "~0.21.0", "ipfs-block": "~0.8.0", "ipfs-block-service": "~0.15.1", "ipfs-http-response": "~0.2.0", - "ipfs-mfs": "~0.4.2", + "ipfs-mfs": "~0.5.2", "ipfs-multipart": "~0.1.0", "ipfs-repo": "~0.25.0", "ipfs-unixfs": "~0.1.16", - "ipfs-unixfs-engine": "~0.33.0", - "ipld": "~0.19.3", + "ipfs-unixfs-engine": "~0.34.0", + "ipld": "~0.20.1", "ipld-bitcoin": "~0.1.8", "ipld-dag-pb": "~0.14.11", "ipld-ethereum": "^2.0.1", diff --git a/src/cli/bin.js b/src/cli/bin.js index 49163d909e..401357ebf3 100755 --- a/src/cli/bin.js +++ b/src/cli/bin.js @@ -69,20 +69,9 @@ if (args[0] === 'daemon' || args[0] === 'init') { throw err } - // add mfs commands + // add MFS (Files API) commands mfs(cli) - // NOTE: This creates an alias of - // `jsipfs files {add, get, cat}` to `jsipfs {add, get, cat}`. - // This will stay until https://github.com/ipfs/specs/issues/98 is resolved. - const addCmd = require('./commands/files/add') - const catCmd = require('./commands/files/cat') - const getCmd = require('./commands/files/get') - const aliases = [addCmd, catCmd, getCmd] - aliases.forEach((alias) => { - cli.command(alias) - }) - cli .commandDir('commands') .help() diff --git a/src/cli/commands/files/add.js b/src/cli/commands/add.js similarity index 96% rename from src/cli/commands/files/add.js rename to src/cli/commands/add.js index 2ab492f27f..8b930434d6 100644 --- a/src/cli/commands/files/add.js +++ b/src/cli/commands/add.js @@ -11,9 +11,9 @@ const getFolderSize = require('get-folder-size') const byteman = require('byteman') const waterfall = require('async/waterfall') const mh = require('multihashes') -const utils = require('../../utils') -const print = require('../../utils').print -const createProgressBar = require('../../utils').createProgressBar +const utils = require('../utils') +const print = require('../utils').print +const createProgressBar = require('../utils').createProgressBar function checkPath (inPath, recursive) { // This function is to check for the following possible inputs @@ -231,7 +231,7 @@ module.exports = { } } - next(null, ipfs.files.addPullStream(options)) + next(null, ipfs.addPullStream(options)) } ], (err, addStream) => { if (err) throw err diff --git a/src/cli/commands/files/cat.js b/src/cli/commands/cat.js similarity index 91% rename from src/cli/commands/files/cat.js rename to src/cli/commands/cat.js index f68d6badfa..3a7548fea0 100644 --- a/src/cli/commands/files/cat.js +++ b/src/cli/commands/cat.js @@ -29,7 +29,7 @@ module.exports = { length: argv.length } - const stream = argv.ipfs.files.catReadableStream(path, options) + const stream = argv.ipfs.catReadableStream(path, options) stream.once('error', (err) => { throw err diff --git a/src/cli/commands/files/get.js b/src/cli/commands/get.js similarity index 94% rename from src/cli/commands/files/get.js rename to src/cli/commands/get.js index d9e0a39a67..1f571e175d 100644 --- a/src/cli/commands/files/get.js +++ b/src/cli/commands/get.js @@ -5,7 +5,7 @@ const path = require('path') const mkdirp = require('mkdirp') const pull = require('pull-stream') const toPull = require('stream-to-pull-stream') -const print = require('../../utils').print +const print = require('../utils').print function checkArgs (hash, outPath) { // format the output directory @@ -63,7 +63,7 @@ module.exports = { const dir = checkArgs(ipfsPath, argv.output) - const stream = argv.ipfs.files.getReadableStream(ipfsPath) + const stream = argv.ipfs.getReadableStream(ipfsPath) stream.once('error', (err) => { if (err) { throw err } diff --git a/src/core/components/files-mfs.js b/src/core/components/files-mfs.js new file mode 100644 index 0000000000..531219c4fd --- /dev/null +++ b/src/core/components/files-mfs.js @@ -0,0 +1,9 @@ +'use strict' + +const mfs = require('ipfs-mfs/core') + +module.exports = self => mfs({ + ipld: self._ipld, + repo: self._repo, + repoOwner: self._options.repoOwner +}) diff --git a/src/core/components/files.js b/src/core/components/files-regular.js similarity index 93% rename from src/core/components/files.js rename to src/core/components/files-regular.js index f13f42ae43..d843ba6735 100644 --- a/src/core/components/files.js +++ b/src/core/components/files-regular.js @@ -24,6 +24,23 @@ const WRAPPER = 'wrapper/' function noop () {} +function normalizePath (path) { + if (Buffer.isBuffer(path)) { + path = toB58String(path) + } + if (CID.isCID(path)) { + path = path.toBaseEncodedString() + } + if (path.indexOf('/ipfs/') === 0) { + path = path.substring('/ipfs/'.length) + } + if (path.charAt(path.length - 1) === '/') { + path = path.substring(0, path.length - 1) + } + + return path +} + function prepareFile (self, opts, file, callback) { opts = opts || {} @@ -47,7 +64,9 @@ function prepareFile (self, opts, file, callback) { } cb(null, { - path: opts.wrapWithDirectory ? file.path.substring(WRAPPER.length) : (file.path || b58Hash), + path: opts.wrapWithDirectory + ? file.path.substring(WRAPPER.length) + : (file.path || b58Hash), hash: b58Hash, size }) @@ -154,7 +173,8 @@ class AddHelper extends Duplex { } } -module.exports = function files (self) { +module.exports = function (self) { + // Internal add func that gets used by all add funcs function _addPullStream (options = {}) { let chunkerOptions try { @@ -191,6 +211,7 @@ module.exports = function files (self) { ) } + // Internal cat func that gets used by all cat funcs function _catPullStream (ipfsPath, options) { if (typeof ipfsPath === 'function') { throw new Error('You must supply an ipfsPath') @@ -232,7 +253,8 @@ module.exports = function files (self) { return d } - function _lsPullStreamImmutable (ipfsPath, options) { + // Internal ls func that gets used by all ls funcs + function _lsPullStream (ipfsPath, options) { options = options || {} const path = normalizePath(ipfsPath) @@ -301,7 +323,7 @@ module.exports = function files (self) { return function () { const args = Array.from(arguments) - // If we files.add(), then promisify thinks the pull stream + // If we .add(), 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])) { @@ -337,7 +359,7 @@ module.exports = function files (self) { } if (typeof callback !== 'function') { - throw new Error('Please supply a callback to ipfs.files.cat') + throw new Error('Please supply a callback to ipfs.cat') } pull( @@ -441,7 +463,7 @@ module.exports = function files (self) { return exporter(ipfsPath, self._ipld, options) }, - lsImmutable: promisify((ipfsPath, options, callback) => { + ls: promisify((ipfsPath, options, callback) => { if (typeof options === 'function') { callback = options options = {} @@ -450,7 +472,7 @@ module.exports = function files (self) { options = options || {} pull( - _lsPullStreamImmutable(ipfsPath, options), + _lsPullStream(ipfsPath, options), pull.collect((err, values) => { if (err) { callback(err) @@ -461,27 +483,14 @@ module.exports = function files (self) { ) }), - lsReadableStreamImmutable: (ipfsPath, options) => { - return toStream.source(_lsPullStreamImmutable(ipfsPath, options)) + lsReadableStream: (ipfsPath, options) => { + return toStream.source(_lsPullStream(ipfsPath, options)) }, - lsPullStreamImmutable: _lsPullStreamImmutable - } -} + lsPullStream: _lsPullStream -function normalizePath (path) { - if (Buffer.isBuffer(path)) { - path = toB58String(path) - } - if (CID.isCID(path)) { - path = path.toBaseEncodedString() + // TODO create addFromFs + // TODO create addFromStream + // TODO create addFromUrl } - if (path.indexOf('/ipfs/') === 0) { - path = path.substring('/ipfs/'.length) - } - if (path.charAt(path.length - 1) === '/') { - path = path.substring(0, path.length - 1) - } - - return path } diff --git a/src/core/components/index.js b/src/core/components/index.js index cf6506e6dd..ac893efbdd 100644 --- a/src/core/components/index.js +++ b/src/core/components/index.js @@ -19,13 +19,13 @@ exports.ping = require('./ping') exports.pingPullStream = require('./ping-pull-stream') exports.pingReadableStream = require('./ping-readable-stream') exports.pin = require('./pin') -exports.files = require('./files') +exports.filesRegular = require('./files-regular') +exports.filesMFS = require('./files-mfs') exports.bitswap = require('./bitswap') exports.pubsub = require('./pubsub') exports.dht = require('./dht') exports.dns = require('./dns') exports.key = require('./key') exports.stats = require('./stats') -exports.mfs = require('./mfs') exports.resolve = require('./resolve') exports.name = require('./name') diff --git a/src/core/components/init-assets.js b/src/core/components/init-assets.js index 9756a83d56..362bad7345 100644 --- a/src/core/components/init-assets.js +++ b/src/core/components/init-assets.js @@ -21,7 +21,7 @@ module.exports = function addDefaultAssets (self, log, callback) { const addPath = element.substring(index + 1) return { path: addPath, content: file(element) } }), - self.files.addPullStream(), + self.addPullStream(), pull.through(file => { if (file.path === 'init-docs') { const cid = new CID(file.hash) diff --git a/src/core/components/mfs.js b/src/core/components/mfs.js deleted file mode 100644 index 2fd44d2979..0000000000 --- a/src/core/components/mfs.js +++ /dev/null @@ -1,40 +0,0 @@ -'use strict' - -const promisify = require('promisify-es6') -const mfs = require('ipfs-mfs/core') - -module.exports = self => { - const mfsSelf = Object.assign({}, self) - - // A patched dag API to ensure preload doesn't happen for MFS operations - // (MFS is preloaded periodically) - mfsSelf.dag = Object.assign({}, self.dag, { - get: promisify((cid, path, opts, cb) => { - if (typeof path === 'function') { - cb = path - path = undefined - } - - if (typeof opts === 'function') { - cb = opts - opts = {} - } - - opts = Object.assign({}, opts, { preload: false }) - - return self.dag.get(cid, path, opts, cb) - }), - put: promisify((node, opts, cb) => { - if (typeof opts === 'function') { - cb = opts - opts = {} - } - - opts = Object.assign({}, opts, { preload: false }) - - return self.dag.put(node, opts, cb) - }) - }) - - return mfs(mfsSelf, mfsSelf._options) -} diff --git a/src/core/index.js b/src/core/index.js index 034a8a494f..5ba48d0425 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -137,6 +137,7 @@ class IPFS extends EventEmitter { this.shutdown = this.stop this.isOnline = components.isOnline(this) // - interface-ipfs-core defined API + Object.assign(this, components.filesRegular(this)) this.version = components.version(this) this.id = components.id(this) this.repo = components.repo(this) @@ -145,9 +146,9 @@ class IPFS extends EventEmitter { this.block = components.block(this) this.object = components.object(this) this.dag = components.dag(this) + this.files = components.filesMFS(this) this.libp2p = components.libp2p(this) this.swarm = components.swarm(this) - this.files = components.files(this) this.name = components.name(this) this.bitswap = components.bitswap(this) this.pin = components.pin(this) @@ -173,24 +174,12 @@ class IPFS extends EventEmitter { this.state = require('./state')(this) - // ipfs.ls - this.ls = this.files.lsImmutable - this.lsReadableStream = this.files.lsReadableStreamImmutable - this.lsPullStream = this.files.lsPullStreamImmutable - // ipfs.util this.util = { - crypto: crypto, - isIPFS: isIPFS + crypto, + isIPFS } - // ipfs.files - const mfs = components.mfs(this) - - Object.keys(mfs).forEach(key => { - this.files[key] = mfs[key] - }) - boot(this) } } diff --git a/src/http/api/resources/files.js b/src/http/api/resources/files-regular.js similarity index 98% rename from src/http/api/resources/files.js rename to src/http/api/resources/files-regular.js index 939ac25df3..1a02fab3d1 100644 --- a/src/http/api/resources/files.js +++ b/src/http/api/resources/files-regular.js @@ -79,7 +79,7 @@ exports.cat = { const options = request.pre.args.options const ipfs = request.server.app.ipfs - ipfs.files.cat(key, options, (err, stream) => { + ipfs.cat(key, options, (err, stream) => { if (err) { log.error(err) if (err.message === 'No such file') { @@ -113,7 +113,7 @@ exports.get = { const ipfs = request.server.app.ipfs const pack = tar.pack() - ipfs.files.get(cid, (err, filesArray) => { + ipfs.get(cid, (err, filesArray) => { if (err) { log.error(err) pack.emit('error', err) @@ -258,7 +258,7 @@ exports.add = { pull( fileAdder, - ipfs.files.addPullStream(options), + ipfs.addPullStream(options), pull.map((file) => { return { Name: file.path, // addPullStream already turned this into a hash if it wanted to @@ -282,7 +282,7 @@ exports.add = { } } -exports.immutableLs = { +exports.ls = { // uses common parseKey method that returns a `key` parseArgs: exports.parseKey, diff --git a/src/http/api/resources/index.js b/src/http/api/resources/index.js index 58b68962cf..66646d29d5 100644 --- a/src/http/api/resources/index.js +++ b/src/http/api/resources/index.js @@ -13,7 +13,7 @@ exports.block = require('./block') exports.swarm = require('./swarm') exports.bitswap = require('./bitswap') exports.file = require('./file') -exports.files = require('./files') +exports.filesRegular = require('./files-regular') exports.pubsub = require('./pubsub') exports.dns = require('./dns') exports.key = require('./key') diff --git a/src/http/api/routes/files.js b/src/http/api/routes/files.js index 44b00f9fa8..2e51ca7b0c 100644 --- a/src/http/api/routes/files.js +++ b/src/http/api/routes/files.js @@ -12,9 +12,9 @@ module.exports = (server) => { path: '/api/v0/cat', config: { pre: [ - { method: resources.files.cat.parseArgs, assign: 'args' } + { method: resources.filesRegular.cat.parseArgs, assign: 'args' } ], - handler: resources.files.cat.handler + handler: resources.filesRegular.cat.handler } }) @@ -24,9 +24,9 @@ module.exports = (server) => { path: '/api/v0/get', config: { pre: [ - { method: resources.files.get.parseArgs, assign: 'args' } + { method: resources.filesRegular.get.parseArgs, assign: 'args' } ], - handler: resources.files.get.handler + handler: resources.filesRegular.get.handler } }) @@ -40,8 +40,8 @@ module.exports = (server) => { output: 'stream', maxBytes: Number.MAX_SAFE_INTEGER }, - handler: resources.files.add.handler, - validate: resources.files.add.validate + handler: resources.filesRegular.add.handler, + validate: resources.filesRegular.add.validate } }) @@ -51,9 +51,9 @@ module.exports = (server) => { path: '/api/v0/ls', config: { pre: [ - { method: resources.files.immutableLs.parseArgs, assign: 'args' } + { method: resources.filesRegular.ls.parseArgs, assign: 'args' } ], - handler: resources.files.immutableLs.handler + handler: resources.filesRegular.ls.handler } }) diff --git a/src/http/gateway/resources/gateway.js b/src/http/gateway/resources/gateway.js index 4b6df5977f..4f6cc67b8c 100644 --- a/src/http/gateway/resources/gateway.js +++ b/src/http/gateway/resources/gateway.js @@ -94,7 +94,7 @@ module.exports = { return handleGatewayResolverError(err) } - const stream = ipfs.files.catReadableStream(data.multihash) + const stream = ipfs.catReadableStream(data.multihash) stream.once('error', (err) => { if (err) { log.error(err) diff --git a/test/cli/init.js b/test/cli/init.js index b1a826c1db..c8bcf61765 100644 --- a/test/cli/init.js +++ b/test/cli/init.js @@ -41,7 +41,7 @@ describe('init', function () { expect(repoExistsSync('version')).to.equal(true) // Test that the following was written when init-ing the repo - // jsipfs files cat /ipfs/QmfGBRT6BbWJd7yUc2uYdaUZJBbnEFvTqehPFoSMQ6wgdr/readme + // jsipfs cat /ipfs/QmfGBRT6BbWJd7yUc2uYdaUZJBbnEFvTqehPFoSMQ6wgdr/readme let command = out.substring(out.indexOf('cat'), out.length - 2 /* omit the newline char */) return ipfs(command) }).then((out) => expect(out).to.equal(readme)) diff --git a/test/core/bitswap.spec.js b/test/core/bitswap.spec.js index 5c0ce9f976..9540aba53e 100644 --- a/test/core/bitswap.spec.js +++ b/test/core/bitswap.spec.js @@ -228,10 +228,10 @@ describe('bitswap', function () { (cb) => addNode(fDaemon, inProcNode, cb), // 1. Add file to tmp instance (remote, cb) => { - remote.files.add([{ path: 'awesome.txt', content: file }], cb) + remote.add([{ path: 'awesome.txt', content: file }], cb) }, // 2. Request file from local instance - (filesAdded, cb) => inProcNode.files.cat(filesAdded[0].hash, cb) + (filesAdded, cb) => inProcNode.cat(filesAdded[0].hash, cb) ], (err, data) => { expect(err).to.not.exist() expect(data).to.eql(file) diff --git a/test/core/circuit-relay.js b/test/core/circuit-relay.js index 709b24188c..1566ce04b1 100644 --- a/test/core/circuit-relay.js +++ b/test/core/circuit-relay.js @@ -118,8 +118,8 @@ describe('circuit relay', () => { it('should transfer', function (done) { const data = crypto.randomBytes(128) waterfall([ - (cb) => nodeA.files.add(data, cb), - (res, cb) => nodeB.files.cat(res[0].hash, cb), + (cb) => nodeA.add(data, cb), + (res, cb) => nodeB.cat(res[0].hash, cb), (buffer, cb) => { expect(buffer).to.deep.equal(data) cb() diff --git a/test/core/files-sharding.spec.js b/test/core/files-sharding.spec.js index 8c96f00aa4..01d014c4f7 100644 --- a/test/core/files-sharding.spec.js +++ b/test/core/files-sharding.spec.js @@ -66,7 +66,7 @@ describe('files directory (sharding tests)', () => { pull( pull.values(createTestFiles()), - ipfs.files.addPullStream(), + ipfs.addPullStream(), pull.collect((err, results) => { expect(err).to.not.exist() const last = results[results.length - 1] @@ -118,7 +118,7 @@ describe('files directory (sharding tests)', () => { pull( pull.values(createTestFiles()), - ipfs.files.addPullStream(), + ipfs.addPullStream(), pull.collect((err, results) => { expect(err).to.not.exist() const last = results[results.length - 1] diff --git a/test/core/files.spec.js b/test/core/files.spec.js index 033058a809..77f99739ca 100644 --- a/test/core/files.spec.js +++ b/test/core/files.spec.js @@ -42,7 +42,7 @@ describe('files', () => { describe('get', () => { it('should callback with error for invalid IPFS path input', (done) => { const invalidPath = null - ipfs.files.get(invalidPath, (err) => { + ipfs.get(invalidPath, (err) => { expect(err).to.exist() expect(err.code).to.equal('ERR_INVALID_PATH') done() @@ -53,7 +53,7 @@ describe('files', () => { describe('getReadableStream', () => { it('should return erroring stream for invalid IPFS path input', (done) => { const invalidPath = null - const stream = ipfs.files.getReadableStream(invalidPath) + const stream = ipfs.getReadableStream(invalidPath) stream.on('error', (err) => { expect(err).to.exist() @@ -67,7 +67,7 @@ describe('files', () => { it('should return erroring stream for invalid IPFS path input', (done) => { const invalidPath = null pull( - ipfs.files.getPullStream(invalidPath), + ipfs.getPullStream(invalidPath), pull.collect((err) => { expect(err).to.exist() expect(err.code).to.equal('ERR_INVALID_PATH') @@ -79,14 +79,14 @@ describe('files', () => { describe('add', () => { it('should not error when passed null options', (done) => { - ipfs.files.add(Buffer.from(hat()), null, (err) => { + ipfs.add(Buffer.from(hat()), null, (err) => { expect(err).to.not.exist() done() }) }) it('should add a file with a v1 CID', (done) => { - ipfs.files.add(Buffer.from([0, 1, 2]), { + ipfs.add(Buffer.from([0, 1, 2]), { cidVersion: 1 }, (err, files) => { expect(err).to.not.exist() @@ -98,7 +98,7 @@ describe('files', () => { }) it('should add a file with a v1 CID and not raw leaves', (done) => { - ipfs.files.add(Buffer.from([0, 1, 2]), { + ipfs.add(Buffer.from([0, 1, 2]), { cidVersion: 1, rawLeaves: false }, (err, files) => { diff --git a/test/core/interface.spec.js b/test/core/interface.spec.js index fb5c964c17..6fde7915c9 100644 --- a/test/core/interface.spec.js +++ b/test/core/interface.spec.js @@ -78,7 +78,21 @@ describe('interface-ipfs-core tests', () => { ] : true }) - tests.files(defaultCommonFactory) + tests.filesRegular(defaultCommonFactory, { + skip: [{ + name: 'addFromStream', + reason: 'TODO: not implemented yet' + }, { + name: 'addFromFs', + reason: 'TODO: not implemented yet' + }, { + name: 'addFromUrl', + reason: 'TODO: not implemented yet' + }] + }) + + // TODO needs MFS module to be updated + // tests.filesMFS(defaultCommonFactory) tests.key(CommonFactory.create({ spawnOptions: { @@ -87,8 +101,6 @@ describe('interface-ipfs-core tests', () => { } })) - tests.ls(defaultCommonFactory) - tests.miscellaneous(CommonFactory.create({ // No need to stop, because the test suite does a 'stop' test. createTeardown: () => cb => cb() diff --git a/test/core/kad-dht.node.js b/test/core/kad-dht.node.js index 2670a6f846..1f1f484ae6 100644 --- a/test/core/kad-dht.node.js +++ b/test/core/kad-dht.node.js @@ -78,10 +78,10 @@ describe.skip('verify that kad-dht is doing its thing', () => { content: Buffer.from('hello kad') } - nodeC.files.add(file, (err, filesAdded) => { + nodeC.add(file, (err, filesAdded) => { expect(err).to.not.exist() - nodeA.files.cat(filesAdded[0].hash, (err, data) => { + nodeA.cat(filesAdded[0].hash, (err, data) => { expect(err).to.not.exist() expect(data.length).to.equal(file.data.length) expect(data).to.eql(file.data) diff --git a/test/core/name.js b/test/core/name.js index 3bab36ece0..208b0d6925 100644 --- a/test/core/name.js +++ b/test/core/name.js @@ -188,7 +188,7 @@ describe('ipns.path', function () { after((done) => ipfsd.stop(done)) it('should resolve an ipfs path correctly', function (done) { - node.files.add(fixture, (err, res) => { + node.add(fixture, (err, res) => { expect(err).to.not.exist() ipnsPath.resolvePath(node, `/ipfs/${res[0].hash}`, (err, value) => { expect(err).to.not.exist() @@ -199,7 +199,7 @@ describe('ipns.path', function () { }) it('should resolve an ipns path correctly', function (done) { - node.files.add(fixture, (err, res) => { + node.add(fixture, (err, res) => { expect(err).to.not.exist() node.name.publish(`/ipfs/${res[0].hash}`, (err, res) => { expect(err).to.not.exist() diff --git a/test/core/pin.js b/test/core/pin.js index f99ded2548..8c3fb90326 100644 --- a/test/core/pin.js +++ b/test/core/pin.js @@ -77,7 +77,7 @@ describe('pin', function () { ipfs = new IPFS({ repo }) ipfs.on('ready', () => { pin = ipfs.pin - ipfs.files.add(fixtures, done) + ipfs.add(fixtures, done) }) }) diff --git a/test/core/preload.spec.js b/test/core/preload.spec.js index 37528b81fe..27dc63e35d 100644 --- a/test/core/preload.spec.js +++ b/test/core/preload.spec.js @@ -45,15 +45,15 @@ describe('preload', () => { after((done) => repo.teardown(done)) - it('should preload content added with files.add', (done) => { - ipfs.files.add(Buffer.from(hat()), (err, res) => { + it('should preload content added with add', (done) => { + ipfs.add(Buffer.from(hat()), (err, res) => { expect(err).to.not.exist() MockPreloadNode.waitForCids(res[0].hash, done) }) }) - it('should preload multiple content added with files.add', (done) => { - ipfs.files.add([{ + it('should preload multiple content added with add', (done) => { + ipfs.add([{ content: Buffer.from(hat()) }, { content: Buffer.from(hat()) @@ -65,8 +65,8 @@ describe('preload', () => { }) }) - it('should preload multiple content and intermediate dirs added with files.add', (done) => { - ipfs.files.add([{ + it('should preload multiple content and intermediate dirs added with add', (done) => { + ipfs.add([{ path: 'dir0/dir1/file0', content: Buffer.from(hat()) }, { @@ -85,8 +85,8 @@ describe('preload', () => { }) }) - it('should preload multiple content and wrapping dir for content added with files.add and wrapWithDirectory option', (done) => { - ipfs.files.add([{ + it('should preload multiple content and wrapping dir for content added with add and wrapWithDirectory option', (done) => { + ipfs.add([{ path: 'dir0/dir1/file0', content: Buffer.from(hat()) }, { @@ -105,20 +105,20 @@ describe('preload', () => { }) }) - it('should preload content retrieved with files.cat', (done) => { - ipfs.files.add(Buffer.from(hat()), { preload: false }, (err, res) => { + it('should preload content retrieved with cat', (done) => { + ipfs.add(Buffer.from(hat()), { preload: false }, (err, res) => { expect(err).to.not.exist() - ipfs.files.cat(res[0].hash, (err) => { + ipfs.cat(res[0].hash, (err) => { expect(err).to.not.exist() MockPreloadNode.waitForCids(res[0].hash, done) }) }) }) - it('should preload content retrieved with files.get', (done) => { - ipfs.files.add(Buffer.from(hat()), { preload: false }, (err, res) => { + it('should preload content retrieved with get', (done) => { + ipfs.add(Buffer.from(hat()), { preload: false }, (err, res) => { expect(err).to.not.exist() - ipfs.files.get(res[0].hash, (err) => { + ipfs.get(res[0].hash, (err) => { expect(err).to.not.exist() MockPreloadNode.waitForCids(res[0].hash, done) }) @@ -126,7 +126,7 @@ describe('preload', () => { }) it('should preload content retrieved with ls', (done) => { - ipfs.files.add([{ + ipfs.add([{ path: 'dir0/dir1/file0', content: Buffer.from(hat()) }, { @@ -332,7 +332,7 @@ describe('preload disabled', () => { after((done) => repo.teardown(done)) it('should not preload if disabled', (done) => { - ipfs.files.add(Buffer.from(hat()), (err, res) => { + ipfs.add(Buffer.from(hat()), (err, res) => { expect(err).to.not.exist() MockPreloadNode.waitForCids(res[0].hash, (err) => { diff --git a/test/core/utils.js b/test/core/utils.js index 49bd7f19fc..1ad815e926 100644 --- a/test/core/utils.js +++ b/test/core/utils.js @@ -122,7 +122,7 @@ describe('utils', () => { node = new IPFS({ repo: repo }) - node.once('ready', () => node.files.add(fixtures, done)) + node.once('ready', () => node.add(fixtures, done)) }) after(done => node.stop(done)) diff --git a/test/gateway/index.js b/test/gateway/index.js index 837261be84..952b0d3a82 100644 --- a/test/gateway/index.js +++ b/test/gateway/index.js @@ -70,7 +70,7 @@ describe('HTTP Gateway', function () { emptyDir('nested-folder/empty') ] - http.api.node.files.add(dirs, (err, res) => { + http.api.node.add(dirs, (err, res) => { expect(err).to.not.exist() const root = res[res.length - 1] @@ -82,7 +82,7 @@ describe('HTTP Gateway', function () { (cb) => { const expectedMultihash = 'Qme79tX2bViL26vNjPsF3DP1R9rMKMvnPYJiKTTKPrXJjq' - http.api.node.files.add(bigFile, (err, res) => { + http.api.node.add(bigFile, (err, res) => { expect(err).to.not.exist() const file = res[0] expect(file.path).to.equal(expectedMultihash) @@ -93,7 +93,7 @@ describe('HTTP Gateway', function () { (cb) => { const expectedMultihash = 'QmT78zSuBmuS4z925WZfrqQ1qHaJ56DQaTfyMUF7F8ff5o' - http.api.node.files.add(Buffer.from('hello world' + '\n'), { cidVersion: 0 }, (err, res) => { + http.api.node.add(Buffer.from('hello world' + '\n'), { cidVersion: 0 }, (err, res) => { expect(err).to.not.exist() const file = res[0] expect(file.path).to.equal(expectedMultihash) @@ -108,7 +108,7 @@ describe('HTTP Gateway', function () { content('cat-folder/cat.jpg') ] - http.api.node.files.add(dir, (err, res) => { + http.api.node.add(dir, (err, res) => { expect(err).to.not.exist() const file = res[1] expect(file.path).to.equal('test-folder/cat-folder') @@ -124,7 +124,7 @@ describe('HTTP Gateway', function () { content('unsniffable-folder/hexagons.svg') ] - http.api.node.files.add(dir, (err, res) => { + http.api.node.add(dir, (err, res) => { expect(err).to.not.exist() const file = res[res.length - 2] expect(file.path).to.equal('test-folder/unsniffable-folder') diff --git a/test/http-api/interface.js b/test/http-api/interface.js index 00a1743482..314cab9dec 100644 --- a/test/http-api/interface.js +++ b/test/http-api/interface.js @@ -25,7 +25,9 @@ describe('interface-ipfs-core over ipfs-api tests', () => { skip: { reason: 'TODO: DHT is not implemented in js-ipfs yet!' } }) - tests.files(defaultCommonFactory) + tests.filesRegular(defaultCommonFactory) + + tests.filesMFS(defaultCommonFactory) tests.key(CommonFactory.create({ spawnOptions: { diff --git a/test/utils/ipfs-exec.js b/test/utils/ipfs-exec.js index 786a3f7f3b..52b6e6ed1f 100644 --- a/test/utils/ipfs-exec.js +++ b/test/utils/ipfs-exec.js @@ -13,7 +13,7 @@ const _ = require('lodash') // The top level export is a function that can be passed a `repoPath` // and optional `opts` to customize the execution of the commands. // This function returns the actual executer, which consists of -// `ipfs('get ')` and `ipfs.fail('files get ')` +// `ipfs('get ')` and `ipfs.fail('get ')` // The first one executes and asserts that the command ran successfully // and returns a promise which is resolved to `stdout` of the command. // The `.fail` variation asserts that the command exited with `Code > 0`