From cbbb1eb9021f7c396572670f3e1c59a0c6f513df Mon Sep 17 00:00:00 2001 From: AdmREQ Date: Tue, 7 Aug 2018 08:40:09 +0100 Subject: [PATCH 1/2] Merged latest IPFS code into Request timeout fork. --- .aegir.js | 7 +- CHANGELOG.md | 156 +++++++++ README.md | 306 ++++++++++-------- examples/bundle-browserify/package.json | 2 +- examples/bundle-webpack/package.json | 4 +- examples/name-api/package.json | 2 +- examples/sub-module/package.json | 2 +- examples/upload-file-via-browser/package.json | 3 +- .../upload-file-via-browser/webpack.config.js | 4 +- package.json | 71 ++-- src/bitswap/unwant.js | 12 +- src/bitswap/wantlist.js | 23 +- src/block/get.js | 7 + src/config/get.js | 16 +- src/config/set.js | 4 +- src/dag/put.js | 66 ++-- src/files/cp.js | 17 +- src/files/flush.js | 2 +- src/files/index.js | 2 + src/files/ls.js | 7 + src/files/mkdir.js | 2 +- src/files/mv.js | 18 +- src/files/read-pull-stream.js | 26 ++ src/files/read-readable-stream.js | 26 ++ src/files/rm.js | 2 +- src/ping-pull-stream.js | 7 +- src/ping-readable-stream.js | 15 +- src/ping.js | 30 +- src/pubsub.js | 67 +++- src/swarm/peers.js | 38 +-- src/util/url-add.js | 3 +- src/utils/find-sources.js | 25 ++ src/utils/ping-message-converter.js | 23 ++ src/utils/ping-message-stream.js | 27 ++ src/utils/send-request.js | 10 +- test/commands.spec.js | 5 +- test/constructor.spec.js | 15 +- test/custom-headers.spec.js | 61 ++++ test/diag.spec.js | 5 +- test/files.spec.js | 157 ++++++--- test/get.spec.js | 7 +- test/interface.spec.js | 248 ++++++++++++++ test/key.spec.js | 5 +- test/log.spec.js | 5 +- test/name.spec.js | 44 ++- test/ping.spec.js | 101 +++--- test/pubsub-in-browser.spec.js | 16 +- test/refs.spec.js | 5 +- test/repo.spec.js | 5 +- test/stats.spec.js | 5 +- test/types.spec.js | 5 +- test/util.spec.js | 39 ++- test/utils/interface-common-factory.js | 49 +++ 53 files changed, 1393 insertions(+), 416 deletions(-) create mode 100644 src/files/read-pull-stream.js create mode 100644 src/files/read-readable-stream.js create mode 100644 src/utils/find-sources.js create mode 100644 src/utils/ping-message-converter.js create mode 100644 src/utils/ping-message-stream.js create mode 100644 test/custom-headers.spec.js create mode 100644 test/interface.spec.js create mode 100644 test/utils/interface-common-factory.js diff --git a/.aegir.js b/.aegir.js index f7a4806f3..bbe8a75e9 100644 --- a/.aegir.js +++ b/.aegir.js @@ -5,6 +5,11 @@ const createServer = require('ipfsd-ctl').createServer const server = createServer() module.exports = { + webpack: { + resolve: { + mainFields: ['browser', 'main'] + } + }, karma: { files: [{ pattern: 'node_modules/interface-ipfs-core/js/test/fixtures/**/*', @@ -12,7 +17,7 @@ module.exports = { served: true, included: false }], - browserNoActivityTimeout: 150 * 1000, + browserNoActivityTimeout: 210 * 1000, singleRun: true }, hooks: { diff --git a/CHANGELOG.md b/CHANGELOG.md index 002714fde..cabf56988 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,159 @@ + +# [22.3.0](https://github.com/ipfs/js-ipfs-api/compare/v22.2.4...v22.3.0) (2018-08-02) + + +### Bug Fixes + +* config.set rejects buffer values ([#800](https://github.com/ipfs/js-ipfs-api/issues/800)) ([f3e6bf1](https://github.com/ipfs/js-ipfs-api/commit/f3e6bf1)) + + +### Features + +* compatible with go-ipfs 0.4.16 ([8536ee4](https://github.com/ipfs/js-ipfs-api/commit/8536ee4)) +* expose mfs files.read*Stream methods ([#823](https://github.com/ipfs/js-ipfs-api/issues/823)) ([70c9df1](https://github.com/ipfs/js-ipfs-api/commit/70c9df1)) + + + + +## [22.2.4](https://github.com/ipfs/js-ipfs-api/compare/v22.2.3...v22.2.4) (2018-07-17) + + +### Bug Fixes + +* increase browserNoActivityTimeout to account for before ([328e338](https://github.com/ipfs/js-ipfs-api/commit/328e338)) +* increase timeout for .name after all ([3dc4313](https://github.com/ipfs/js-ipfs-api/commit/3dc4313)) +* missing debug dependency fixes [#809](https://github.com/ipfs/js-ipfs-api/issues/809) ([#810](https://github.com/ipfs/js-ipfs-api/issues/810)) ([0f1fe95](https://github.com/ipfs/js-ipfs-api/commit/0f1fe95)) + + + + +## [22.2.3](https://github.com/ipfs/js-ipfs-api/compare/v22.2.2...v22.2.3) (2018-07-10) + + +### Bug Fixes + +* Request logging broken in Electron ([#808](https://github.com/ipfs/js-ipfs-api/issues/808)) ([52298ae](https://github.com/ipfs/js-ipfs-api/commit/52298ae)) + + + + +## [22.2.2](https://github.com/ipfs/js-ipfs-api/compare/v22.2.1...v22.2.2) (2018-07-05) + + +### Bug Fixes + +* ignore response body for some mfs commands ([#805](https://github.com/ipfs/js-ipfs-api/issues/805)) ([b604a64](https://github.com/ipfs/js-ipfs-api/commit/b604a64)) + + +### Features + +* modular interface tests ([#785](https://github.com/ipfs/js-ipfs-api/issues/785)) ([2426072](https://github.com/ipfs/js-ipfs-api/commit/2426072)), closes [#339](https://github.com/ipfs/js-ipfs-api/issues/339) [#802](https://github.com/ipfs/js-ipfs-api/issues/802) [#801](https://github.com/ipfs/js-ipfs-api/issues/801) + + + + +## [22.2.1](https://github.com/ipfs/js-ipfs-api/compare/v22.2.0...v22.2.1) (2018-06-29) + + +### Bug Fixes + +* res.req only in Node.js, in browser use res.url instead ([#798](https://github.com/ipfs/js-ipfs-api/issues/798)) ([e8a5ab9](https://github.com/ipfs/js-ipfs-api/commit/e8a5ab9)) + + + + +# [22.2.0](https://github.com/ipfs/js-ipfs-api/compare/v22.1.1...v22.2.0) (2018-06-29) + + +### Features + +* logs path & querystring for requests ([#796](https://github.com/ipfs/js-ipfs-api/issues/796)) ([4e55d19](https://github.com/ipfs/js-ipfs-api/commit/4e55d19)) + + + + +## [22.1.1](https://github.com/ipfs/js-ipfs-api/compare/v22.1.0...v22.1.1) (2018-06-25) + + +### Bug Fixes + +* get block with empty data ([#789](https://github.com/ipfs/js-ipfs-api/issues/789)) ([88edd83](https://github.com/ipfs/js-ipfs-api/commit/88edd83)) + + + + +# [22.1.0](https://github.com/ipfs/js-ipfs-api/compare/v22.0.2...v22.1.0) (2018-06-18) + + +### Features + +* add support for custom headers to send-request ([#741](https://github.com/ipfs/js-ipfs-api/issues/741)) ([7fb2e07](https://github.com/ipfs/js-ipfs-api/commit/7fb2e07)) +* implement bitswap wantlist peer ID param and bitswap unwant ([#761](https://github.com/ipfs/js-ipfs-api/issues/761)) ([73a153e](https://github.com/ipfs/js-ipfs-api/commit/73a153e)) + + + + +## [22.0.2](https://github.com/ipfs/js-ipfs-api/compare/v22.0.1...v22.0.2) (2018-06-14) + + +### Bug Fixes + +* json-loader error in upload-file-via-browser example ([#784](https://github.com/ipfs/js-ipfs-api/issues/784)) ([5e7b7c4](https://github.com/ipfs/js-ipfs-api/commit/5e7b7c4)) + + + + +## [22.0.1](https://github.com/ipfs/js-ipfs-api/compare/v22.0.0...v22.0.1) (2018-05-30) + + +### Bug Fixes + +* configure webpack to not use esmodules in dependencies ([dc14333](https://github.com/ipfs/js-ipfs-api/commit/dc14333)) +* correctly differentiate pong responses ([4ad25a3](https://github.com/ipfs/js-ipfs-api/commit/4ad25a3)) +* util.addFromURL with URL-escaped file ([a3bd811](https://github.com/ipfs/js-ipfs-api/commit/a3bd811)) + + + + +# [22.0.0](https://github.com/ipfs/js-ipfs-api/compare/v21.0.0...v22.0.0) (2018-05-20) + + +### Bug Fixes + +* callback from unsub after stream ends ([51a80f2](https://github.com/ipfs/js-ipfs-api/commit/51a80f2)) +* do not fail stop node if failed start node ([533760f](https://github.com/ipfs/js-ipfs-api/commit/533760f)) +* **ping:** convert the ping messages to lowercase ([632af40](https://github.com/ipfs/js-ipfs-api/commit/632af40)) +* more robust ping tests ([fc6d301](https://github.com/ipfs/js-ipfs-api/commit/fc6d301)) +* remove .only ([0e21c8a](https://github.com/ipfs/js-ipfs-api/commit/0e21c8a)) +* result.Peers can be null, ensure callback is called ([f5f2e83](https://github.com/ipfs/js-ipfs-api/commit/f5f2e83)) +* update asserted error message ([17c1f1c](https://github.com/ipfs/js-ipfs-api/commit/17c1f1c)) +* use async/setImmediate vs process.nextTick ([faa51b4](https://github.com/ipfs/js-ipfs-api/commit/faa51b4)) + + + + +# [21.0.0](https://github.com/ipfs/js-ipfs-api/compare/v20.2.1...v21.0.0) (2018-05-12) + + +### Bug Fixes + +* make pubsub.unsubscribe async and alter pubsub.subscribe signature ([b98f8f3](https://github.com/ipfs/js-ipfs-api/commit/b98f8f3)) + + +### BREAKING CHANGES + +* pubsub.unsubscribe is now async and argument order for pubsub.subscribe has changed + +License: MIT +Signed-off-by: Alan Shaw + + + + +## [20.2.1](https://github.com/ipfs/js-ipfs-api/compare/v20.2.0...v20.2.1) (2018-05-06) + + + # [20.2.0](https://github.com/ipfs/js-ipfs-api/compare/v20.0.1...v20.2.0) (2018-04-30) diff --git a/README.md b/README.md index 7c1cc362d..4492bb695 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,10 @@ > A client library for the IPFS HTTP API, implemented in JavaScript. This client library implements the [interface-ipfs-core](https://github.com/ipfs/interface-ipfs-core) enabling applications to change between a embebed js-ipfs node and any remote IPFS node without having to change the code. In addition, this client library implements a set of utility functions. +## Lead Maintainer + +[Alan Shaw](http://github.com/alanshaw). + ## Table of Contents - [Install](#install) @@ -48,7 +52,7 @@ This module uses node.js, and can be installed through npm: ```bash -> npm install --save ipfs-api +npm install --save ipfs-api ``` **Note:** ipfs-api requires Node.js v6 (LTS) or higher. @@ -82,14 +86,19 @@ var ipfs = ipfsAPI('/ip4/127.0.0.1/tcp/5001') // or using options var ipfs = ipfsAPI({host: 'localhost', port: '5001', protocol: 'http'}) + +// or specifying a specific API path +var ipfs = ipfsAPI({host: '1.1.1.1', port: '80', 'api-path': '/ipfs/api/v0'}) ``` + ### Importing a sub-module and usage + ```javascript const bitswap = require('ipfs-api/src/bitswap')('/ip4/127.0.0.1/tcp/5001') bitswap.unwant(key, (err) => { // ... -} +}) ``` ### In a web browser through Browserify @@ -100,7 +109,7 @@ See the example in the [examples folder](/examples/bundle-browserify) to get a b ### In a web browser through webpack -See the example in the [examples folder](/examples/bundle-webpack) to get an idea on how to use js-ipfs-api with webpack +See the example in the [examples folder](/examples/bundle-webpack) to get an idea on how to use js-ipfs-api with webpack. ### In a web browser from CDN @@ -109,15 +118,17 @@ Instead of a local installation (and browserification) you may request a remo To always request the latest version, use the following: ```html + + + + ``` For maximum security you may also decide to: * reference a specific version of IPFS API (to prevent unexpected breaking changes when a newer latest version is published) - * [generate a SRI hash](https://www.srihash.org/) of that version and use it to ensure integrity - * set the [CORS settings attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) to make anonymous requests to CDN Example: @@ -130,13 +141,13 @@ crossorigin="anonymous"> CDN-based IPFS API provides the `IpfsApi` constructor as a method of the global `window` object. Example: -``` +```js var ipfs = window.IpfsApi('localhost', '5001') ``` If you omit the host and port, the API will parse `window.host`, and use this information. This also works, and can be useful if you want to write apps that can be run from multiple different gateways: -``` +```js var ipfs = window.IpfsApi() ``` @@ -145,150 +156,174 @@ var ipfs = window.IpfsApi() In a web browser IPFS API (either browserified or CDN-based) might encounter an error saying that the origin is not allowed. This would be a CORS ("Cross Origin Resource Sharing") failure: IPFS servers are designed to reject requests from unknown domains by default. You can whitelist the domain that you are calling from by changing your ipfs config like this: ```bash -$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin "[\"http://example.com\"]" -$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials "[\"true\"]" -$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods "[\"PUT\", \"POST\", \"GET\"]" +ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin "[\"http://example.com\"]" +ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials "[\"true\"]" +ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods "[\"PUT\", \"POST\", \"GET\"]" +``` + +### Custom Headers + +If you wish to send custom headers with each request made by this library, for example, the Authorization header. You can use the config to do so: + +``` +const ipfs = IpfsApi({ + host: 'localhost', + port: 5001, + protocol: 'http', + headers: { + authorization: 'Bearer ' + TOKEN + } +}) ``` ## Usage ### API -[![](https://github.com/ipfs/interface-ipfs-core/raw/master/img/badge.png)](https://github.com/ipfs/interface-ipfs-core) +[![IPFS Core API Compatible](https://cdn.rawgit.com/ipfs/interface-ipfs-core/master/img/badge.svg)](https://github.com/ipfs/interface-ipfs-core) > `js-ipfs-api` follows the spec defined by [`interface-ipfs-core`](https://github.com/ipfs/interface-ipfs-core), which concerns the interface to expect from IPFS implementations. This interface is a currently active endeavor. You can use it today to consult the methods available. -#### `Files` +#### 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/tree/master/SPEC/FILES.md#add). Alias to `ipfs.add`. - - [`ipfs.files.addReadableStream([options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#addreadablestream) - - [`ipfs.files.addPullStream([options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#addpullstream) - - [`ipfs.files.cat(ipfsPath, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#cat). Alias to `ipfs.cat`. - - [`ipfs.files.catReadableStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#catreadablestream) - - [`ipfs.files.catPullStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#catpullstream) - - [`ipfs.files.get(ipfsPath, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#get). Alias to `ipfs.get`. - - [`ipfs.files.getReadableStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#getreadablestream) - - [`ipfs.files.getPullStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#getpullstream) + - [`ipfs.files.add(data, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesadd). Alias to `ipfs.add`. + - [`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). Alias to `ipfs.cat`. + - [`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). Alias to `ipfs.get`. + - [`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) - [`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/tree/master/SPEC/FILES.md#cp) - - [`ipfs.files.mkdir(path, [options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#mkdir) - - [`ipfs.files.stat(path, [options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#stat) - - [`ipfs.files.rm(path, [options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#rm) - - [`ipfs.files.read(path, [options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#read) - - [`ipfs.files.write(path, content, [options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#write) - - [`ipfs.files.mv([from, to], [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#mv) - - [`ipfs.files.ls([path, options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#ls-1) - - [`ipfs.files.flush([path, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/FILES.md#flush) - -- [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#get) - - [`ipfs.block.put(block, cid, [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md#put) - - [`ipfs.block.stat(cid, [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/BLOCK.md#stat) - -#### `Graph` - -- [dag (not implemented, yet!)](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/DAG.md) - - [`ipfs.dag.put(dagNode, options, callback)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/DAG.md#dagput) - - [`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). - - [`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) - - [`ipfs.object.data(multihash, [options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectdata) - - [`ipfs.object.links(multihash, [options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectlinks) - - [`ipfs.object.stat(multihash, [options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectstat) - - [`ipfs.object.patch.addLink(multihash, DAGLink, [options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectpatchaddlink) - - [`ipfs.object.patch.rmLink(multihash, DAGLink, [options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/OBJECT.md#objectpatchrmlink) - - [`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/tree/master/SPEC/) - - [`ipfs.pin.add()`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PIN.md#add) - - [`ipfs.pin.rm()`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PIN.md#rm) - - [`ipfs.pin.ls()`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PIN.md#ls) -- [refs](https://github.com/ipfs/interface-ipfs-core/tree/master/API/refs) - - [`ipfs.refs.local()`](https://github.com/ipfs/interface-ipfs-core/tree/master/API/refs#local) - - -#### `Network` - -- [bootstrap](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/) - - `ipfs.bootstrap.list` - - `ipfs.bootstrap.add` - - `ipfs.bootstrap.rm` - -- [bitswap](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/) - - `ipfs.bitswap.wantlist()` - - `ipfs.bitswap.stat()` - - `ipfs.bitswap.unwant()` - -- [dht](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/) - - [`ipfs.dht.findprovs()`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/DHT.md#findprovs) - - [`ipfs.dht.get()`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/DHT.md#get) - - [`ipfs.dht.put()`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/DHT.md#put) - -- [pubsub](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PUBSUB.md) - - [`ipfs.pubsub.subscribe(topic, options, handler, callback)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PUBSUB.md#pubsubsubscribe) - - [`ipfs.pubsub.unsubscribe(topic, handler)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PUBSUB.md#pubsubunsubscribe) - - [`ipfs.pubsub.publish(topic, data, callback)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PUBSUB.md#pubsubpublish) - - [`ipfs.pubsub.ls(topic, callback)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PUBSUB.md#pubsubls) - - [`ipfs.pubsub.peers(topic, callback)`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/PUBSUB.md#pubsubpeers) - -- [swarm](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/SWARM.md) - - [`ipfs.swarm.addrs([callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/SWARM.md#addrs) - - [`ipfs.swarm.connect(addr, [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/SWARM.md#connect) - - [`ipfs.swarm.disconnect(addr, [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/SWARM.md#disconnect) - - [`ipfs.swarm.peers([opts] [, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/SWARM.md#peers) - -- [name](https://github.com/ipfs/interface-ipfs-core/tree/master/API/name) - - [`ipfs.name.publish(addr, [options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/NAME.md#publish) - - [`ipfs.name.resolve(addr, [options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/NAME.md#resolve) - -#### `Node Management` - -- [miscellaneous operations](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md) - - [`ipfs.id([callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md#id) - - [`ipfs.version([callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md#version) - - [`ipfs.ping(id, [options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md#ping) - - `ipfs.pingPullStream(id, [options])` - - `ipfs.pingReadableStream(id, [options])` - - [`ipfs.dns(domain, [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md#dns) - - [`ipfs.stop([callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/MISCELLANEOUS.md#stop). Alias to `ipfs.shutdown`. - -- [config](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/CONFIG.md) - - [`ipfs.config.get([key, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/CONFIG.md#configget) - - [`ipfs.config.set(key, value, [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/CONFIG.md#configset) - - [`ipfs.config.replace(config, [callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/CONFIG.md#configreplace) - -- [stats](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/STATS.md) - - [`ipfs.stats.bitswap([callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/STATS.md#bitswap) - - [`ipfs.stats.bw([options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/STATS.md#bw) - - [`ipfs.stats.repo([options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/STATS.md#repo) - + - [`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/blob/master/SPEC/BLOCK.md) + - [`ipfs.block.get(cid, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BLOCK.md#blockget) + - [`ipfs.block.put(block, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BLOCK.md#blockput) + - [`ipfs.block.stat(cid, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BLOCK.md#blockstat) + +#### Graph + +- [dag](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DAG.md) + - [`ipfs.dag.get(cid, [path], [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DAG.md#dagget) + - [`ipfs.dag.put(dagNode, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DAG.md#dagput) + - [`ipfs.dag.tree(cid, [path], [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DAG.md#dagtree) + +- [object](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md) + - [`ipfs.object.data(multihash, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectdata) + - [`ipfs.object.get(multihash, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectget) + - [`ipfs.object.links(multihash, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectlinks) + - [`ipfs.object.new([template], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectnew) + - [`ipfs.object.patch.addLink(multihash, DAGLink, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectpatchaddlink) + - [`ipfs.object.patch.appendData(multihash, data, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectpatchappenddata) + - [`ipfs.object.patch.rmLink(multihash, DAGLink, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectpatchrmlink) + - [`ipfs.object.patch.setData(multihash, data, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectpatchsetdata) + - [`ipfs.object.put(obj, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectput) + - [`ipfs.object.stat(multihash, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectstat) + +- [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) + +- refs + - `ipfs.refs.local()` + +#### Network + +- [bootstrap](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BOOTSTRAP.md) + - [`ipfs.bootstrap.add(addr, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BOOTSTRAP.md#bootstrapadd) + - [`ipfs.bootstrap.list([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BOOTSTRAP.md#bootstraplist) + - [`ipfs.bootstrap.rm(addr, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BOOTSTRAP.md#bootstraprm) + +- [bitswap](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BITSWAP.md) + - [`ipfs.bitswap.stat([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BITSWAP.md#bitswapstat) + - [`ipfs.bitswap.wantlist([peerId])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BITSWAP.md#bitswapwantlist) + - [`ipfs.bitswap.unwant(cid)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BITSWAP.md#bitswapunwant) + +- [dht](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md) + - [`ipfs.dht.findpeer(peerId, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtfindpeer) + - [`ipfs.dht.findprovs(hash, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtfindprovs) + - [`ipfs.dht.get(key, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtget) + - [`ipfs.dht.provide(cid, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtprovide) + - [`ipfs.dht.put(key, value, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtput) + +- [pubsub](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PUBSUB.md) + - [`ipfs.pubsub.ls(topic, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PUBSUB.md#pubsubls) + - [`ipfs.pubsub.peers(topic, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PUBSUB.md#pubsubpeers) + - [`ipfs.pubsub.publish(topic, data, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PUBSUB.md#pubsubpublish) + - [`ipfs.pubsub.subscribe(topic, handler, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PUBSUB.md#pubsubsubscribe) + - [`ipfs.pubsub.unsubscribe(topic, handler, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PUBSUB.md#pubsubunsubscribe) + +- [swarm](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/SWARM.md) + - [`ipfs.swarm.addrs([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/SWARM.md#swarmaddrs) + - [`ipfs.swarm.connect(addr, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/SWARM.md#swarmconnect) + - [`ipfs.swarm.disconnect(addr, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/SWARM.md#swarmdisconnect) + - [`ipfs.swarm.peers([options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/SWARM.md#swarmpeers) + +- [name](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md) + - [`ipfs.name.publish(addr, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#namepublish) + - [`ipfs.name.resolve(addr, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#nameresolve) + +#### Node Management + +- [miscellaneous operations](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/MISCELLANEOUS.md) + - [`ipfs.dns(domain, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/MISCELLANEOUS.md#dns) + - [`ipfs.id([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/MISCELLANEOUS.md#id) + - [`ipfs.ping(id, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/MISCELLANEOUS.md#ping) + - [`ipfs.pingPullStream(id, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/MISCELLANEOUS.md#pingpullstream) + - [`ipfs.pingReadableStream(id, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/MISCELLANEOUS.md#pingreadablestream) + - [`ipfs.stop([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/MISCELLANEOUS.md#stop). Alias to `ipfs.shutdown`. + - [`ipfs.version([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/MISCELLANEOUS.md#version) + +- [config](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/CONFIG.md) + - [`ipfs.config.get([key], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/CONFIG.md#configget) + - [`ipfs.config.replace(config, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/CONFIG.md#configreplace) + - [`ipfs.config.set(key, value, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/CONFIG.md#configset) + +- [stats](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/STATS.md) + - [`ipfs.stats.bitswap([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/STATS.md#statsbitswap) + - [`ipfs.stats.bw([options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/STATS.md#statsbw) + - [`ipfs.stats.bwPullStream([options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/STATS.md#statsbwpullstream) + - [`ipfs.stats.bwReadableStream([options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/STATS.md#statsbwreadablestream) + - [`ipfs.stats.repo([options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/STATS.md#statsrepo) + - log + - `ipfs.log.level(subsystem, level, [options], [callback])` - `ipfs.log.ls([callback])` - `ipfs.log.tail([callback])` - - `ipfs.log.level(subsystem, level, [options, callback])` -- [repo](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/REPO.md) - - [`ipfs.repo.gc([options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/REPO.md#gc) - - [`ipfs.repo.stat([options, callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/REPO.md#stat) - - [`ipfs.repo.version([callback])`](https://github.com/ipfs/interface-ipfs-core/tree/master/SPEC/REPO.md#version) - +- [repo](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REPO.md) + - [`ipfs.repo.gc([options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REPO.md#repogc) + - [`ipfs.repo.stat([options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REPO.md#repostat) + - [`ipfs.repo.version([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REPO.md#repoversion) + - [key](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md) - - [`ipfs.key.gen(name, options, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#javascript---ipfskeygenname-options-callback) - - [`ipfs.key.list([options, callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#javascript---ipfskeylistcallback) - - [`ipfs.key.rm(name, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#javascript---ipfskeyrmname-callback) - - [`ipfs.key.rename(oldName, newName, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#javascript---ipfskeyrenameoldname-newname-callback) - - [`ipfs.key.export(name, password, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#javascript---ipfskeyexportname-password-callback) - - [`ipfs.key.import(name, pem, password, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#javascript---ipfskeyimportname-pem-password-callback) + - [`ipfs.key.export(name, password, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyexport) + - [`ipfs.key.gen(name, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keygen) + - [`ipfs.key.import(name, pem, password, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyimport) + - [`ipfs.key.list([options, callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keylist) + - [`ipfs.key.rename(oldName, newName, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyrename) + - [`ipfs.key.rm(name, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyrm) -#### `Pubsub Caveat` +#### Pubsub Caveat -**Currently, the [PubSub API only works in Node.js envinroment](https://github.com/ipfs/js-ipfs-api/issues/518)** +**Currently, the [PubSub API only works in Node.js environment](https://github.com/ipfs/js-ipfs-api/issues/518)** We currently don't support pubsub when run in the browser, and we test it with separate set of tests to make sure if it's being used in the browser, pubsub errors. @@ -308,7 +343,7 @@ This means: - See https://github.com/ipfs/js-ipfs for details on pubsub in js-ipfs -#### `Domain data types` +#### Domain data types A set of data types are exposed directly from the IPFS instance under `ipfs.types`. That way you're not required to import/require the following. @@ -322,7 +357,7 @@ A set of data types are exposed directly from the IPFS instance under `ipfs.type - [`ipfs.types.dagPB`](https://github.com/ipld/js-ipld-dag-pb) - [`ipfs.types.dagCBOR`](https://github.com/ipld/js-ipld-dag-cbor) -#### `Utility functions` +#### Utility functions Adding to the methods defined by [`interface-ipfs-core`](https://github.com/ipfs/interface-ipfs-core), `js-ipfs-api` exposes a set of extra utility methods. These utility functions are scoped behind the `ipfs.util`. @@ -335,7 +370,7 @@ Complete documentation for these methods is coming with: https://github.com/ipfs Reads a file or folder from `path` on the filesystem and adds it to IPFS. Options: - **recursive**: If `path` is a directory, use option `{ recursive: true }` to add the directory and all its sub-directories. - **ignore**: To exclude fileglobs from the directory, use option `{ ignore: ['ignore/this/folder/**', 'and/this/file'] }`. - - **hidden**: hidden/dot files (files or folders starting with a `.`, for example, `.git/`) are not included by default. To add them, use the option `{ hidden: true }`. + - **hidden**: hidden/dot files (files or folders starting with a `.`, for example, `.git/`) are not included by default. To add them, use the option `{ hidden: true }`. ```JavaScript ipfs.util.addFromFs('path/to/a/folder', { recursive: true , ignore: ['subfolder/to/ignore/**']}, (err, result) => { @@ -346,7 +381,7 @@ ipfs.util.addFromFs('path/to/a/folder', { recursive: true , ignore: ['subfolder/ `result` is an array of objects describing the files that were added, such as: -``` +```js [ { path: 'test-folder', @@ -368,7 +403,6 @@ ipfs.util.addFromURL('http://example.com/', (err, result) => { } console.log(result) }) - ``` ##### Add a file from a stream to IPFS diff --git a/examples/bundle-browserify/package.json b/examples/bundle-browserify/package.json index 0d06ab502..14634eaa5 100644 --- a/examples/bundle-browserify/package.json +++ b/examples/bundle-browserify/package.json @@ -12,7 +12,7 @@ "devDependencies": { "browserify": "^13.1.1", "ipfs-api": "^11.1.0", - "http-server": "^0.9.0" + "http-server": "~0.9.0" }, "dependencies": { } diff --git a/examples/bundle-webpack/package.json b/examples/bundle-webpack/package.json index fa2325f0a..b1ad4eead 100644 --- a/examples/bundle-webpack/package.json +++ b/examples/bundle-webpack/package.json @@ -12,8 +12,8 @@ "babel-core": "^5.4.7", "babel-loader": "^5.1.2", "ipfs-api": "^11.1.0", - "json-loader": "^0.5.3", - "react": "^0.13.0", + "json-loader": "~0.5.3", + "react": "~0.13.0", "react-hot-loader": "^1.3.0", "webpack": "^1.9.6", "webpack-dev-server": "^1.8.2" diff --git a/examples/name-api/package.json b/examples/name-api/package.json index 37bb28535..388d50e01 100644 --- a/examples/name-api/package.json +++ b/examples/name-api/package.json @@ -10,6 +10,6 @@ "license": "MIT", "devDependencies": { "browserify": "^14.4.0", - "http-server": "^0.10.0" + "http-server": "~0.10.0" } } diff --git a/examples/sub-module/package.json b/examples/sub-module/package.json index 5cdec6d0f..74d650390 100644 --- a/examples/sub-module/package.json +++ b/examples/sub-module/package.json @@ -11,7 +11,7 @@ "babel-core": "^6.25.0", "babel-loader": "^7.1.0", "babel-preset-env": "^1.5.2", - "babili": "^0.1.4", + "babili": "~0.1.4", "webpack": "^3.0.0" } } diff --git a/examples/upload-file-via-browser/package.json b/examples/upload-file-via-browser/package.json index 4b53ccd8c..13a1235f1 100644 --- a/examples/upload-file-via-browser/package.json +++ b/examples/upload-file-via-browser/package.json @@ -14,11 +14,10 @@ "babel-core": "^5.4.7", "babel-loader": "^5.1.2", "ipfs-api": "../../", - "json-loader": "^0.5.4", "react": "^15.4.2", "react-dom": "^15.4.2", "react-hot-loader": "^1.3.1", - "webpack": "^1.9.6", + "webpack": "^2.0.0", "webpack-dev-server": "^1.8.2" } } diff --git a/examples/upload-file-via-browser/webpack.config.js b/examples/upload-file-via-browser/webpack.config.js index cbb60be2b..b4ccf9e88 100644 --- a/examples/upload-file-via-browser/webpack.config.js +++ b/examples/upload-file-via-browser/webpack.config.js @@ -21,9 +21,9 @@ module.exports = { module: { loaders: [{ test: /\.js$/, - loaders: ['react-hot', 'babel'], + loaders: ['react-hot-loader', 'babel-loader'], include: path.join(__dirname, 'src') - }, { test: /\.json$/, loader: 'json-loader' }] + }] }, node: { fs: 'empty', diff --git a/package.json b/package.json index c120e986e..a018df4d3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { "name": "ipfs-api", - "version": "20.2.0-timeout", + "version": "22.3.0", "description": "A client library for the IPFS HTTP API", + "leadMaintainer": "Alan Shaw ", "main": "src/index.js", "browser": { "glob": false, @@ -25,41 +26,42 @@ "coverage-publish": "aegir coverage --provider coveralls --timeout 100000" }, "dependencies": { - "async": "^2.6.0", - "big.js": "^5.0.3", + "async": "^2.6.1", + "big.js": "^5.1.2", "bs58": "^4.0.1", "cids": "~0.5.3", "concat-stream": "^1.6.2", + "debug": "^3.1.0", "detect-node": "^2.0.3", "flatmap": "0.0.3", "glob": "^7.1.2", "ipfs-block": "~0.7.1", - "ipfs-unixfs": "~0.1.14", - "ipld-dag-cbor": "~0.12.0", - "ipld-dag-pb": "~0.14.4", - "is-ipfs": "~0.3.2", + "ipfs-unixfs": "~0.1.15", + "ipld-dag-cbor": "~0.12.1", + "ipld-dag-pb": "~0.14.6", + "is-ipfs": "~0.4.2", "is-pull-stream": "0.0.0", "is-stream": "^1.1.0", - "libp2p-crypto": "^0.13.0", - "lru-cache": "^4.1.2", + "libp2p-crypto": "~0.13.0", + "lru-cache": "^4.1.3", "multiaddr": "^5.0.0", "multibase": "~0.4.0", "multihashes": "~0.4.13", "ndjson": "^1.5.0", "once": "^1.4.0", - "peer-id": "~0.10.7", + "peer-id": "~0.11.0", "peer-info": "~0.14.1", "promisify-es6": "^1.0.3", - "pull-defer": "^0.2.2", + "pull-defer": "~0.2.2", "pull-pushable": "^2.2.0", "pull-stream-to-stream": "^1.3.4", "pump": "^3.0.0", - "qs": "^6.5.1", + "qs": "^6.5.2", "readable-stream": "^2.3.6", - "stream-http": "^2.8.1", + "stream-http": "^2.8.3", "stream-to-pull-stream": "^1.7.2", - "streamifier": "^0.1.1", - "tar-stream": "^1.5.7" + "streamifier": "~0.1.1", + "tar-stream": "^1.6.1" }, "engines": { "node": ">=6.0.0", @@ -70,33 +72,28 @@ "url": "https://github.com/ipfs/js-ipfs-api" }, "devDependencies": { - "aegir": "^13.1.0", - "browser-process-platform": "^0.1.1", + "aegir": "^15.1.0", + "browser-process-platform": "~0.1.1", "chai": "^4.1.2", - "cross-env": "^5.1.4", + "cross-env": "^5.2.0", "dirty-chai": "^2.0.1", - "eslint-plugin-react": "^7.7.0", - "go-ipfs-dep": "^0.4.14", + "eslint-plugin-react": "^7.10.0", + "go-ipfs-dep": "~0.4.17", "gulp": "^3.9.1", - "hapi": "^17.3.1", - "interface-ipfs-core": "~0.64.2", - "ipfs": "~0.28.2", - "ipfsd-ctl": "~0.32.1", - "pre-commit": "^1.2.2", - "pull-stream": "^3.6.7", - "socket.io": "^2.1.0", - "socket.io-client": "^2.1.0", + "interface-ipfs-core": "~0.75.0", + "ipfsd-ctl": "~0.39.0", + "pull-stream": "^3.6.8", + "socket.io": "^2.1.1", + "socket.io-client": "^2.1.1", "stream-equal": "^1.1.1" }, - "pre-commit": [ - ], "keywords": [ "ipfs" ], - "author": "Matt Bell ", "contributors": [ "Alan Shaw ", "Alex Mingoia ", + "Alex Potsides ", "Antonio Tenorio-Fornés ", "Bruno Barbieri ", "Clemo ", @@ -110,6 +107,7 @@ "Fil ", "Francisco Baio Dias ", "Friedel Ziegelmayer ", + "Gar ", "Gavin McDermott ", "Greenkeeper ", "Haad ", @@ -117,6 +115,7 @@ "Harlan T Wood ", "Henrique Dias ", "Holodisc ", + "JGAntunes ", "Jacob Heun ", "James Halliday ", "Jason Carver ", @@ -126,34 +125,38 @@ "Jeromy ", "Joe Turgeon ", "Jonathan ", - "João Antunes ", "Juan Batiz-Benet ", "Kevin Wang ", "Kristoffer Ström ", + "Marcin Rataj ", "Matt Bell ", "Maxime Lathuilière ", "Michael Muré ", + "Mikeal Rogers ", "Mitar ", "Mithgol ", "Nuno Nogueira ", "Oli Evans ", + "Orie Steele ", "Pedro Teixeira ", "Pete Thomas ", "Richard Littauer ", "Richard Schneider ", + "Roman Khafizianov ", "Stephen Whitmore ", "Tara Vancil ", + "Travis Person ", "Travis Person ", - "Vasco Santos ", "Vasco Santos ", + "Vasco Santos ", "Victor Bjelkholm ", "Volker Mische ", - "achingbrain ", "dmitriy ryajov ", "elsehow ", "ethers ", "haad ", "kumavis ", + "leekt216 ", "nginnever ", "noah the goodra ", "priecint ", diff --git a/src/bitswap/unwant.js b/src/bitswap/unwant.js index 267568ee1..865fbc27b 100644 --- a/src/bitswap/unwant.js +++ b/src/bitswap/unwant.js @@ -1,16 +1,24 @@ 'use strict' const promisify = require('promisify-es6') +const CID = require('cids') module.exports = (send) => { - return promisify((args, opts, callback) => { + return promisify((cid, opts, callback) => { if (typeof (opts) === 'function') { callback = opts opts = {} } + + try { + cid = new CID(cid) + } catch (err) { + return callback(err) + } + send({ path: 'bitswap/unwant', - args: args, + args: cid.toBaseEncodedString(), qs: opts }, callback) }) diff --git a/src/bitswap/wantlist.js b/src/bitswap/wantlist.js index c96aaaaac..6cd1e3868 100644 --- a/src/bitswap/wantlist.js +++ b/src/bitswap/wantlist.js @@ -1,11 +1,30 @@ 'use strict' const promisify = require('promisify-es6') +const CID = require('cids') module.exports = (send) => { - return promisify((callback) => { + return promisify((peerId, opts, callback) => { + if (typeof (peerId) === 'function') { + callback = peerId + opts = {} + peerId = null + } else if (typeof (opts) === 'function') { + callback = opts + opts = {} + } + + if (peerId) { + try { + opts.peer = new CID(peerId).toBaseEncodedString() + } catch (err) { + return callback(err) + } + } + send({ - path: 'bitswap/wantlist' + path: 'bitswap/wantlist', + qs: opts }, callback) }) } diff --git a/src/block/get.js b/src/block/get.js index c30381893..327b9e7ff 100644 --- a/src/block/get.js +++ b/src/block/get.js @@ -34,11 +34,18 @@ module.exports = (send) => { const transform = (res, callback) => { if (Buffer.isBuffer(res)) { callback(null, new Block(res, cid)) + // For empty blocks, concat-stream can't infer the encoding so we are + // passed back an empty array + } else if (Array.isArray(res) && res.length === 0) { + callback(null, new Block(Buffer.alloc(0), cid)) } else { streamToValue(res, (err, data) => { if (err) { return callback(err) } + // For empty blocks, concat-stream can't infer the encoding so we are + // passed back an empty array + if (!data.length) data = Buffer.alloc(0) callback(null, new Block(data, cid)) }) } diff --git a/src/config/get.js b/src/config/get.js index fa1d605f8..882efe3df 100644 --- a/src/config/get.js +++ b/src/config/get.js @@ -2,6 +2,14 @@ const promisify = require('promisify-es6') +const toObject = function (res, callback) { + if (Buffer.isBuffer(res)) { + callback(null, JSON.parse(res.toString())) + } else { + callback(null, res) + } +} + module.exports = (send) => { return promisify((key, callback) => { if (typeof key === 'function') { @@ -10,18 +18,18 @@ module.exports = (send) => { } if (!key) { - send({ + send.andTransform({ path: 'config/show', buffer: true - }, callback) + }, toObject, callback) return } - send({ + send.andTransform({ path: 'config', args: key, buffer: true - }, (err, response) => { + }, toObject, (err, response) => { if (err) { return callback(err) } diff --git a/src/config/set.js b/src/config/set.js index fba4bd5bf..ae36a75b5 100644 --- a/src/config/set.js +++ b/src/config/set.js @@ -12,9 +12,7 @@ module.exports = (send) => { return callback(new Error('Invalid key type')) } - if (typeof value !== 'object' && - typeof value !== 'boolean' && - typeof value !== 'string') { + if (value === undefined || Buffer.isBuffer(value)) { return callback(new Error('Invalid value type')) } diff --git a/src/dag/put.js b/src/dag/put.js index 541c0d512..636d39ae4 100644 --- a/src/dag/put.js +++ b/src/dag/put.js @@ -7,51 +7,65 @@ const CID = require('cids') const multihash = require('multihashes') const SendOneFile = require('../utils/send-one-file') -function noop () {} - module.exports = (send) => { const sendOneFile = SendOneFile(send, 'dag/put') return promisify((dagNode, options, callback) => { if (typeof options === 'function') { - return setImmediate(() => callback(new Error('no options were passed'))) + callback = options } - callback = callback || noop + options = options || {} - let hashAlg = options.hash || 'sha2-256' - let format - let inputEnc + if (options.hash) { + options.hashAlg = options.hash + delete options.hash + } - if (options.cid && CID.isCID(options.cid)) { - format = options.cid.codec - hashAlg = multihash.decode(options.cid.multihash).name - prepare() - } else if (options.format) { - format = options.format - prepare() - } else { - callback(new Error('Invalid arguments')) + if (options.cid && (options.format || options.hashAlg)) { + return callback(new Error('Can\'t put dag node. Please provide either `cid` OR `format` and `hash` options.')) + } else if ((options.format && !options.hashAlg) || (!options.format && options.hashAlg)) { + return callback(new Error('Can\'t put dag node. Please provide `format` AND `hash` options.')) } - function prepare () { - inputEnc = 'raw' + if (options.cid) { + let cid - if (format === 'dag-cbor') { - dagCBOR.util.serialize(dagNode, finalize) - } - if (format === 'dag-pb') { - dagPB.util.serialize(dagNode, finalize) + try { + cid = new CID(options.cid) + } catch (err) { + return callback(err) } + + options.format = cid.codec + options.hashAlg = multihash.decode(cid.multihash).name + delete options.cid + } + + const optionDefaults = { + format: 'dag-cbor', + hashAlg: 'sha2-256', + inputEnc: 'raw' + } + + options = Object.assign(optionDefaults, options) + + if (options.format === 'dag-cbor') { + dagCBOR.util.serialize(dagNode, finalize) + } else if (options.format === 'dag-pb') { + dagPB.util.serialize(dagNode, finalize) + } else { + // FIXME Hopefully already serialized...can we use IPLD to serialise instead? + finalize(null, dagNode) } function finalize (err, serialized) { if (err) { return callback(err) } const sendOptions = { qs: { - hash: hashAlg, - format: format, - 'input-enc': inputEnc + hash: options.hashAlg, + format: options.format, + 'input-enc': options.inputEnc } } sendOneFile(serialized, sendOptions, (err, result) => { diff --git a/src/files/cp.js b/src/files/cp.js index b808ccc39..de4e0954d 100644 --- a/src/files/cp.js +++ b/src/files/cp.js @@ -1,17 +1,20 @@ 'use strict' const promisify = require('promisify-es6') +const findSources = require('../utils/find-sources') module.exports = (send) => { - return promisify((args, opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } + return promisify(function () { + const { + callback, + sources, + opts + } = findSources(Array.prototype.slice.call(arguments)) + send({ path: 'files/cp', - args: args, + args: sources, qs: opts - }, callback) + }, (error) => callback(error)) }) } diff --git a/src/files/flush.js b/src/files/flush.js index ea4de8dc6..6a131989b 100644 --- a/src/files/flush.js +++ b/src/files/flush.js @@ -12,6 +12,6 @@ module.exports = (send) => { return send({ path: 'files/flush', args: args - }, callback) + }, (error) => callback(error)) }) } diff --git a/src/files/index.js b/src/files/index.js index f729f4305..6bcbd722b 100644 --- a/src/files/index.js +++ b/src/files/index.js @@ -24,6 +24,8 @@ module.exports = (arg) => { rm: require('./rm')(send), ls: require('./ls')(send), read: require('./read')(send), + readReadableStream: require('./read-readable-stream')(send), + readPullStream: require('./read-pull-stream')(send), write: require('./write')(send), mv: require('./mv')(send) } diff --git a/src/files/ls.js b/src/files/ls.js index 2f5292aaa..ff22f5396 100644 --- a/src/files/ls.js +++ b/src/files/ls.js @@ -21,6 +21,13 @@ module.exports = (send) => { callback = opts opts = {} } + + if (typeof (args) === 'function') { + callback = args + opts = {} + args = null + } + return send.andTransform({ path: 'files/ls', args: args, diff --git a/src/files/mkdir.js b/src/files/mkdir.js index 393baecf4..b77fbf6dd 100644 --- a/src/files/mkdir.js +++ b/src/files/mkdir.js @@ -13,6 +13,6 @@ module.exports = (send) => { path: 'files/mkdir', args: args, qs: opts - }, callback) + }, (error) => callback(error)) }) } diff --git a/src/files/mv.js b/src/files/mv.js index 1f5a85f1f..234491b28 100644 --- a/src/files/mv.js +++ b/src/files/mv.js @@ -1,18 +1,20 @@ 'use strict' const promisify = require('promisify-es6') +const findSources = require('../utils/find-sources') module.exports = (send) => { - return promisify((args, opts, callback) => { - if (typeof opts === 'function' && - callback === undefined) { - callback = opts - opts = {} - } + return promisify(function () { + const { + callback, + sources, + opts + } = findSources(Array.prototype.slice.call(arguments)) + send({ path: 'files/mv', - args: args, + args: sources, qs: opts - }, callback) + }, (error) => callback(error)) }) } diff --git a/src/files/read-pull-stream.js b/src/files/read-pull-stream.js new file mode 100644 index 000000000..3e9ab8c3d --- /dev/null +++ b/src/files/read-pull-stream.js @@ -0,0 +1,26 @@ +'use strict' + +const toPull = require('stream-to-pull-stream') +const deferred = require('pull-defer') + +module.exports = (send) => { + return (args, opts) => { + opts = opts || {} + + const p = deferred.source() + + send({ + path: 'files/read', + args: args, + qs: opts + }, (err, stream) => { + if (err) { + return p.abort(err) + } + + p.resolve(toPull(stream)) + }) + + return p + } +} diff --git a/src/files/read-readable-stream.js b/src/files/read-readable-stream.js new file mode 100644 index 000000000..df8b92fbf --- /dev/null +++ b/src/files/read-readable-stream.js @@ -0,0 +1,26 @@ +'use strict' + +const Stream = require('readable-stream') +const pump = require('pump') + +module.exports = (send) => { + return (args, opts) => { + opts = opts || {} + + const pt = new Stream.PassThrough() + + send({ + path: 'files/read', + args: args, + qs: opts + }, (err, stream) => { + if (err) { + return pt.destroy(err) + } + + pump(stream, pt) + }) + + return pt + } +} diff --git a/src/files/rm.js b/src/files/rm.js index 2cfd209b6..404ceed10 100644 --- a/src/files/rm.js +++ b/src/files/rm.js @@ -22,6 +22,6 @@ module.exports = (send) => { path: 'files/rm', args: path, qs: opts - }, callback) + }, (error) => callback(error)) }) } diff --git a/src/ping-pull-stream.js b/src/ping-pull-stream.js index 9c18140e2..a7871faa3 100644 --- a/src/ping-pull-stream.js +++ b/src/ping-pull-stream.js @@ -2,7 +2,9 @@ const toPull = require('stream-to-pull-stream') const deferred = require('pull-defer') +const pump = require('pump') const moduleConfig = require('./utils/module-config') +const PingMessageStream = require('./utils/ping-message-stream') module.exports = (arg) => { const send = moduleConfig(arg) @@ -18,10 +20,13 @@ module.exports = (arg) => { qs: opts } const p = deferred.source() + const response = new PingMessageStream() send(request, (err, stream) => { if (err) { return p.abort(err) } - p.resolve(toPull.source(stream)) + + pump(stream, response) + p.resolve(toPull.source(response)) }) return p diff --git a/src/ping-readable-stream.js b/src/ping-readable-stream.js index 6281a44de..df4f70401 100644 --- a/src/ping-readable-stream.js +++ b/src/ping-readable-stream.js @@ -1,8 +1,8 @@ 'use strict' -const Stream = require('readable-stream') const pump = require('pump') const moduleConfig = require('./utils/module-config') +const PingMessageStream = require('./utils/ping-message-stream') module.exports = (arg) => { const send = moduleConfig(arg) @@ -17,17 +17,14 @@ module.exports = (arg) => { args: id, qs: opts } - // ndjson streams objects - const pt = new Stream.PassThrough({ - objectMode: true - }) - send(request, (err, stream) => { - if (err) { return pt.destroy(err) } + const response = new PingMessageStream() - pump(stream, pt) + send(request, (err, stream) => { + if (err) { return response.emit('error', err) } + pump(stream, response) }) - return pt + return response } } diff --git a/src/ping.js b/src/ping.js index 2682e9752..8b9081967 100644 --- a/src/ping.js +++ b/src/ping.js @@ -1,8 +1,10 @@ 'use strict' const promisify = require('promisify-es6') +const pump = require('pump') +const Writable = require('readable-stream').Writable const moduleConfig = require('./utils/module-config') -const streamToValue = require('./utils/stream-to-value') +const PingMessageStream = require('./utils/ping-message-stream') module.exports = (arg) => { const send = moduleConfig(arg) @@ -29,15 +31,23 @@ module.exports = (arg) => { } // Transform the response stream to a value: - // [{ Success: , Time: , Text: }] - const transform = (res, callback) => { - streamToValue(res, (err, res) => { - if (err) { - return callback(err) - } - - callback(null, res) - }) + // [{ success: , time: , text: }] + const transform = (stream, callback) => { + const messageConverter = new PingMessageStream() + const responses = [] + + pump( + stream, + messageConverter, + new Writable({ + objectMode: true, + write (chunk, enc, cb) { + responses.push(chunk) + cb() + } + }), + (err) => callback(err, responses) + ) } send.andTransform(request, transform, callback) diff --git a/src/pubsub.js b/src/pubsub.js index e5ed5d54b..f539d0e3a 100644 --- a/src/pubsub.js +++ b/src/pubsub.js @@ -4,6 +4,7 @@ const promisify = require('promisify-es6') const EventEmitter = require('events') const eos = require('end-of-stream') const isNode = require('detect-node') +const setImmediate = require('async/setImmediate') const PubsubMessageStream = require('./utils/pubsub-message-stream') const stringlistToArray = require('./utils/stringlist-to-array') const moduleConfig = require('./utils/module-config') @@ -19,14 +20,13 @@ module.exports = (arg) => { const subscriptions = {} ps.id = Math.random() return { - subscribe: (topic, options, handler, callback) => { + subscribe: (topic, handler, options, callback) => { const defaultOptions = { discover: false } if (typeof options === 'function') { - callback = handler - handler = options + callback = options options = defaultOptions } @@ -39,14 +39,15 @@ module.exports = (arg) => { if (!callback) { return Promise.reject(NotSupportedError()) } - return callback(NotSupportedError()) + + return setImmediate(() => callback(NotSupportedError())) } // promisify doesn't work as we always pass a // function as last argument (`handler`) if (!callback) { return new Promise((resolve, reject) => { - subscribe(topic, options, handler, (err) => { + subscribe(topic, handler, options, (err) => { if (err) { return reject(err) } @@ -55,24 +56,61 @@ module.exports = (arg) => { }) } - subscribe(topic, options, handler, callback) + subscribe(topic, handler, options, callback) }, - unsubscribe: (topic, handler) => { + unsubscribe: (topic, handler, callback) => { if (!isNode) { - throw NotSupportedError() + if (!callback) { + return Promise.reject(NotSupportedError()) + } + + return setImmediate(() => callback(NotSupportedError())) } if (ps.listenerCount(topic) === 0 || !subscriptions[topic]) { - throw new Error(`Not subscribed to '${topic}'`) + const err = new Error(`Not subscribed to '${topic}'`) + + if (!callback) { + return Promise.reject(err) + } + + return setImmediate(() => callback(err)) } ps.removeListener(topic, handler) - // Drop the request once we are actualy done + // Drop the request once we are actually done if (ps.listenerCount(topic) === 0) { - subscriptions[topic].abort() + if (!callback) { + return new Promise((resolve, reject) => { + // When the response stream has ended, resolve the promise + eos(subscriptions[topic].res, (err) => { + // FIXME: Artificial timeout needed to ensure unsubscribed + setTimeout(() => { + if (err) return reject(err) + resolve() + }) + }) + subscriptions[topic].req.abort() + subscriptions[topic] = null + }) + } + + // When the response stream has ended, call the callback + eos(subscriptions[topic].res, (err) => { + // FIXME: Artificial timeout needed to ensure unsubscribed + setTimeout(() => callback(err)) + }) + subscriptions[topic].req.abort() subscriptions[topic] = null + return } + + if (!callback) { + return Promise.resolve() + } + + setImmediate(() => callback()) }, publish: promisify((topic, data, callback) => { if (!isNode) { @@ -118,7 +156,7 @@ module.exports = (arg) => { } } - function subscribe (topic, options, handler, callback) { + function subscribe (topic, handler, options, callback) { ps.on(topic, handler) if (subscriptions[topic]) { @@ -137,13 +175,16 @@ module.exports = (arg) => { // Start the request and transform the response // stream to Pubsub messages stream - subscriptions[topic] = send.andTransform(request, PubsubMessageStream.from, (err, stream) => { + subscriptions[topic] = {} + subscriptions[topic].req = send.andTransform(request, PubsubMessageStream.from, (err, stream) => { if (err) { subscriptions[topic] = null ps.removeListener(topic, handler) return callback(err) } + subscriptions[topic].res = stream + stream.on('data', (msg) => { ps.emit(topic, msg) }) diff --git a/src/swarm/peers.js b/src/swarm/peers.js index 4f6746219..9ccbb1d2a 100644 --- a/src/swarm/peers.js +++ b/src/swarm/peers.js @@ -21,9 +21,9 @@ module.exports = (send) => { return callback(err) } + // go-ipfs <= 0.4.4 if (result.Strings) { - // go-ipfs <= 0.4.4 - callback(null, result.Strings.map((p) => { + return callback(null, result.Strings.map((p) => { const res = {} if (verbose) { @@ -40,26 +40,26 @@ module.exports = (send) => { return res })) - } else if (result.Peers) { - // go-ipfs >= 0.4.5 - callback(null, result.Peers.map((p) => { - const res = { - addr: multiaddr(p.Addr), - peer: PeerId.createFromB58String(p.Peer), - muxer: p.Muxer - } + } - if (p.Latency) { - res.latency = p.Latency - } + // go-ipfs >= 0.4.5 + callback(null, (result.Peers || []).map((p) => { + const res = { + addr: multiaddr(p.Addr), + peer: PeerId.createFromB58String(p.Peer), + muxer: p.Muxer + } - if (p.Streams) { - res.streams = p.Streams - } + if (p.Latency) { + res.latency = p.Latency + } - return res - })) - } + if (p.Streams) { + res.streams = p.Streams + } + + return res + })) }) }) } diff --git a/src/util/url-add.js b/src/util/url-add.js index 39244c289..e9e4be184 100644 --- a/src/util/url-add.js +++ b/src/util/url-add.js @@ -55,10 +55,11 @@ const requestWithRedirect = (url, opts, sendOneFile, callback) => { qs: opts, converter: FileResultStreamConverter } + const fileName = decodeURIComponent(parsedUrl.pathname.split('/').pop()) sendOneFile({ content: res, - path: parsedUrl.pathname.split('/').pop() + path: fileName }, requestOpts, callback) } }) diff --git a/src/utils/find-sources.js b/src/utils/find-sources.js new file mode 100644 index 000000000..2a862514a --- /dev/null +++ b/src/utils/find-sources.js @@ -0,0 +1,25 @@ +'use strict' + +module.exports = (args) => { + const callback = args.pop() + let opts = {} + let sources = [] + + if (!Array.isArray(args[args.length - 1]) && typeof args[args.length - 1] === 'object') { + opts = args.pop() + } + + if (args.length === 1 && Array.isArray(args[0])) { + // support ipfs.file.cp([src, dest], opts, cb) + sources = args[0] + } else { + // support ipfs.file.cp(src, dest, opts, cb) and ipfs.file.cp(src1, src2, dest, opts, cb) + sources = args + } + + return { + callback, + sources, + opts + } +} diff --git a/src/utils/ping-message-converter.js b/src/utils/ping-message-converter.js new file mode 100644 index 000000000..79d9fc3be --- /dev/null +++ b/src/utils/ping-message-converter.js @@ -0,0 +1,23 @@ +'use strict' + +// Converts IPFS API ping messages to lowercase +// +// { +// Success: true, +// Text: 'foobar', +// Time: 0 +// } +// + +module.exports = function pingMessageConverter (obj) { + if (!isPingMessage(obj)) throw new Error('Invalid ping message received') + return { + success: obj.Success, + time: obj.Time, + text: obj.Text + } +} + +function isPingMessage (obj) { + return obj && typeof obj.Success === 'boolean' +} diff --git a/src/utils/ping-message-stream.js b/src/utils/ping-message-stream.js new file mode 100644 index 000000000..944e2d9cf --- /dev/null +++ b/src/utils/ping-message-stream.js @@ -0,0 +1,27 @@ +'use strict' + +const TransformStream = require('readable-stream').Transform +const pingMessageConverter = require('./ping-message-converter') + +class PingMessageStream extends TransformStream { + constructor (options) { + const opts = Object.assign(options || {}, { objectMode: true }) + super(opts) + } + + _transform (obj, enc, callback) { + try { + const msg = pingMessageConverter(obj) + this.push(msg) + + if (!msg.success) { + throw new Error(msg.text) + } + } catch (err) { + return callback(err) + } + callback() + } +} + +module.exports = PingMessageStream diff --git a/src/utils/send-request.js b/src/utils/send-request.js index 982fd2654..1e7528d05 100644 --- a/src/utils/send-request.js +++ b/src/utils/send-request.js @@ -9,6 +9,7 @@ const once = require('once') const streamToValue = require('./stream-to-value') const streamToJsonValue = require('./stream-to-json-value') const request = require('./request') +const log = require('debug')('ipfs-api:request') // -- Internal @@ -23,6 +24,7 @@ function parseError (res, cb) { if (payload) { error.code = payload.Code error.message = payload.Message || payload.toString() + error.type = payload.Type } cb(error) }) @@ -35,6 +37,12 @@ function onRes (buffer, cb) { const isJson = res.headers['content-type'] && res.headers['content-type'].indexOf('application/json') === 0 + if (res.req) { + log(res.req.method, `${res.req.getHeaders().host}${res.req.path}`, res.statusCode, res.statusMessage) + } else { + log(res.url, res.statusCode, res.statusMessage) + } + if (res.statusCode >= 400 || !res.statusCode) { return parseError(res, cb) } @@ -106,7 +114,7 @@ function requestAPI (config, options, callback) { delete options.qs.followSymlinks const method = 'POST' - const headers = {} + const headers = Object.assign({}, config.headers) if (isNode) { // Browsers do not allow you to modify the user agent diff --git a/test/commands.spec.js b/test/commands.spec.js index 02d73427b..2e82f6d8d 100644 --- a/test/commands.spec.js +++ b/test/commands.spec.js @@ -25,7 +25,10 @@ describe('.commands', function () { }) }) - after((done) => ipfsd.stop(done)) + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) it('lists commands', (done) => { ipfs.commands((err, res) => { diff --git a/test/constructor.spec.js b/test/constructor.spec.js index fb8b6ca23..0a3af1897 100644 --- a/test/constructor.spec.js +++ b/test/constructor.spec.js @@ -35,7 +35,10 @@ describe('ipfs-api constructor tests', () => { }) }) - after((done) => ipfsd.stop(done)) + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) it('opts', (done) => { const splitted = apiAddr.split('/') @@ -56,6 +59,16 @@ describe('ipfs-api constructor tests', () => { clientWorks(ipfsAPI(splitted[2], splitted[4]), done) }) + it('specify host, port and api path', (done) => { + const splitted = apiAddr.split('/') + + clientWorks(ipfsAPI({ + host: splitted[2], + port: splitted[4], + 'api-path': '/api/v0/' + }), done) + }) + it('host, port, opts', (done) => { const splitted = apiAddr.split('/') diff --git a/test/custom-headers.spec.js b/test/custom-headers.spec.js new file mode 100644 index 000000000..2cf4c71c3 --- /dev/null +++ b/test/custom-headers.spec.js @@ -0,0 +1,61 @@ +/* eslint-env mocha */ +'use strict' + +const isNode = require('detect-node') +const chai = require('chai') +const dirtyChai = require('dirty-chai') +const expect = chai.expect +chai.use(dirtyChai) + +const IPFSApi = require('../src') +const f = require('./utils/factory') + +describe('custom headers', function () { + // do not test in browser + if (!isNode) { return } + this.timeout(50 * 1000) // slow CI + let ipfs + let ipfsd + // initialize ipfs with custom headers + before(done => { + f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { + expect(err).to.not.exist() + ipfsd = _ipfsd + ipfs = IPFSApi({ + host: 'localhost', + port: 6001, + protocol: 'http', + headers: { + authorization: 'Bearer ' + 'YOLO' + } + }) + done() + }) + }) + + it('are supported', done => { + // spin up a test http server to inspect the requests made by the library + const server = require('http').createServer((req, res) => { + req.on('data', () => {}) + req.on('end', () => { + res.writeHead(200) + res.end() + // ensure custom headers are present + expect(req.headers.authorization).to.equal('Bearer ' + 'YOLO') + server.close() + done() + }) + }) + + server.listen(6001, () => { + ipfs.id((err, res) => { + if (err) { + throw new Error('Unexpected error.') + } + // this call is used to test that headers are being sent. + }) + }) + }) + + after(done => ipfsd.stop(done)) +}) diff --git a/test/diag.spec.js b/test/diag.spec.js index 3a2bb07a5..d2648024d 100644 --- a/test/diag.spec.js +++ b/test/diag.spec.js @@ -28,7 +28,10 @@ describe('.diag', function () { }) }) - after((done) => ipfsd.stop(done)) + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) describe('Callback API', () => { // Disabled in go-ipfs 0.4.10 diff --git a/test/files.spec.js b/test/files.spec.js index e3832b3b6..05477c41b 100644 --- a/test/files.spec.js +++ b/test/files.spec.js @@ -6,7 +6,6 @@ const chai = require('chai') const dirtyChai = require('dirty-chai') const expect = chai.expect chai.use(dirtyChai) -const isNode = require('detect-node') const loadFixture = require('aegir/fixtures') const mh = require('multihashes') const CID = require('cids') @@ -47,7 +46,10 @@ describe('.files (the MFS API part)', function () { }) }) - after((done) => ipfsd.stop(done)) + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) it('add file for testing', (done) => { ipfs.files.add(testfile, (err, res) => { @@ -327,22 +329,80 @@ describe('.files (the MFS API part)', function () { ipfs.files.flush('/', done) }) - it('files.cp', (done) => { - ipfs.files.cp([ - '/ipfs/Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP', - '/test-folder/test-file' - ], (err) => { - expect(err).to.not.exist() - done() - }) + it('files.cp', () => { + const folder = `/test-folder-${Math.random()}` + + return ipfs.files.mkdir(folder) + .then(() => ipfs.files.cp([ + '/ipfs/Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP', + `${folder}/test-file-${Math.random()}` + ])) }) - it('files.ls', (done) => { - ipfs.files.ls('/test-folder', (err, res) => { - expect(err).to.not.exist() - expect(res.length).to.equal(1) - done() - }) + it('files.cp with non-array arguments', () => { + const folder = `/test-folder-${Math.random()}` + + return ipfs.files.mkdir(folder) + .then(() => ipfs.files.cp( + '/ipfs/Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP', + `${folder}/test-file-${Math.random()}` + )) + }) + + it('files.mv', () => { + const folder = `/test-folder-${Math.random()}` + const source = `${folder}/test-file-${Math.random()}` + const dest = `${folder}/test-file-${Math.random()}` + + return ipfs.files.mkdir(folder) + .then(() => ipfs.files.cp( + '/ipfs/Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP', + source + )) + .then(() => ipfs.files.mv([ + source, + dest + ])) + }) + + it('files.mv with non-array arguments', () => { + const folder = `/test-folder-${Math.random()}` + const source = `${folder}/test-file-${Math.random()}` + const dest = `${folder}/test-file-${Math.random()}` + + return ipfs.files.mkdir(folder) + .then(() => ipfs.files.cp( + '/ipfs/Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP', + source + )) + .then(() => ipfs.files.mv( + source, + dest + )) + }) + + it('files.ls', () => { + const folder = `/test-folder-${Math.random()}` + const file = `${folder}/test-file-${Math.random()}` + + return ipfs.files.mkdir(folder) + .then(() => ipfs.files.write(file, Buffer.from('Hello, world'), { + create: true + })) + .then(() => ipfs.files.ls(folder)) + .then(files => { + expect(files.length).to.equal(1) + }) + }) + + it('files.ls mfs root by default', () => { + const folder = `test-folder-${Math.random()}` + + return ipfs.files.mkdir(`/${folder}`) + .then(() => ipfs.files.ls()) + .then(files => { + expect(files.find(file => file.name === folder)).to.be.ok() + }) }) it('files.write', (done) => { @@ -371,46 +431,53 @@ describe('.files (the MFS API part)', function () { }) }) - it('files.stat', (done) => { - ipfs.files.stat('/test-folder/test-file', (err, res) => { - expect(err).to.not.exist() - expect(res).to.deep.equal({ - hash: 'Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP', - size: 12, - cumulativeSize: 20, - blocks: 0, - type: 'file', - withLocality: false, - local: undefined, - sizeLocal: undefined + it('files.stat', () => { + const folder = `/test-folder-${Math.random()}` + const file = `${folder}/test-file-${Math.random()}` + + return ipfs.files.mkdir(folder) + .then(() => ipfs.files.write(file, testfile, { + create: true + })) + .then(() => ipfs.files.stat(file)) + .then((stats) => { + expect(stats).to.deep.equal({ + hash: 'QmQhouoDPAnzhVM148yCa9CbUXK65wSEAZBtgrLGHtmdmP', + size: 12, + cumulativeSize: 70, + blocks: 1, + type: 'file', + withLocality: false, + local: undefined, + sizeLocal: undefined + }) }) - - done() - }) }) it('files.stat file that does not exist()', (done) => { ipfs.files.stat('/test-folder/does-not-exist()', (err, res) => { expect(err).to.exist() - if (err.code === 0) { - return done() - } - throw err - }) - }) - - it('files.read', (done) => { - if (!isNode) { - return done() - } + expect(err.code).to.equal(0) + expect(err.type).to.equal('error') - ipfs.files.read('/test-folder/test-file', (err, buf) => { - expect(err).to.not.exist() - expect(Buffer.from(buf)).to.deep.equal(testfile) done() }) }) + it('files.read', () => { + const folder = `/test-folder-${Math.random()}` + const file = `${folder}/test-file-${Math.random()}` + + return ipfs.files.mkdir(folder) + .then(() => ipfs.files.write(file, testfile, { + create: true + })) + .then(() => ipfs.files.read(file)) + .then((buf) => { + expect(Buffer.from(buf)).to.deep.equal(testfile) + }) + }) + it('files.rm without options', (done) => { ipfs.files.rm('/test-folder/test-file-2.txt', done) }) diff --git a/test/get.spec.js b/test/get.spec.js index af28ba61c..91d16f3fe 100644 --- a/test/get.spec.js +++ b/test/get.spec.js @@ -41,7 +41,10 @@ describe('.get (specific go-ipfs features)', function () { ], done) }) - after((done) => ipfsd.stop(done)) + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) it('no compression args', (done) => { ipfs.get(smallFile.cid, (err, files) => { @@ -69,7 +72,7 @@ describe('.get (specific go-ipfs features)', function () { 'compression-level': 10 }, (err, files) => { expect(err).to.exist() - expect(err.toString()).to.equal('Error: Compression level must be between 1 and 9') + expect(err.toString()).to.equal('Error: compression level must be between 1 and 9') done() }) }) diff --git a/test/interface.spec.js b/test/interface.spec.js new file mode 100644 index 000000000..a3130159d --- /dev/null +++ b/test/interface.spec.js @@ -0,0 +1,248 @@ +/* eslint-env mocha */ +'use strict' + +const tests = require('interface-ipfs-core') +const isNode = require('detect-node') +const CommonFactory = require('./utils/interface-common-factory') +const IPFSApi = require('../src') +const isWindows = process.platform && process.platform === 'win32' + +describe('interface-ipfs-core tests', () => { + const defaultCommonFactory = CommonFactory.create() + + tests.bitswap(defaultCommonFactory, { + skip: [ + // bitswap.stat + { + name: 'should not get bitswap stats when offline', + reason: 'FIXME go-ipfs returns an error https://github.com/ipfs/go-ipfs/issues/4078' + }, + // bitswap.wantlist + { + name: 'should not get the wantlist when offline', + reason: 'FIXME go-ipfs returns an error https://github.com/ipfs/go-ipfs/issues/4078' + }, + // bitswap.unwant + { + name: 'should remove a key from the wantlist', + reason: 'FIXME why is this skipped?' + }, + { + name: 'should not remove a key from the wantlist when offline', + reason: 'FIXME go-ipfs returns an error https://github.com/ipfs/go-ipfs/issues/4078' + } + ] + }) + + tests.block(defaultCommonFactory) + + tests.bootstrap(defaultCommonFactory) + + tests.config(defaultCommonFactory, { + skip: [ + // config.replace + { + name: 'replace', + reason: 'FIXME Waiting for fix on go-ipfs https://github.com/ipfs/js-ipfs-api/pull/307#discussion_r69281789 and https://github.com/ipfs/go-ipfs/issues/2927' + } + ] + }) + + tests.dag(defaultCommonFactory, { + skip: [ + // dag.tree + { + name: 'tree', + reason: 'TODO vmx 2018-02-22: Currently the tree API is not exposed in go-ipfs' + }, + // dag.get: + { + name: 'should get a dag-pb node local value', + reason: 'FIXME vmx 2018-02-22: Currently not supported in go-ipfs, it might be possible once https://github.com/ipfs/go-ipfs/issues/4728 is done' + }, + { + name: 'should get dag-pb value via dag-cbor node', + reason: 'FIXME vmx 2018-02-22: Currently not supported in go-ipfs, it might be possible once https://github.com/ipfs/go-ipfs/issues/4728 is done' + }, + { + name: 'should get by CID string + path', + reason: 'FIXME vmx 2018-02-22: Currently not supported in go-ipfs, it might be possible once https://github.com/ipfs/go-ipfs/issues/4728 is done' + } + ] + }) + + tests.dht(defaultCommonFactory, { + skip: [ + // dht.findpeer + { + name: 'should fail to find other peer if peer does not exist', + reason: 'FIXME checking what is exactly go-ipfs returning https://github.com/ipfs/go-ipfs/issues/3862#issuecomment-294168090' + }, + // dht.findprovs + { + name: 'should provide from one node and find it through another node', + reason: 'FIXME go-ipfs endpoint doesn\'t conform with the others https://github.com/ipfs/go-ipfs/issues/5047' + }, + // dht.get + { + name: 'should get a value after it was put on another node', + reason: 'FIXME go-ipfs errors with Error: key was not found (type 6) https://github.com/ipfs/go-ipfs/issues/3862' + } + ] + }) + + tests.files(defaultCommonFactory, { + skip: [ + // files.add + isNode ? null : { + name: 'should add a nested directory as array of tupples', + reason: 'FIXME https://github.com/ipfs/js-ipfs-api/issues/339' + }, + isNode ? null : { + name: 'should add a nested directory as array of tupples with progress', + reason: 'FIXME https://github.com/ipfs/js-ipfs-api/issues/339' + }, + // files.addPullStream + isNode ? null : { + name: 'should add pull stream of valid files and dirs', + reason: 'FIXME https://github.com/ipfs/js-ipfs-api/issues/339' + }, + // files.addReadableStream + isNode ? null : { + name: 'should add readable stream of valid files and dirs', + reason: 'FIXME https://github.com/ipfs/js-ipfs-api/issues/339' + }, + // files.catPullStream + { + name: 'should export a chunk of a file', + reason: 'TODO not implemented in go-ipfs yet' + }, + { + name: 'should export a chunk of a file in a Pull Stream', + reason: 'TODO not implemented in go-ipfs yet' + }, + { + name: 'should export a chunk of a file in a Readable Stream', + reason: 'TODO not implemented in go-ipfs yet' + }, + // files.get + isNode ? null : { + name: 'should get a directory', + reason: 'FIXME https://github.com/ipfs/js-ipfs-api/issues/339' + } + ] + }) + + tests.key(defaultCommonFactory, { + skip: [ + // key.export + { + name: 'export', + reason: 'TODO not implemented in go-ipfs yet' + }, + // key.import + { + name: 'import', + reason: 'TODO not implemented in go-ipfs yet' + } + ] + }) + + tests.ls(defaultCommonFactory, { + skip: [ + // lsPullStream + isNode ? null : { + name: 'should pull stream ls with a base58 encoded CID', + reason: 'FIXME https://github.com/ipfs/js-ipfs-api/issues/339' + }, + // lsReadableStream + isNode ? null : { + name: 'should readable stream ls with a base58 encoded CID', + reason: 'FIXME https://github.com/ipfs/js-ipfs-api/issues/339' + }, + // ls + isNode ? null : { + name: 'should ls with a base58 encoded CID', + reason: 'FIXME https://github.com/ipfs/js-ipfs-api/issues/339' + } + ] + }) + + tests.miscellaneous(defaultCommonFactory, { + skip: [ + // stop + { + name: 'should stop the node', + reason: 'FIXME go-ipfs returns an error https://github.com/ipfs/go-ipfs/issues/4078' + }, + // resolve + 'resolve' + ] + }) + + tests.object(defaultCommonFactory) + + tests.pin(defaultCommonFactory) + + tests.ping(defaultCommonFactory) + + tests.pubsub(CommonFactory.create({ + spawnOptions: { + args: ['--enable-pubsub-experiment'], + initOptions: { bits: 1024 } + } + }), { + skip: isNode ? [ + // pubsub.subscribe + isWindows ? { + name: 'should send/receive 100 messages', + reason: 'FIXME https://github.com/ipfs/interface-ipfs-core/pull/188#issuecomment-354673246 and https://github.com/ipfs/go-ipfs/issues/4778' + } : null, + isWindows ? { + name: 'should receive multiple messages', + reason: 'FIXME https://github.com/ipfs/interface-ipfs-core/pull/188#issuecomment-354673246 and https://github.com/ipfs/go-ipfs/issues/4778' + } : null + ] : { + reason: 'FIXME pubsub is not supported in the browser https://github.com/ipfs/js-ipfs-api/issues/518' + } + }) + + tests.repo(defaultCommonFactory) + + tests.stats(defaultCommonFactory) + + tests.swarm(CommonFactory.create({ + createSetup ({ ipfsFactory, nodes }) { + return callback => { + callback(null, { + spawnNode (repoPath, config, cb) { + if (typeof repoPath === 'function') { + cb = repoPath + repoPath = undefined + } + + if (typeof config === 'function') { + cb = config + config = undefined + } + + const spawnOptions = { repoPath, config, initOptions: { bits: 1024 } } + + ipfsFactory.spawn(spawnOptions, (err, _ipfsd) => { + if (err) { + return cb(err) + } + + nodes.push(_ipfsd) + cb(null, IPFSApi(_ipfsd.apiAddr)) + }) + } + }) + } + } + })) + + tests.types(defaultCommonFactory, { skip: { reason: 'FIXME currently failing' } }) + + tests.util(defaultCommonFactory, { skip: { reason: 'FIXME currently failing' } }) +}) diff --git a/test/key.spec.js b/test/key.spec.js index 24a2a77b1..7de7a2a97 100644 --- a/test/key.spec.js +++ b/test/key.spec.js @@ -25,7 +25,10 @@ describe('.key', function () { }) }) - after((done) => ipfsd.stop(done)) + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) describe('Callback API', () => { describe('.gen', () => { diff --git a/test/log.spec.js b/test/log.spec.js index b45911c2f..1c583b670 100644 --- a/test/log.spec.js +++ b/test/log.spec.js @@ -25,7 +25,10 @@ describe('.log', function () { }) }) - after((done) => ipfsd.stop(done)) + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) it('.log.tail', (done) => { const req = ipfs.log.tail((err, res) => { diff --git a/test/name.spec.js b/test/name.spec.js index baad2654d..3e5d0402b 100644 --- a/test/name.spec.js +++ b/test/name.spec.js @@ -24,7 +24,7 @@ describe('.name', () => { let testFileCid before(function (done) { - this.timeout(20 * 1000) + this.timeout(30 * 1000) series([ (cb) => { @@ -44,26 +44,38 @@ describe('.name', () => { }) }, (cb) => { - ipfsd.api.id((err, id) => { - expect(err).to.not.exist() - const ma = id.addresses[0] - other.swarm.connect(ma, cb) - }) - }, - (cb) => { - ipfs.files.add(testfile, (err, res) => { - expect(err).to.not.exist() - testFileCid = res[0].hash - cb() - }) + parallel([ + (cb) => { + ipfs.id((err, id) => { + expect(err).to.not.exist() + const ma = id.addresses[0] + other.swarm.connect(ma, cb) + }) + }, + (cb) => { + ipfs.files.add(testfile, (err, res) => { + expect(err).to.not.exist() + testFileCid = res[0].hash + cb() + }) + } + ], cb) } ], done) }) - after((done) => { + after(function (done) { + this.timeout(10 * 1000) + parallel([ - (cb) => ipfsd.stop(cb), - (cb) => otherd.stop(cb) + (cb) => { + if (!ipfsd) return cb() + ipfsd.stop(cb) + }, + (cb) => { + if (!otherd) return cb() + otherd.stop(cb) + } ], done) }) diff --git a/test/ping.spec.js b/test/ping.spec.js index c429a95ee..06848ee78 100644 --- a/test/ping.spec.js +++ b/test/ping.spec.js @@ -12,9 +12,17 @@ const parallel = require('async/parallel') const series = require('async/series') const IPFSApi = require('../src') +const PingMessageStream = require('../src/utils/ping-message-stream') const f = require('./utils/factory') +// Determine if a ping response object is a pong, or something else, like a status message +function isPong (pingResponse) { + return Boolean(pingResponse && pingResponse.success && !pingResponse.text) +} + describe('.ping', function () { + this.timeout(10 * 1000) + let ipfs let ipfsd let other @@ -22,7 +30,7 @@ describe('.ping', function () { let otherId before(function (done) { - this.timeout(20 * 1000) // slow CI + this.timeout(30 * 1000) // slow CI series([ (cb) => { @@ -42,26 +50,36 @@ describe('.ping', function () { }) }, (cb) => { - ipfsd.api.id((err, id) => { - expect(err).to.not.exist() - const ma = id.addresses[0] - other.swarm.connect(ma, cb) - }) - }, - (cb) => { - other.id((err, id) => { - expect(err).to.not.exist() - otherId = id.id - cb() - }) + parallel([ + (cb) => { + ipfs.id((err, id) => { + expect(err).to.not.exist() + const ma = id.addresses[0] + other.swarm.connect(ma, cb) + }) + }, + (cb) => { + other.id((err, id) => { + expect(err).to.not.exist() + otherId = id.id + cb() + }) + } + ], cb) } ], done) }) after((done) => { parallel([ - (cb) => ipfsd.stop(cb), - (cb) => otherd.stop(cb) + (cb) => { + if (!ipfsd) return cb() + ipfsd.stop(cb) + }, + (cb) => { + if (!otherd) return cb() + otherd.stop(cb) + } ], done) }) @@ -69,12 +87,12 @@ describe('.ping', function () { ipfs.ping(otherId, (err, res) => { expect(err).to.not.exist() expect(res).to.be.an('array') - expect(res).to.have.lengthOf(3) + expect(res.filter(isPong)).to.have.lengthOf(1) res.forEach(packet => { - expect(packet).to.have.keys('Success', 'Time', 'Text') - expect(packet.Time).to.be.a('number') + expect(packet).to.have.keys('success', 'time', 'text') + expect(packet.time).to.be.a('number') }) - const resultMsg = res.find(packet => packet.Text.includes('Average latency')) + const resultMsg = res.find(packet => packet.text.includes('Average latency')) expect(resultMsg).to.exist() done() }) @@ -84,12 +102,12 @@ describe('.ping', function () { ipfs.ping(otherId, { count: 2 }, (err, res) => { expect(err).to.not.exist() expect(res).to.be.an('array') - expect(res).to.have.lengthOf(4) + expect(res.filter(isPong)).to.have.lengthOf(2) res.forEach(packet => { - expect(packet).to.have.keys('Success', 'Time', 'Text') - expect(packet.Time).to.be.a('number') + expect(packet).to.have.keys('success', 'time', 'text') + expect(packet.time).to.be.a('number') }) - const resultMsg = res.find(packet => packet.Text.includes('Average latency')) + const resultMsg = res.find(packet => packet.text.includes('Average latency')) expect(resultMsg).to.exist() done() }) @@ -99,12 +117,12 @@ describe('.ping', function () { ipfs.ping(otherId, { n: 2 }, (err, res) => { expect(err).to.not.exist() expect(res).to.be.an('array') - expect(res).to.have.lengthOf(4) + expect(res.filter(isPong)).to.have.lengthOf(2) res.forEach(packet => { - expect(packet).to.have.keys('Success', 'Time', 'Text') - expect(packet.Time).to.be.a('number') + expect(packet).to.have.keys('success', 'time', 'text') + expect(packet.time).to.be.a('number') }) - const resultMsg = res.find(packet => packet.Text.includes('Average latency')) + const resultMsg = res.find(packet => packet.text.includes('Average latency')) expect(resultMsg).to.exist() done() }) @@ -123,12 +141,12 @@ describe('.ping', function () { return ipfs.ping(otherId) .then((res) => { expect(res).to.be.an('array') - expect(res).to.have.lengthOf(3) + expect(res.filter(isPong)).to.have.lengthOf(1) res.forEach(packet => { - expect(packet).to.have.keys('Success', 'Time', 'Text') - expect(packet.Time).to.be.a('number') + expect(packet).to.have.keys('success', 'time', 'text') + expect(packet.time).to.be.a('number') }) - const resultMsg = res.find(packet => packet.Text.includes('Average latency')) + const resultMsg = res.find(packet => packet.text.includes('Average latency')) expect(resultMsg).to.exist() }) }) @@ -139,12 +157,12 @@ describe('.ping', function () { collect((err, data) => { expect(err).to.not.exist() expect(data).to.be.an('array') - expect(data).to.have.lengthOf(3) + expect(data.filter(isPong)).to.have.lengthOf(1) data.forEach(packet => { - expect(packet).to.have.keys('Success', 'Time', 'Text') - expect(packet.Time).to.be.a('number') + expect(packet).to.have.keys('success', 'time', 'text') + expect(packet.time).to.be.a('number') }) - const resultMsg = data.find(packet => packet.Text.includes('Average latency')) + const resultMsg = data.find(packet => packet.text.includes('Average latency')) expect(resultMsg).to.exist() done() }) @@ -156,15 +174,22 @@ describe('.ping', function () { ipfs.pingReadableStream(otherId) .on('data', data => { expect(data).to.be.an('object') - expect(data).to.have.keys('Success', 'Time', 'Text') - packetNum++ + expect(data).to.have.keys('success', 'time', 'text') + if (isPong(data)) packetNum++ }) .on('error', err => { expect(err).not.to.exist() }) .on('end', () => { - expect(packetNum).to.be.above(2) + expect(packetNum).to.equal(1) done() }) }) + + it('message conversion fails if invalid message is received', () => { + const messageConverter = new PingMessageStream() + expect(() => { + messageConverter.write({some: 'InvalidMessage'}) + }).to.throw('Invalid ping message received') + }) }) diff --git a/test/pubsub-in-browser.spec.js b/test/pubsub-in-browser.spec.js index ce2f1139e..6a47044f9 100644 --- a/test/pubsub-in-browser.spec.js +++ b/test/pubsub-in-browser.spec.js @@ -55,7 +55,10 @@ describe('.pubsub is not supported in the browser, yet!', function () { }) }) - after((done) => ipfsd.stop(done)) + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) describe('everything errors', () => { describe('Callback API', () => { @@ -72,7 +75,7 @@ describe('.pubsub is not supported in the browser, yet!', function () { describe('.subscribe', () => { const handler = () => {} it('throws an error if called in the browser', (done) => { - ipfs.pubsub.subscribe(topic, {}, handler, (err, topics) => { + ipfs.pubsub.subscribe(topic, handler, {}, (err, topics) => { expect(err).to.exist() expect(err.message).to.equal(expectedError) done() @@ -115,7 +118,7 @@ describe('.pubsub is not supported in the browser, yet!', function () { describe('.subscribe', () => { const handler = () => {} it('throws an error if called in the browser', (done) => { - ipfs.pubsub.subscribe(topic, {}, handler) + ipfs.pubsub.subscribe(topic, handler, {}) .catch((err) => { expect(err).to.exist() expect(err.message).to.equal(expectedError) @@ -148,14 +151,11 @@ describe('.pubsub is not supported in the browser, yet!', function () { describe('.unsubscribe', () => { it('throws an error if called in the browser', (done) => { - try { - ipfs.pubsub.unsubscribe() - done('unsubscribe() didn\'t throw an error') - } catch (err) { + ipfs.pubsub.unsubscribe('test', () => {}, (err) => { expect(err).to.exist() expect(err.message).to.equal(expectedError) done() - } + }) }) }) }) diff --git a/test/refs.spec.js b/test/refs.spec.js index e8d36b541..7ce245455 100644 --- a/test/refs.spec.js +++ b/test/refs.spec.js @@ -49,7 +49,10 @@ describe('.refs', function () { ], done) }) - after((done) => ipfsd.stop(done)) + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) const result = [ { diff --git a/test/repo.spec.js b/test/repo.spec.js index f08c50ca1..8bdf95bd7 100644 --- a/test/repo.spec.js +++ b/test/repo.spec.js @@ -24,7 +24,10 @@ describe('.repo', function () { }) }) - after((done) => ipfsd.stop(done)) + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) it('.repo.gc', (done) => { ipfs.repo.gc((err, res) => { diff --git a/test/stats.spec.js b/test/stats.spec.js index 81abb945a..c7eb48c13 100644 --- a/test/stats.spec.js +++ b/test/stats.spec.js @@ -24,7 +24,10 @@ describe('stats', function () { }) }) - after((done) => ipfsd.stop(done)) + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) it('.stats.bitswap', (done) => { ipfs.stats.bitswap((err, res) => { diff --git a/test/types.spec.js b/test/types.spec.js index 5310982ae..49b68a5ef 100644 --- a/test/types.spec.js +++ b/test/types.spec.js @@ -34,7 +34,10 @@ describe('.types', function () { }) }) - after((done) => ipfsd.stop(done)) + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) it('types object', () => { expect(ipfs.types).to.be.deep.equal({ diff --git a/test/util.spec.js b/test/util.spec.js index e8372d501..f905911cc 100644 --- a/test/util.spec.js +++ b/test/util.spec.js @@ -32,7 +32,10 @@ describe('.util', () => { }) }) - after((done) => ipfsd.stop(done)) + after((done) => { + if (!ipfsd) return done() + ipfsd.stop(done) + }) it('.streamAdd', (done) => { const tfpath = path.join(__dirname, '/fixtures/testfile.txt') @@ -111,7 +114,7 @@ describe('.util', () => { describe('.urlAdd', () => { it('http', function (done) { - this.timeout(20 * 1000) + this.timeout(40 * 1000) ipfs.util.addFromURL('http://example.com/', (err, result) => { expect(err).to.not.exist() @@ -121,7 +124,7 @@ describe('.util', () => { }) it('https', function (done) { - this.timeout(20 * 1000) + this.timeout(40 * 1000) ipfs.util.addFromURL('https://example.com/', (err, result) => { expect(err).to.not.exist() @@ -131,7 +134,7 @@ describe('.util', () => { }) it('http with redirection', function (done) { - this.timeout(20 * 1000) + this.timeout(40 * 1000) ipfs.util.addFromURL('http://covers.openlibrary.org/book/id/969165.jpg', (err, result) => { expect(err).to.not.exist() @@ -140,8 +143,8 @@ describe('.util', () => { }) }) - it('.urlAdd http with redirection', function (done) { - this.timeout(20 * 1000) + it('https with redirection', function (done) { + this.timeout(40 * 1000) ipfs.util.addFromURL('https://coverartarchive.org/release/6e2a1694-d8b9-466a-aa33-b1077b2333c1', (err, result) => { expect(err).to.not.exist() @@ -157,8 +160,10 @@ describe('.util', () => { .then(out => expectTimeout(ipfs.object.get(out[0].hash), 4000)) }) - it('with wrap-with-directory=true', (done) => { - ipfs.util.addFromURL('http://ipfs.io/ipfs/QmWjppACLcFLQ2qL38unKQvJBhXH3RUtcGLPk7zmrTwV61/969165.jpg', { + it('with wrap-with-directory=true', function (done) { + this.timeout(40 * 1000) + + ipfs.util.addFromURL('http://ipfs.io/ipfs/QmWjppACLcFLQ2qL38unKQvJBhXH3RUtcGLPk7zmrTwV61/969165.jpg?foo=bar#buzz', { wrapWithDirectory: true }, (err, result) => { expect(err).to.not.exist() @@ -170,7 +175,23 @@ describe('.util', () => { }) }) - it('with invalid url', function (done) { + it('with wrap-with-directory=true and URL-escaped file name', function (done) { + this.timeout(40 * 1000) + + // Sample URL contains URL-escaped ( ) and local diacritics + ipfs.util.addFromURL('https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/Doma%C5%BElice%2C_Jir%C3%A1skova_43_%289102%29.jpg/320px-Doma%C5%BElice%2C_Jir%C3%A1skova_43_%289102%29.jpg?foo=bar#buzz', { + wrapWithDirectory: true + }, (err, result) => { + expect(err).to.not.exist() + expect(result[0].hash).to.equal('QmRJ9ExxSMV4BLF9ZJUb2mLngupm6BXZEek755VHGTJo2Y') + expect(result[0].path).to.equal('320px-Domažlice,_Jiráskova_43_(9102).jpg') + expect(result[1].hash).to.equal('QmbxsHFU3sCfr8wszDHuDLA76C2xCv9HT8L3aC1pBwgaHk') + expect(result.length).to.equal(2) + done() + }) + }) + + it('with invalid url', (done) => { ipfs.util.addFromURL('http://invalid', (err, result) => { expect(err.code).to.equal('ENOTFOUND') expect(result).to.not.exist() diff --git a/test/utils/interface-common-factory.js b/test/utils/interface-common-factory.js new file mode 100644 index 000000000..dbbf3eb18 --- /dev/null +++ b/test/utils/interface-common-factory.js @@ -0,0 +1,49 @@ +/* eslint-env mocha */ +'use strict' + +const each = require('async/each') +const IPFSFactory = require('ipfsd-ctl') +const IPFSApi = require('../../src') + +function createFactory (options) { + options = options || {} + + options.factoryOptions = options.factoryOptions || {} + options.spawnOptions = options.spawnOptions || { initOptions: { bits: 1024 } } + + const ipfsFactory = IPFSFactory.create(options.factoryOptions) + + return function createCommon () { + const nodes = [] + let setup, teardown + + if (options.createSetup) { + setup = options.createSetup({ ipfsFactory, nodes }, options) + } else { + setup = (callback) => { + callback(null, { + spawnNode (cb) { + ipfsFactory.spawn(options.spawnOptions, (err, _ipfsd) => { + if (err) { + return cb(err) + } + + nodes.push(_ipfsd) + cb(null, IPFSApi(_ipfsd.apiAddr)) + }) + } + }) + } + } + + if (options.createTeardown) { + teardown = options.createTeardown({ ipfsFactory, nodes }, options) + } else { + teardown = callback => each(nodes, (node, cb) => node.stop(cb), callback) + } + + return { setup, teardown } + } +} + +exports.create = createFactory From c19777248cf23a7f40c45439f43b2192feb8a76a Mon Sep 17 00:00:00 2001 From: AdmREQ Date: Tue, 7 Aug 2018 09:19:58 +0100 Subject: [PATCH 2/2] Fixed linting issues, added new bug fix commit from yesterday and removed redundant tests. --- CHANGELOG.md | 15 +++++++ package.json | 4 +- src/files/cat.js | 2 +- src/resolve.js | 22 ++++++++++ src/utils/load-commands.js | 1 + test/bitswap.spec.js | 66 ---------------------------- test/interface.spec.js | 4 +- test/interface/block.spec.js | 32 -------------- test/interface/bootstrap.spec.js | 32 -------------- test/interface/config.spec.js | 32 -------------- test/interface/dag.spec.js | 34 -------------- test/interface/dht.spec.js | 31 ------------- test/interface/files-mfs.spec.js | 32 -------------- test/interface/files.spec.js | 32 -------------- test/interface/key.spec.js | 32 -------------- test/interface/miscellaneous.spec.js | 33 -------------- test/interface/object.spec.js | 32 -------------- test/interface/pin.spec.js | 32 -------------- test/interface/pubsub.spec.js | 37 ---------------- test/interface/repo.spec.js | 32 -------------- test/interface/stats.spec.js | 32 -------------- test/interface/swarm.spec.js | 42 ------------------ 22 files changed, 42 insertions(+), 569 deletions(-) create mode 100644 src/resolve.js delete mode 100644 test/bitswap.spec.js delete mode 100644 test/interface/block.spec.js delete mode 100644 test/interface/bootstrap.spec.js delete mode 100644 test/interface/config.spec.js delete mode 100644 test/interface/dag.spec.js delete mode 100644 test/interface/dht.spec.js delete mode 100644 test/interface/files-mfs.spec.js delete mode 100644 test/interface/files.spec.js delete mode 100644 test/interface/key.spec.js delete mode 100644 test/interface/miscellaneous.spec.js delete mode 100644 test/interface/object.spec.js delete mode 100644 test/interface/pin.spec.js delete mode 100644 test/interface/pubsub.spec.js delete mode 100644 test/interface/repo.spec.js delete mode 100644 test/interface/stats.spec.js delete mode 100644 test/interface/swarm.spec.js diff --git a/CHANGELOG.md b/CHANGELOG.md index cabf56988..ad289e321 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ + +# [23.0.0](https://github.com/ipfs/js-ipfs-api/compare/v22.3.0...v23.0.0) (2018-08-06) + + +### Bug Fixes + +* config get ([#825](https://github.com/ipfs/js-ipfs-api/issues/825)) ([ef5a4a3](https://github.com/ipfs/js-ipfs-api/commit/ef5a4a3)) + + +### Features + +* add resolve cmd ([#826](https://github.com/ipfs/js-ipfs-api/issues/826)) ([c7ad0e4](https://github.com/ipfs/js-ipfs-api/commit/c7ad0e4)) + + + # [22.3.0](https://github.com/ipfs/js-ipfs-api/compare/v22.2.4...v22.3.0) (2018-08-02) diff --git a/package.json b/package.json index a018df4d3..d91ecea71 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ipfs-api", - "version": "22.3.0", + "version": "23.0.0-timeout", "description": "A client library for the IPFS HTTP API", "leadMaintainer": "Alan Shaw ", "main": "src/index.js", @@ -80,7 +80,7 @@ "eslint-plugin-react": "^7.10.0", "go-ipfs-dep": "~0.4.17", "gulp": "^3.9.1", - "interface-ipfs-core": "~0.75.0", + "interface-ipfs-core": "~0.75.1", "ipfsd-ctl": "~0.39.0", "pull-stream": "^3.6.8", "socket.io": "^2.1.1", diff --git a/src/files/cat.js b/src/files/cat.js index 7314bfefb..b70ced601 100644 --- a/src/files/cat.js +++ b/src/files/cat.js @@ -25,7 +25,7 @@ module.exports = (send) => { length: opts.length } - send({ path: 'cat', args: hash, buffer: opts.buffer, qs: query, timeout: opts.timeout}, (err, stream) => { + send({ path: 'cat', args: hash, buffer: opts.buffer, qs: query, timeout: opts.timeout }, (err, stream) => { if (err) { return callback(err) } stream.pipe(bl((err, data) => { diff --git a/src/resolve.js b/src/resolve.js new file mode 100644 index 000000000..05b62282d --- /dev/null +++ b/src/resolve.js @@ -0,0 +1,22 @@ +'use strict' + +const promisify = require('promisify-es6') + +const transform = function (res, callback) { + callback(null, res.Path) +} + +module.exports = (send) => { + return promisify((args, opts, callback) => { + if (typeof (opts) === 'function') { + callback = opts + opts = {} + } + + send.andTransform({ + path: 'resolve', + args: args, + qs: opts + }, transform, callback) + }) +} diff --git a/src/utils/load-commands.js b/src/utils/load-commands.js index ec56d2a11..55b4570ab 100644 --- a/src/utils/load-commands.js +++ b/src/utils/load-commands.js @@ -43,6 +43,7 @@ function requireCommands () { update: require('../update'), version: require('../version'), types: require('../types'), + resolve: require('../resolve'), dns: require('../dns') } diff --git a/test/bitswap.spec.js b/test/bitswap.spec.js deleted file mode 100644 index b878cf67c..000000000 --- a/test/bitswap.spec.js +++ /dev/null @@ -1,66 +0,0 @@ -/* eslint-env mocha */ -'use strict' - -const chai = require('chai') -const dirtyChai = require('dirty-chai') -const expect = chai.expect -chai.use(dirtyChai) - -const IPFSApi = require('../src') - -const f = require('./utils/factory') - -describe('.bitswap', function () { - this.timeout(20 * 1000) // slow CI - - let ipfs - let ipfsd = null - - before(function (done) { - this.timeout(20 * 1000) // slow CI - - f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { - expect(err).to.not.exist() - ipfsd = _ipfsd - ipfs = IPFSApi(_ipfsd.apiAddr) - done() - }) - }) - - after((done) => ipfsd.stop(done)) - - it('.wantlist', (done) => { - ipfs.bitswap.wantlist((err, res) => { - expect(err).to.not.exist() - expect(res).to.have.to.eql({ - Keys: [] - }) - done() - }) - }) - - it('.stat', (done) => { - ipfs.bitswap.stat((err, res) => { - expect(err).to.not.exist() - expect(res).to.have.a.property('provideBufLen') - expect(res).to.have.a.property('wantlist') - expect(res).to.have.a.property('peers') - expect(res).to.have.a.property('blocksReceived') - expect(res).to.have.a.property('dataReceived') - expect(res).to.have.a.property('blocksSent') - expect(res).to.have.a.property('dataSent') - expect(res).to.have.a.property('dupBlksReceived') - expect(res).to.have.a.property('dupDataReceived') - - done() - }) - }) - - it('.unwant', (done) => { - const key = 'Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP' - ipfs.bitswap.unwant(key, (err) => { - expect(err).to.not.exist() - done() - }) - }) -}) diff --git a/test/interface.spec.js b/test/interface.spec.js index a3130159d..5f169433f 100644 --- a/test/interface.spec.js +++ b/test/interface.spec.js @@ -174,9 +174,7 @@ describe('interface-ipfs-core tests', () => { { name: 'should stop the node', reason: 'FIXME go-ipfs returns an error https://github.com/ipfs/go-ipfs/issues/4078' - }, - // resolve - 'resolve' + } ] }) diff --git a/test/interface/block.spec.js b/test/interface/block.spec.js deleted file mode 100644 index 180f17a04..000000000 --- a/test/interface/block.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-env mocha */ - -'use strict' - -const test = require('interface-ipfs-core') -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } -} - -test.block(common) diff --git a/test/interface/bootstrap.spec.js b/test/interface/bootstrap.spec.js deleted file mode 100644 index caea5856e..000000000 --- a/test/interface/bootstrap.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-env mocha */ - -'use strict' - -const test = require('interface-ipfs-core') -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } -} - -test.bootstrap(common) diff --git a/test/interface/config.spec.js b/test/interface/config.spec.js deleted file mode 100644 index aeb4a6a9a..000000000 --- a/test/interface/config.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-env mocha */ -/* eslint max-nested-callbacks: ["error", 8] */ -'use strict' - -const test = require('interface-ipfs-core') -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } -} - -test.config(common) diff --git a/test/interface/dag.spec.js b/test/interface/dag.spec.js deleted file mode 100644 index 6c68680e7..000000000 --- a/test/interface/dag.spec.js +++ /dev/null @@ -1,34 +0,0 @@ -/* eslint-env mocha */ - -'use strict' - -const test = require('interface-ipfs-core') -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') - -const DaemonFactory = require('ipfsd-ctl') -const df = DaemonFactory.create() - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - df.spawn((err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } -} - -test.dag(common) diff --git a/test/interface/dht.spec.js b/test/interface/dht.spec.js deleted file mode 100644 index 2b324cb99..000000000 --- a/test/interface/dht.spec.js +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint-env mocha */ -'use strict' - -const test = require('interface-ipfs-core') -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } -} - -test.dht(common) diff --git a/test/interface/files-mfs.spec.js b/test/interface/files-mfs.spec.js deleted file mode 100644 index 6de81af4e..000000000 --- a/test/interface/files-mfs.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-env mocha */ -/* eslint max-nested-callbacks: ["error", 8] */ -'use strict' - -const test = require('interface-ipfs-core') -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } -} - -test.filesMFS(common) diff --git a/test/interface/files.spec.js b/test/interface/files.spec.js deleted file mode 100644 index c99f768a6..000000000 --- a/test/interface/files.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-env mocha */ -/* eslint max-nested-callbacks: ["error", 8] */ -'use strict' - -const test = require('interface-ipfs-core') -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } -} - -test.files(common) diff --git a/test/interface/key.spec.js b/test/interface/key.spec.js deleted file mode 100644 index 56f6e6893..000000000 --- a/test/interface/key.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-env mocha */ - -'use strict' - -const test = require('interface-ipfs-core') -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } -} - -test.key(common) diff --git a/test/interface/miscellaneous.spec.js b/test/interface/miscellaneous.spec.js deleted file mode 100644 index c890a2fa3..000000000 --- a/test/interface/miscellaneous.spec.js +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-env mocha */ - -'use strict' - -const test = require('interface-ipfs-core') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - // No need to stop, because the test suite does a 'stop' test. - // parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - callback() - } -} - -test.generic(common) diff --git a/test/interface/object.spec.js b/test/interface/object.spec.js deleted file mode 100644 index e76c45673..000000000 --- a/test/interface/object.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-env mocha */ - -'use strict' - -const test = require('interface-ipfs-core') -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } -} - -test.object(common) diff --git a/test/interface/pin.spec.js b/test/interface/pin.spec.js deleted file mode 100644 index e56bc413d..000000000 --- a/test/interface/pin.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-env mocha */ -/* eslint max-nested-callbacks: ["error", 8] */ -'use strict' - -const test = require('interface-ipfs-core') -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } -} - -test.pin(common) diff --git a/test/interface/pubsub.spec.js b/test/interface/pubsub.spec.js deleted file mode 100644 index 154fec2f4..000000000 --- a/test/interface/pubsub.spec.js +++ /dev/null @@ -1,37 +0,0 @@ -/* eslint-env mocha */ - -'use strict' - -const test = require('interface-ipfs-core') -const isNode = require('detect-node') - -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -if (isNode) { - const nodes = [] - const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - f.spawn({ initOptions: { bits: 1024 }, args: ['--enable-pubsub-experiment'] }, - (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } - } - - test.pubsub(common) -} diff --git a/test/interface/repo.spec.js b/test/interface/repo.spec.js deleted file mode 100644 index c6966772d..000000000 --- a/test/interface/repo.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-env mocha */ -/* eslint max-nested-callbacks: ["error", 8] */ -'use strict' - -const test = require('interface-ipfs-core') -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } -} - -test.repo(common) diff --git a/test/interface/stats.spec.js b/test/interface/stats.spec.js deleted file mode 100644 index eee30ad98..000000000 --- a/test/interface/stats.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-env mocha */ - -'use strict' - -const test = require('interface-ipfs-core') -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (cb) => { - f.spawn({ initOptions: { bits: 1024 } }, (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } -} - -test.stats(common) diff --git a/test/interface/swarm.spec.js b/test/interface/swarm.spec.js deleted file mode 100644 index 56b9cbe41..000000000 --- a/test/interface/swarm.spec.js +++ /dev/null @@ -1,42 +0,0 @@ -/* eslint-env mocha */ -/* eslint max-nested-callbacks: ["error", 8] */ -'use strict' - -const test = require('interface-ipfs-core') -const parallel = require('async/parallel') - -const IPFSApi = require('../../src') -const f = require('../utils/factory') - -const nodes = [] -const common = { - setup: function (callback) { - callback(null, { - spawnNode: (repoPath, config, cb) => { - if (typeof repoPath === 'function') { - cb = repoPath - repoPath = undefined - } - - if (typeof config === 'function') { - cb = config - config = undefined - } - - f.spawn({ repoPath, config, initOptions: { bits: 1024 } }, (err, _ipfsd) => { - if (err) { - return cb(err) - } - - nodes.push(_ipfsd) - cb(null, IPFSApi(_ipfsd.apiAddr)) - }) - } - }) - }, - teardown: function (callback) { - parallel(nodes.map((node) => (cb) => node.stop(cb)), callback) - } -} - -test.swarm(common)