From 3e5967af8e456517485c8a7536792107c0ed6e63 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Fri, 22 Nov 2019 11:45:30 +0000 Subject: [PATCH] refactor: async await roundup (#1173) This is a round up of the remaining async/await PRs along with some cleanup and docs fixes. resolves #1103 resolves https://github.com/ipfs/js-ipfs-http-client/issues/1122 resolves https://github.com/ipfs/js-ipfs-http-client/issues/1158 (hopefully!) closes https://github.com/ipfs/js-ipfs-http-client/pull/1164 closes https://github.com/ipfs/js-ipfs-http-client/pull/1165 closes https://github.com/ipfs/js-ipfs-http-client/pull/1166 closes https://github.com/ipfs/js-ipfs-http-client/pull/1169 closes https://github.com/ipfs/js-ipfs-http-client/pull/1170 closes https://github.com/ipfs/js-ipfs-http-client/pull/1172 BREAKING CHANGE: The `log.tail` method now returns an async iterator that yields log messages. Use it like: ```js for await (const message of ipfs.log.tail()) { console.log(message) } ``` BREAKING CHANGE: The response to a call to `log.level` now returns an object that has camel cased keys. i.e. `Message` and `Error` properties have changed to `message` and `error`. BREAKING CHANGE: Dropped support for go-ipfs <= 0.4.4 in `swarm.peers` response. BREAKING CHANGE: The signature for `ipfs.mount` has changed from `ipfs.mount([ipfsPath], [ipnsPath])` to `ipfs.mount([options])`. Where `options` is an optional object that may contain two boolean properties `ipfsPath` and `ipnsPath`. The response object has also changed to be camel case. See https://docs.ipfs.io/reference/api/http/#api-v0-mount. BREAKING CHANGE: Default ping `count` of 1 in client has been removed. The default ping count is now whatever the IPFS node defaults it to (currently 10). If you specifically need 1 ping message then please pass `count: 1` in options for `ipfs.ping()`. BREAKING CHANGE: Multi parameter constructor options are no longer supported. To create a new IPFS HTTP client, pass a single parameter to the constructor. The parameter can be one of: * String, formatted as one of: * Multiaddr e.g. /ip4/127.0.0.1/tcp/5001 * URL e.g. http://127.0.0.1:5001 * [Multiaddr](https://www.npmjs.com/package/multiaddr) instance * Object, in format of either: * Address and path e.g. `{ apiAddr: '/ip4/127.0.0.1/tcp/5001': apiPath: '/api/v0' }` (Note: `apiAddr` can also be a string in URL form or a Multiaddr instance) * Node.js style address e.g. `{ host: '127.0.0.1', port: 5001, protocol: 'http' }` --- README.md | 231 +++++++++-------- package.json | 32 +-- src/add-from-url.js | 4 +- src/add/index.js | 4 +- src/bitswap/stat.js | 2 +- src/bitswap/unwant.js | 2 +- src/bitswap/wantlist.js | 2 +- src/block/get.js | 2 +- src/block/rm-async-iterator.js | 2 +- src/block/stat.js | 2 +- src/bootstrap/list.js | 2 +- src/cat.js | 6 +- src/commands.js | 29 ++- src/config/get.js | 2 +- src/config/profiles/list.js | 2 +- src/dag/resolve.js | 2 +- src/dht/find-peer.js | 6 +- src/dht/find-provs.js | 6 +- src/dht/get.js | 6 +- src/dht/provide.js | 6 +- src/dht/put.js | 6 +- src/dht/query.js | 6 +- src/diag/cmds.js | 2 +- src/diag/net.js | 2 +- src/diag/sys.js | 2 +- src/dns.js | 35 ++- src/get-endpoint-config.js | 15 +- src/get.js | 16 +- src/id.js | 41 +-- src/index.js | 191 ++++++++++---- src/key/export.js | 35 ++- src/key/gen.js | 39 ++- src/key/import.js | 44 ++-- src/key/index.js | 22 +- src/key/list.js | 35 +-- src/key/rename.js | 37 +-- src/key/rm.js | 33 +-- src/lib/configure.js | 31 ++- src/lib/multiaddr.js | 18 -- src/log/index.js | 16 +- src/log/level.js | 40 ++- src/log/ls.js | 27 +- src/log/tail.js | 32 +-- src/ls.js | 16 +- src/mount.js | 43 ++-- src/name/index.js | 16 +- src/name/publish.js | 43 ++-- src/name/pubsub/cancel.js | 36 ++- src/name/pubsub/index.js | 10 +- src/name/pubsub/state.js | 32 +-- src/name/pubsub/subs.js | 29 +-- src/name/resolve.js | 37 +-- src/object/data.js | 4 +- src/object/get.js | 2 +- src/object/links.js | 2 +- src/pin/ls.js | 2 +- src/ping-pull-stream.js | 34 --- src/ping-readable-stream.js | 30 --- src/ping.js | 81 ++---- src/pubsub/ls.js | 2 +- src/pubsub/peers.js | 2 +- src/refs/index.js | 18 +- src/refs/local.js | 2 +- src/repo/gc.js | 48 ++-- src/repo/index.js | 17 +- src/repo/stat.js | 44 ++-- src/repo/version.js | 32 +-- src/resolve.js | 75 ++---- src/stats/bitswap.js | 32 --- src/stats/bw-pull-stream.js | 31 --- src/stats/bw-readable-stream.js | 31 --- src/stats/bw-util.js | 12 - src/stats/bw.js | 51 ++-- src/stats/index.js | 22 +- src/stats/repo.js | 28 -- src/stop.js | 20 +- src/swarm/addrs.js | 40 ++- src/swarm/connect.js | 33 ++- src/swarm/disconnect.js | 33 ++- src/swarm/index.js | 20 +- src/swarm/localAddrs.js | 38 ++- src/swarm/peers.js | 104 +++----- src/update.js | 47 +--- src/utils/clean-cid.js | 17 -- src/utils/clean-multihash.js | 21 -- src/utils/default-config.js | 13 - src/utils/load-commands.js | 161 ------------ src/utils/module-config.js | 22 -- src/utils/multipart.js | 121 --------- src/utils/ping-message-converter.js | 23 -- src/utils/ping-message-stream.js | 27 -- src/utils/prepare-file.js | 153 ----------- src/utils/progress-stream.js | 49 ---- src/utils/send-files-stream.js | 161 ------------ src/utils/send-one-file-multiple-results.js | 18 -- src/utils/send-one-file.js | 15 -- src/utils/send-request.js | 239 ------------------ src/utils/stream-to-json-value.js | 34 --- src/utils/stream-to-value-with-transformer.js | 18 -- src/utils/stream-to-value.js | 18 -- src/version.js | 39 +-- test/constructor.spec.js | 21 +- test/custom-headers.spec.js | 21 +- test/endpoint-config.spec.js | 35 +-- test/lib.configure.spec.js | 13 +- test/log.spec.js | 23 +- test/node/swarm.js | 18 -- test/ping.spec.js | 54 +--- test/sub-modules.spec.js | 52 ++-- 109 files changed, 1079 insertions(+), 2581 deletions(-) delete mode 100644 src/lib/multiaddr.js delete mode 100644 src/ping-pull-stream.js delete mode 100644 src/ping-readable-stream.js delete mode 100644 src/stats/bitswap.js delete mode 100644 src/stats/bw-pull-stream.js delete mode 100644 src/stats/bw-readable-stream.js delete mode 100644 src/stats/bw-util.js delete mode 100644 src/stats/repo.js delete mode 100644 src/utils/clean-cid.js delete mode 100644 src/utils/clean-multihash.js delete mode 100644 src/utils/default-config.js delete mode 100644 src/utils/load-commands.js delete mode 100644 src/utils/module-config.js delete mode 100644 src/utils/multipart.js delete mode 100644 src/utils/ping-message-converter.js delete mode 100644 src/utils/ping-message-stream.js delete mode 100644 src/utils/prepare-file.js delete mode 100644 src/utils/progress-stream.js delete mode 100644 src/utils/send-files-stream.js delete mode 100644 src/utils/send-one-file-multiple-results.js delete mode 100644 src/utils/send-one-file.js delete mode 100644 src/utils/send-request.js delete mode 100644 src/utils/stream-to-json-value.js delete mode 100644 src/utils/stream-to-value-with-transformer.js delete mode 100644 src/utils/stream-to-value.js diff --git a/README.md b/README.md index 4e27f3db3..5c6a00070 100644 --- a/README.md +++ b/README.md @@ -43,14 +43,16 @@ - [In a web browser](#in-a-web-browser) - [CORS](#cors) - [Custom Headers](#custom-headers) + - [Global Timeouts](#global-timeouts) - [Usage](#usage) - [API](#api) - [Files](#files) - [Graph](#graph) - [Network](#network) - [Node Management](#node-management) - - [Instance utils](#instance-utils) - - [Static types and utils](#static-types-and-utils) + - [Additional Options](#additional-options) + - [Instance Utils](#instance-utils) + - [Static Types and Utils](#static-types-and-utils) - [Development](#development) - [Testing](#testing) - [Contribute](#contribute) @@ -86,19 +88,19 @@ To interact with the API, you need to have a local daemon running. It needs to b ### Importing the module and usage ```javascript -var ipfsClient = require('ipfs-http-client') +const ipfsClient = require('ipfs-http-client') // connect to ipfs daemon API server -var ipfs = ipfsClient('localhost', '5001', { protocol: 'http' }) // leaving out the arguments will default to these values +const ipfs = ipfsClient('http://localhost:5001') // (the default in Node.js) // or connect with multiaddr -var ipfs = ipfsClient('/ip4/127.0.0.1/tcp/5001') +const ipfs = ipfsClient('/ip4/127.0.0.1/tcp/5001') // or using options -var ipfs = ipfsClient({ host: 'localhost', port: '5001', protocol: 'http' }) +const ipfs = ipfsClient({ host: 'localhost', port: '5001', protocol: 'http' }) // or specifying a specific API path -var ipfs = ipfsClient({ host: '1.1.1.1', port: '80', 'api-path': '/ipfs/api/v0' }) +const ipfs = ipfsClient({ host: '1.1.1.1', port: '80', apiPath: '/ipfs/api/v0' }) ``` ### Importing a sub-module and usage @@ -106,9 +108,8 @@ var ipfs = ipfsClient({ host: '1.1.1.1', port: '80', 'api-path': '/ipfs/api/v0' ```javascript const bitswap = require('ipfs-http-client/src/bitswap')('/ip4/127.0.0.1/tcp/5001') -bitswap.wantlist(key, (err) => { - // ... -}) +const list = await bitswap.wantlist(key) +// ... ``` ### In a web browser @@ -130,12 +131,11 @@ Instead of a local installation (and browserification) you may request a remote To always request the latest version, use the following: ```html - - - ``` +Note: remove the `.min` from the URL to get the human-readable (not minified) version. + 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) @@ -153,7 +153,7 @@ crossorigin="anonymous"> CDN-based IPFS API provides the `IpfsHttpClient` constructor as a method of the global `window` object. Example: ```js -const ipfs = window.IpfsHttpClient('localhost', '5001') +const ipfs = window.IpfsHttpClient({ host: 'localhost', port: 5001 }) ``` If you omit the host and port, the client 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: @@ -186,6 +186,18 @@ const ipfs = ipfsClient({ }) ``` +### Global Timeouts + +To set a global timeout for _all_ requests pass a value for the `timeout` option: + +```js +// Timeout after 10 seconds +const ipfs = ipfsClient({ timeout: 10000 }) +// Timeout after 2 minutes +const ipfs = ipfsClient({ timeout: '2m' }) +// see https://www.npmjs.com/package/parse-duration for valid string values +``` + ## Usage ### API @@ -197,74 +209,74 @@ const ipfs = ipfsClient({ #### Files - [Regular Files API](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md) - - [`ipfs.add(data, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#add) + - [`ipfs.add(data, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#add) - [`ipfs.addPullStream([options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addpullstream) - [`ipfs.addReadableStream([options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addreadablestream) - - [`ipfs.addFromStream(stream, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addfromstream) - - [`ipfs.addFromFs(path, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addfromfs) - - [`ipfs.addFromURL(url, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addfromurl) - - [`ipfs.cat(ipfsPath, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#cat) + - [`ipfs.addFromStream(stream)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addfromstream) + - [`ipfs.addFromFs(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addfromfs) + - [`ipfs.addFromURL(url, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#addfromurl) + - [`ipfs.cat(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#cat) - [`ipfs.catPullStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#catpullstream) - [`ipfs.catReadableStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#catreadablestream) - - [`ipfs.get(ipfsPath, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#get) + - [`ipfs.get(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#get) - [`ipfs.getPullStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#getpullstream) - [`ipfs.getReadableStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#getreadablestream) - - [`ipfs.ls(ipfsPath, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#ls) + - [`ipfs.ls(ipfsPath)`](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) _Explore the Mutable File System through interactive coding challenges in our [ProtoSchool tutorial](https://proto.school/#/mutable-file-system/)._ - - [`ipfs.files.cp([from, to], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filescp) - - [`ipfs.files.flush([path], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesflush) - - [`ipfs.files.ls([path], [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesls) - - [`ipfs.files.mkdir(path, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesmkdir) - - [`ipfs.files.mv([from, to], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesmv) - - [`ipfs.files.read(path, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesread) + - [`ipfs.files.cp([from, to])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filescp) + - [`ipfs.files.flush([path])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesflush) + - [`ipfs.files.ls([path], [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesls) + - [`ipfs.files.mkdir(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesmkdir) + - [`ipfs.files.mv([from, to])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesmv) + - [`ipfs.files.read(path, [options])`](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) + - [`ipfs.files.rm(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesrm) + - [`ipfs.files.stat(path, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#filesstat) + - [`ipfs.files.write(path, content, [options])`](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) + - [`ipfs.block.get(cid, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BLOCK.md#blockget) + - [`ipfs.block.put(block, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BLOCK.md#blockput) + - [`ipfs.block.stat(cid)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BLOCK.md#blockstat) - [refs](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REFS.md) - - [`ipfs.refs(ipfsPath, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REFS.md#refs) - - [`ipfs.refsReadableStream(ipfsPath, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REFS.md#refsreadablestream) - - [`ipfs.refsPullStream(ipfsPath, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REFS.md#refspullstream) - - [`ipfs.refs.local([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REFS.md#refslocal) - - [`ipfs.refs.localReadableStream([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REFS.md#refslocalreadablestream) - - [`ipfs.refs.localPullStream([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REFS.md#refslocalpullstream) + - [`ipfs.refs(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REFS.md#refs) + - [`ipfs.refsReadableStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REFS.md#refsreadablestream) + - [`ipfs.refsPullStream(ipfsPath, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REFS.md#refspullstream) + - [`ipfs.refs.local()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REFS.md#refslocal) + - [`ipfs.refs.localReadableStream()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REFS.md#refslocalreadablestream) + - [`ipfs.refs.localPullStream()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REFS.md#refslocalpullstream) #### Graph - [dag](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DAG.md) _Explore the DAG API through interactive coding challenges in our [ProtoSchool tutorial](https://proto.school/#/basics)._ - - [`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) + - [`ipfs.dag.get(cid, [path], [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DAG.md#dagget) + - [`ipfs.dag.put(dagNode, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DAG.md#dagput) + - [`ipfs.dag.tree(cid, [path], [options])`](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) + - [`ipfs.object.data(multihash, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectdata) + - [`ipfs.object.get(multihash, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectget) + - [`ipfs.object.links(multihash, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectlinks) + - [`ipfs.object.new([template])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectnew) + - [`ipfs.object.patch.addLink(multihash, DAGLink, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectpatchaddlink) + - [`ipfs.object.patch.appendData(multihash, data, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectpatchappenddata) + - [`ipfs.object.patch.rmLink(multihash, DAGLink, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectpatchrmlink) + - [`ipfs.object.patch.setData(multihash, data, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectpatchsetdata) + - [`ipfs.object.put(obj, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/OBJECT.md#objectput) + - [`ipfs.object.stat(multihash, [options])`](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) + - [`ipfs.pin.add(hash, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md#pinadd) + - [`ipfs.pin.ls([hash], [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md#pinls) + - [`ipfs.pin.rm(hash, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PIN.md#pinrm) - refs - `ipfs.refs.local()` @@ -272,92 +284,101 @@ const ipfs = ipfsClient({ #### 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) + - [`ipfs.bootstrap.add(addr, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BOOTSTRAP.md#bootstrapadd) + - [`ipfs.bootstrap.list()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/BOOTSTRAP.md#bootstraplist) + - [`ipfs.bootstrap.rm(addr, [options])`](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.stat()`](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) + - [`ipfs.dht.findPeer(peerId)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtfindpeer) + - [`ipfs.dht.findProvs(hash)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtfindprovs) + - [`ipfs.dht.get(key)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtget) + - [`ipfs.dht.provide(cid)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/DHT.md#dhtprovide) + - [`ipfs.dht.put(key, value)`](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) + - [`ipfs.pubsub.ls(topic)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PUBSUB.md#pubsubls) + - [`ipfs.pubsub.peers(topic)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PUBSUB.md#pubsubpeers) + - [`ipfs.pubsub.publish(topic, data)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PUBSUB.md#pubsubpublish) + - [`ipfs.pubsub.subscribe(topic, handler, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PUBSUB.md#pubsubsubscribe) + - [`ipfs.pubsub.unsubscribe(topic, handler)`](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) + - [`ipfs.swarm.addrs()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/SWARM.md#swarmaddrs) + - [`ipfs.swarm.connect(addr)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/SWARM.md#swarmconnect) + - [`ipfs.swarm.disconnect(addr)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/SWARM.md#swarmdisconnect) + - [`ipfs.swarm.peers([options])`](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.pubsub.cancel(arg, [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#namepubsubcancel) - - [`ipfs.name.pubsub.state([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#namepubsubstate) - - [`ipfs.name.pubsub.subs([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#namepubsubsubs) - - [`ipfs.name.resolve(addr, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#nameresolve) + - [`ipfs.name.publish(addr, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#namepublish) + - [`ipfs.name.pubsub.cancel(arg)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#namepubsubcancel) + - [`ipfs.name.pubsub.state()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#namepubsubstate) + - [`ipfs.name.pubsub.subs()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/NAME.md#namepubsubsubs) + - [`ipfs.name.resolve(addr, [options])`](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.dns(domain)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/MISCELLANEOUS.md#dns) + - [`ipfs.id()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/MISCELLANEOUS.md#id) + - [`ipfs.ping(id, [options])`](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) + - [`ipfs.stop()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/MISCELLANEOUS.md#stop). Alias to `ipfs.shutdown`. + - [`ipfs.version()`](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) - - [`ipfs.config.profiles.list([callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/CONFIG.md#configprofileslist) - - [`ipfs.config.profiles.apply(name, [options], [callback])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/CONFIG.md#configprofilesapply) + - [`ipfs.config.get([key])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/CONFIG.md#configget) + - [`ipfs.config.replace(config)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/CONFIG.md#configreplace) + - [`ipfs.config.set(key, value)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/CONFIG.md#configset) + - [`ipfs.config.profiles.list()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/CONFIG.md#configprofileslist) + - [`ipfs.config.profiles.apply(name, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/CONFIG.md#configprofilesapply) - [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.bitswap()`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/STATS.md#statsbitswap) + - [`ipfs.stats.bw([options])`](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) + - [`ipfs.stats.repo([options])`](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])` + - `ipfs.log.ls()` + - `ipfs.log.tail()` - [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) + - [`ipfs.repo.gc([options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REPO.md#repogc) + - [`ipfs.repo.stat([options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/REPO.md#repostat) + - [`ipfs.repo.version()`](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.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) + - [`ipfs.key.export(name, password)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyexport) + - [`ipfs.key.gen(name, [options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keygen) + - [`ipfs.key.import(name, pem, password)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyimport) + - [`ipfs.key.list([options])`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keylist) + - [`ipfs.key.rename(oldName, newName)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyrename) + - [`ipfs.key.rm(name)`](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/KEY.md#keyrm) + +#### Additional Options + +All core API methods take _additional_ `options` specific to the HTTP API: + +* `headers` - An object or [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) instance that can be used to set custom HTTP headers. Note that this option can also be [configured globally](#custom-headers) via the constructor options. +* `signal` - An [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that can be used to abort the request on demand. +* `timeout` - A number or string specifying a timeout for the request. If the timeout is reached before data is received a [`TimeoutError`](https://github.com/sindresorhus/ky/blob/2f37c3f999efb36db9108893b8b3d4b3a7f5ec45/index.js#L127-L132) is thrown. If a number is specified it is interpreted as milliseconds, if a string is passed, it is intepreted according to [`parse-duration`](https://www.npmjs.com/package/parse-duration). Note that this option can also be [configured globally](#global-timeouts) via the constructor options. +* `searchParams` - An object or [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) instance that can be used to add additional query parameters to the query string sent with each request. -#### Instance utils +#### Instance Utils - `ipfs.getEndpointConfig()` Call this on your client instance to return an object containing the `host`, `port`, `protocol` and `api-path`. -#### Static types and utils +#### Static Types and Utils Aside from the default export, `ipfs-http-client` exports various types and utilities that are included in the bundle: diff --git a/package.json b/package.json index 4b305550a..8fc450b79 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,6 @@ }, "dependencies": { "abort-controller": "^3.0.0", - "async": "^2.6.1", "async-iterator-all": "^1.0.0", "async-iterator-to-pull-stream": "^1.3.0", "bignumber.js": "^9.0.0", @@ -51,58 +50,47 @@ "buffer": "^5.4.2", "callbackify": "^1.1.0", "cids": "~0.7.1", - "concat-stream": "github:hugomrdias/concat-stream#feat/smaller", "debug": "^4.1.0", - "detect-node": "^2.0.4", "err-code": "^2.0.0", "explain-error": "^1.0.4", - "flatmap": "0.0.3", "form-data": "^3.0.0", - "glob": "^7.1.3", "ipfs-block": "~0.8.1", "ipfs-utils": "^0.4.0", "ipld-dag-cbor": "~0.15.0", "ipld-dag-pb": "^0.18.1", "ipld-raw": "^4.0.0", "is-ipfs": "~0.6.1", - "is-pull-stream": "0.0.0", - "is-stream": "^2.0.0", - "iso-stream-http": "~0.1.2", "it-glob": "0.0.6", - "it-tar": "^1.1.0", + "it-tar": "^1.1.1", "it-to-stream": "^0.1.1", "iterable-ndjson": "^1.1.0", - "kind-of": "^6.0.2", "ky": "^0.15.0", "ky-universal": "^0.3.0", "merge-options": "^2.0.0", "multiaddr": "^6.0.6", + "multiaddr-to-uri": "^5.0.0", "multibase": "~0.6.0", "multicodec": "~0.5.1", "multihashes": "~0.4.14", - "ndjson": "github:hugomrdias/ndjson#feat/readable-stream3", - "once": "^1.4.0", "parse-duration": "^0.1.1", "peer-id": "~0.12.3", "peer-info": "~0.15.1", - "promise-nodeify": "^3.0.1", - "promisify-es6": "^1.0.3", - "pull-defer": "~0.2.3", - "pull-stream": "^3.6.9", - "pull-to-stream": "~0.1.1", - "pump": "^3.0.0", - "qs": "^6.5.2", - "readable-stream": "^3.1.1", - "stream-to-pull-stream": "^1.7.2" + "promise-nodeify": "^3.0.1" }, "devDependencies": { "aegir": "^20.4.1", + "async": "^3.1.0", "browser-process-platform": "~0.1.1", "cross-env": "^6.0.0", + "detect-node": "^2.0.4", "go-ipfs-dep": "^0.4.22", - "interface-ipfs-core": "^0.120.0", + "interface-ipfs-core": "^0.121.0", "ipfsd-ctl": "^0.47.1", + "ndjson": "^1.5.0", "nock": "^11.4.0", + "promisify-es6": "^1.0.3", + "pull-stream": "^3.6.14", + "pump": "^3.0.0", "stream-equal": "^1.1.1" }, "engines": { diff --git a/src/add-from-url.js b/src/add-from-url.js index 388072984..deb3f4bad 100644 --- a/src/add-from-url.js +++ b/src/add-from-url.js @@ -6,7 +6,7 @@ const toIterable = require('./lib/stream-to-iterable') module.exports = (config) => { const add = require('./add')(config) - return (url, options) => (async function * () { + return async function * addFromURL (url, options) { options = options || {} const { body } = await kyDefault.get(url) @@ -17,5 +17,5 @@ module.exports = (config) => { } yield * add(input, options) - })() + } } diff --git a/src/add/index.js b/src/add/index.js index 8b8ba7690..b1a8bb2a1 100644 --- a/src/add/index.js +++ b/src/add/index.js @@ -7,7 +7,7 @@ const { toFormData } = require('./form-data') const toCamel = require('../lib/object-to-camel') module.exports = configure(({ ky }) => { - return (input, options) => (async function * () { + return async function * add (input, options) { options = options || {} const searchParams = new URLSearchParams(options.searchParams) @@ -47,7 +47,7 @@ module.exports = configure(({ ky }) => { yield toCoreInterface(file) } } - })() + } }) function toCoreInterface ({ name, hash, size }) { diff --git a/src/bitswap/stat.js b/src/bitswap/stat.js index 3795327bb..fee13c355 100644 --- a/src/bitswap/stat.js +++ b/src/bitswap/stat.js @@ -7,7 +7,7 @@ module.exports = configure(({ ky }) => { return async (options) => { options = options || {} - const res = await ky.get('bitswap/stat', { + const res = await ky.post('bitswap/stat', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/bitswap/unwant.js b/src/bitswap/unwant.js index 9b2044d00..a66653d69 100644 --- a/src/bitswap/unwant.js +++ b/src/bitswap/unwant.js @@ -15,7 +15,7 @@ module.exports = configure(({ ky }) => { searchParams.set('arg', new CID(cid).toString()) } - const res = await ky.get('bitswap/unwant', { + const res = await ky.post('bitswap/unwant', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/bitswap/wantlist.js b/src/bitswap/wantlist.js index 3235de8a9..6b087db1b 100644 --- a/src/bitswap/wantlist.js +++ b/src/bitswap/wantlist.js @@ -17,7 +17,7 @@ module.exports = configure(({ ky }) => { } } - const res = await ky.get('bitswap/wantlist', { + const res = await ky.post('bitswap/wantlist', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/block/get.js b/src/block/get.js index 6e28643f3..b53b38f64 100644 --- a/src/block/get.js +++ b/src/block/get.js @@ -13,7 +13,7 @@ module.exports = configure(({ ky }) => { const searchParams = new URLSearchParams(options.searchParams) searchParams.set('arg', `${cid}`) - const data = await ky.get('block/get', { + const data = await ky.post('block/get', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/block/rm-async-iterator.js b/src/block/rm-async-iterator.js index b934df32b..e44aedcd2 100644 --- a/src/block/rm-async-iterator.js +++ b/src/block/rm-async-iterator.js @@ -7,7 +7,7 @@ const toIterable = require('../lib/stream-to-iterable') const toCamel = require('../lib/object-to-camel') module.exports = configure(({ ky }) => { - return async function * removeBlock (cid, options) { + return async function * rm (cid, options) { options = options || {} if (!Array.isArray(cid)) { diff --git a/src/block/stat.js b/src/block/stat.js index 4d0b82787..9063d137c 100644 --- a/src/block/stat.js +++ b/src/block/stat.js @@ -16,7 +16,7 @@ module.exports = configure(({ ky }) => { const searchParams = new URLSearchParams(options.searchParams) searchParams.set('arg', `${cid}`) - const res = await ky.get('block/stat', { + const res = await ky.post('block/stat', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/bootstrap/list.js b/src/bootstrap/list.js index 2a20f5d05..2a6bbef4b 100644 --- a/src/bootstrap/list.js +++ b/src/bootstrap/list.js @@ -6,7 +6,7 @@ module.exports = configure(({ ky }) => { return async (options) => { options = options || {} - const res = await ky.get('bootstrap/list', { + const res = await ky.post('bootstrap/list', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/cat.js b/src/cat.js index 496257e84..32bccf59e 100644 --- a/src/cat.js +++ b/src/cat.js @@ -6,7 +6,7 @@ const configure = require('./lib/configure') const toIterable = require('./lib/stream-to-iterable') module.exports = configure(({ ky }) => { - return (path, options) => (async function * () { + return async function * cat (path, options) { options = options || {} const searchParams = new URLSearchParams(options.searchParams) @@ -20,7 +20,7 @@ module.exports = configure(({ ky }) => { if (options.offset) searchParams.set('offset', options.offset) if (options.length) searchParams.set('length', options.length) - const res = await ky.get('cat', { + const res = await ky.post('cat', { timeout: options.timeout, signal: options.signal, headers: options.headers, @@ -30,5 +30,5 @@ module.exports = configure(({ ky }) => { for await (const chunk of toIterable(res.body)) { yield Buffer.from(chunk) } - })() + } }) diff --git a/src/commands.js b/src/commands.js index 8327e103a..4f8463fe9 100644 --- a/src/commands.js +++ b/src/commands.js @@ -1,14 +1,19 @@ 'use strict' -const promisify = require('promisify-es6') -const moduleConfig = require('./utils/module-config') - -module.exports = (arg) => { - const send = moduleConfig(arg) - - return promisify((callback) => { - send({ - path: 'commands' - }, callback) - }) -} +const configure = require('./lib/configure') + +module.exports = configure(({ ky }) => { + return options => { + options = options || {} + + const searchParams = new URLSearchParams(options.searchParams) + if (options.flags != null) searchParams.set('flags', options.flags) + + return ky.post('commands', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + } +}) diff --git a/src/config/get.js b/src/config/get.js index b8a42a2e3..e4a7b5c2d 100644 --- a/src/config/get.js +++ b/src/config/get.js @@ -15,7 +15,7 @@ module.exports = configure(({ ky }) => { if (key) searchParams.set('arg', key) const url = key ? 'config' : 'config/show' - const data = await ky.get(url, { + const data = await ky.post(url, { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/config/profiles/list.js b/src/config/profiles/list.js index 1e3f44308..0261070bf 100644 --- a/src/config/profiles/list.js +++ b/src/config/profiles/list.js @@ -7,7 +7,7 @@ module.exports = configure(({ ky }) => { return async (options) => { options = options || {} - const res = await ky.get('config/profile/list', { + const res = await ky.post('config/profile/list', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/dag/resolve.js b/src/dag/resolve.js index f0a83d69d..cb7014a41 100644 --- a/src/dag/resolve.js +++ b/src/dag/resolve.js @@ -19,7 +19,7 @@ module.exports = configure(({ ky }) => { const searchParams = new URLSearchParams(options.searchParams) searchParams.set('arg', cidPath) - const res = await ky.get('dag/resolve', { + const res = await ky.post('dag/resolve', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/dht/find-peer.js b/src/dht/find-peer.js index 953e9fc78..71779952c 100644 --- a/src/dht/find-peer.js +++ b/src/dht/find-peer.js @@ -8,14 +8,14 @@ const configure = require('../lib/configure') const toIterable = require('../lib/stream-to-iterable') module.exports = configure(({ ky }) => { - return (peerId, options) => (async function * () { + return async function * findPeer (peerId, options) { options = options || {} const searchParams = new URLSearchParams(options.searchParams) searchParams.set('arg', `${peerId}`) if (options.verbose != null) searchParams.set('verbose', options.verbose) - const res = await ky.get('dht/findpeer', { + const res = await ky.post('dht/findpeer', { timeout: options.timeout, signal: options.signal, headers: options.headers, @@ -33,5 +33,5 @@ module.exports = configure(({ ky }) => { } } } - })() + } }) diff --git a/src/dht/find-provs.js b/src/dht/find-provs.js index b04d001d8..a0fc35722 100644 --- a/src/dht/find-provs.js +++ b/src/dht/find-provs.js @@ -8,7 +8,7 @@ const configure = require('../lib/configure') const toIterable = require('../lib/stream-to-iterable') module.exports = configure(({ ky }) => { - return (cid, options) => (async function * () { + return async function * findProvs (cid, options) { options = options || {} const searchParams = new URLSearchParams(options.searchParams) @@ -16,7 +16,7 @@ module.exports = configure(({ ky }) => { if (options.numProviders) searchParams.set('num-providers', options.numProviders) if (options.verbose != null) searchParams.set('verbose', options.verbose) - const res = await ky.get('dht/findprovs', { + const res = await ky.post('dht/findprovs', { timeout: options.timeout, signal: options.signal, headers: options.headers, @@ -34,5 +34,5 @@ module.exports = configure(({ ky }) => { } } } - })() + } }) diff --git a/src/dht/get.js b/src/dht/get.js index 8a7b8c6a3..d2cd0db22 100644 --- a/src/dht/get.js +++ b/src/dht/get.js @@ -5,14 +5,14 @@ const configure = require('../lib/configure') const toIterable = require('../lib/stream-to-iterable') module.exports = configure(({ ky }) => { - return (key, options) => (async function * () { + return async function * get (key, options) { options = options || {} const searchParams = new URLSearchParams(options.searchParams) searchParams.set('arg', `${key}`) if (options.verbose != null) searchParams.set('verbose', options.verbose) - const res = await ky.get('dht/get', { + const res = await ky.post('dht/get', { timeout: options.timeout, signal: options.signal, headers: options.headers, @@ -26,5 +26,5 @@ module.exports = configure(({ ky }) => { yield message.Extra } } - })() + } }) diff --git a/src/dht/provide.js b/src/dht/provide.js index 1f05710ec..cb72f9c6d 100644 --- a/src/dht/provide.js +++ b/src/dht/provide.js @@ -9,7 +9,7 @@ const toIterable = require('../lib/stream-to-iterable') const toCamel = require('../lib/object-to-camel') module.exports = configure(({ ky }) => { - return (cids, options) => (async function * () { + return async function * provide (cids, options) { cids = Array.isArray(cids) ? cids : [cids] options = options || {} @@ -18,7 +18,7 @@ module.exports = configure(({ ky }) => { if (options.recursive != null) searchParams.set('recursive', options.recursive) if (options.verbose != null) searchParams.set('verbose', options.verbose) - const res = await ky.get('dht/provide', { + const res = await ky.post('dht/provide', { timeout: options.timeout, signal: options.signal, headers: options.headers, @@ -36,5 +36,5 @@ module.exports = configure(({ ky }) => { } yield message } - })() + } }) diff --git a/src/dht/put.js b/src/dht/put.js index 50137e528..49a6947aa 100644 --- a/src/dht/put.js +++ b/src/dht/put.js @@ -10,7 +10,7 @@ const encodeBufferURIComponent = require('../lib/encode-buffer-uri-component') const toCamel = require('../lib/object-to-camel') module.exports = configure(({ ky }) => { - return (key, value, options) => (async function * () { + return async function * put (key, value, options) { options = options || {} const searchParams = new URLSearchParams(options.searchParams) @@ -20,7 +20,7 @@ module.exports = configure(({ ky }) => { value = Buffer.isBuffer(value) ? encodeBufferURIComponent(value) : encodeURIComponent(value) const url = `dht/put?arg=${key}&arg=${value}&${searchParams}` - const res = await ky.get(url, { + const res = await ky.post(url, { timeout: options.timeout, signal: options.signal, headers: options.headers @@ -37,5 +37,5 @@ module.exports = configure(({ ky }) => { } yield message } - })() + } }) diff --git a/src/dht/query.js b/src/dht/query.js index 8ebca71f7..5aefaf90d 100644 --- a/src/dht/query.js +++ b/src/dht/query.js @@ -7,14 +7,14 @@ const configure = require('../lib/configure') const toIterable = require('../lib/stream-to-iterable') module.exports = configure(({ ky }) => { - return (peerId, options) => (async function * () { + return async function * query (peerId, options) { options = options || {} const searchParams = new URLSearchParams(options.searchParams) searchParams.set('arg', `${peerId}`) if (options.verbose != null) searchParams.set('verbose', options.verbose) - const res = await ky.get('dht/query', { + const res = await ky.post('dht/query', { timeout: options.timeout, signal: options.signal, headers: options.headers, @@ -24,5 +24,5 @@ module.exports = configure(({ ky }) => { for await (const message of ndjson(toIterable(res.body))) { yield new PeerInfo(PeerId.createFromB58String(message.ID)) } - })() + } }) diff --git a/src/diag/cmds.js b/src/diag/cmds.js index 68f20ca04..88bb728ef 100644 --- a/src/diag/cmds.js +++ b/src/diag/cmds.js @@ -9,7 +9,7 @@ module.exports = configure(({ ky }) => { const searchParams = new URLSearchParams(options.searchParams) if (options.verbose != null) searchParams.set('verbose', options.verbose) - return ky.get('diag/cmds', { + return ky.post('diag/cmds', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/diag/net.js b/src/diag/net.js index a7404b802..71b971ba7 100644 --- a/src/diag/net.js +++ b/src/diag/net.js @@ -6,7 +6,7 @@ module.exports = configure(({ ky }) => { return options => { options = options || {} - return ky.get('diag/net', { + return ky.post('diag/net', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/diag/sys.js b/src/diag/sys.js index a8cd91b6f..768d13d4d 100644 --- a/src/diag/sys.js +++ b/src/diag/sys.js @@ -6,7 +6,7 @@ module.exports = configure(({ ky }) => { return options => { options = options || {} - return ky.get('diag/sys', { + return ky.post('diag/sys', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/dns.js b/src/dns.js index 3f734bfc2..5032e3fb5 100644 --- a/src/dns.js +++ b/src/dns.js @@ -1,25 +1,22 @@ 'use strict' -const promisify = require('promisify-es6') -const moduleConfig = require('./utils/module-config') +const configure = require('./lib/configure') -const transform = function (res, callback) { - callback(null, res.Path) -} +module.exports = configure(({ ky }) => { + return async (domain, options) => { + options = options || {} -module.exports = (arg) => { - const send = moduleConfig(arg) + const searchParams = new URLSearchParams(options.searchParams) + searchParams.set('arg', domain) + if (options.recursive != null) searchParams.set('recursive', options.recursive) - return promisify((args, opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } + const res = await ky.post('dns', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() - send.andTransform({ - path: 'dns', - args: args, - qs: opts - }, transform, callback) - }) -} + return res.Path + } +}) diff --git a/src/get-endpoint-config.js b/src/get-endpoint-config.js index a4f0c80e1..cf7125e70 100644 --- a/src/get-endpoint-config.js +++ b/src/get-endpoint-config.js @@ -1,10 +1,13 @@ 'use strict' -module.exports = (config) => { +const configure = require('./lib/configure') + +module.exports = configure(({ apiAddr, apiPath }) => { + const url = new URL(apiAddr) return () => ({ - host: config.host, - port: config.port, - protocol: config.protocol, - 'api-path': config['api-path'] + host: url.hostname, + port: url.port, + protocol: url.protocol.split(':')[0], // remove ":" + 'api-path': apiPath }) -} +}) diff --git a/src/get.js b/src/get.js index c06fc6d36..1a5ebfd93 100644 --- a/src/get.js +++ b/src/get.js @@ -2,24 +2,16 @@ const configure = require('./lib/configure') const Tar = require('it-tar') -const IsIpfs = require('is-ipfs') +const { Buffer } = require('buffer') +const CID = require('cids') const toIterable = require('./lib/stream-to-iterable') -const cleanCID = require('./utils/clean-cid') module.exports = configure(({ ky }) => { return async function * get (path, options) { options = options || {} - try { - path = cleanCID(path) - } catch (err) { - if (!IsIpfs.ipfsPath(path)) { - throw err - } - } - const searchParams = new URLSearchParams() - searchParams.set('arg', path.toString()) + searchParams.set('arg', `${Buffer.isBuffer(path) ? new CID(path) : path}`) if (options.compress !== undefined) { searchParams.set('compress', options.compress) @@ -37,7 +29,7 @@ module.exports = configure(({ ky }) => { searchParams.set('length', options.length) } - const res = await ky.get('get', { + const res = await ky.post('get', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/id.js b/src/id.js index b98be8443..d6080ea67 100644 --- a/src/id.js +++ b/src/id.js @@ -1,32 +1,19 @@ 'use strict' -const promisify = require('promisify-es6') -const moduleConfig = require('./utils/module-config') +const configure = require('./lib/configure') +const toCamel = require('./lib/object-to-camel') -module.exports = (arg) => { - const send = moduleConfig(arg) +module.exports = configure(({ ky }) => { + return async options => { + options = options || {} - return promisify((opts, callback) => { - if (typeof opts === 'function') { - callback = opts - opts = undefined - } + const res = await ky.post('id', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams: options.searchParams + }).json() - send({ - path: 'id', - args: opts - }, (err, result) => { - if (err) { - return callback(err) - } - const identity = { - id: result.ID, - publicKey: result.PublicKey, - addresses: result.Addresses, - agentVersion: result.AgentVersion, - protocolVersion: result.ProtocolVersion - } - callback(null, identity) - }) - }) -} + return toCamel(res) + } +}) diff --git a/src/index.js b/src/index.js index bd58a66f1..d9dc89630 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,4 @@ 'use strict' -/* global self */ const isIPFS = require('is-ipfs') const { Buffer } = require('buffer') @@ -10,67 +9,151 @@ const multicodec = require('multicodec') const multihash = require('multihashes') const PeerId = require('peer-id') const PeerInfo = require('peer-info') -const loadCommands = require('./utils/load-commands') -const getConfig = require('./utils/default-config') -const sendRequest = require('./utils/send-request') +const nodeify = require('promise-nodeify') +const callbackify = require('callbackify') +const all = require('async-iterator-all') +const toPullStream = require('async-iterator-to-pull-stream') +const toStream = require('it-to-stream') +const BufferList = require('bl/BufferList') +const { concatify, collectify, pullify, streamify } = require('./lib/converters') -function ipfsClient (hostOrMultiaddr, port, userOptions) { - // convert all three params to objects that we can merge. - let options = {} +function ipfsClient (config) { + const add = require('./add')(config) + const addFromFs = require('./add-from-fs')(config) + const addFromURL = require('./add-from-url')(config) + const cat = require('./cat')(config) + const get = require('./get')(config) + const ls = require('./ls')(config) + const ping = require('./ping')(config) + const refs = require('./refs')(config) - if (!hostOrMultiaddr) { - // autoconfigure host and port in browser - if (typeof self !== 'undefined') { - options = urlToOptions(self.location) - } - } else if (multiaddr.isMultiaddr(hostOrMultiaddr)) { - options = maToOptions(hostOrMultiaddr) - } else if (typeof hostOrMultiaddr === 'object') { - options = hostOrMultiaddr - } else if (typeof hostOrMultiaddr === 'string') { - if (hostOrMultiaddr[0] === '/') { - // throws if multiaddr is malformed or can't be converted to a nodeAddress - options = maToOptions(multiaddr(hostOrMultiaddr)) - } else { - // hostOrMultiaddr is domain or ip address as a string - options.host = hostOrMultiaddr - } - } + const api = { + add: (input, options, callback) => { + if (typeof options === 'function') { + callback = options + options = {} + } + return nodeify(collectify(add)(input, options), callback) + }, + addReadableStream: streamify.transform(add), + addPullStream: pullify.transform(add), + addFromFs: (path, options, callback) => { + if (typeof options === 'function') { + callback = options + options = {} + } + return nodeify(collectify(addFromFs)(path, options), callback) + }, + addFromURL: (url, options, callback) => { + if (typeof options === 'function') { + callback = options + options = {} + } + return nodeify(collectify(addFromURL)(url, options), callback) + }, + addFromStream: (input, options, callback) => { + if (typeof options === 'function') { + callback = options + options = {} + } + return nodeify(collectify(add)(input, options), callback) + }, + _addAsyncIterator: add, + bitswap: require('./bitswap')(config), + block: require('./block')(config), + bootstrap: require('./bootstrap')(config), + cat: callbackify.variadic((path, options) => concatify(cat)(path, options)), + catReadableStream: streamify.readable(cat), + catPullStream: pullify.source(cat), + _catAsyncIterator: cat, + commands: callbackify.variadic(require('./commands')(config)), + config: require('./config')(config), + dag: require('./dag')(config), + dht: require('./dht')(config), + diag: require('./diag')(config), + dns: callbackify.variadic(require('./dns')(config)), + files: require('./files')(config), + get: callbackify.variadic(async (path, options) => { + const output = [] - if (port && typeof port !== 'object') { - port = { port: port } - } + for await (const entry of get(path, options)) { + if (entry.content) { + entry.content = new BufferList(await all(entry.content)).slice() + } - const config = Object.assign(getConfig(), options, port, userOptions) - const requestAPI = sendRequest(config) - const cmds = loadCommands(requestAPI, config) - cmds.send = requestAPI + output.push(entry) + } - return cmds -} + return output + }), + getEndpointConfig: require('./get-endpoint-config')(config), + getReadableStream: streamify.readable(async function * (path, options) { + for await (const file of get(path, options)) { + if (file.content) { + const { content } = file + file.content = toStream((async function * () { + for await (const chunk of content) { + yield chunk.slice() // Convert bl to Buffer + } + })()) + } -function maToOptions (multiaddr) { - // ma.nodeAddress() throws if multiaddr can't be converted to a nodeAddress - const nodeAddr = multiaddr.nodeAddress() - const protos = multiaddr.protos() - // only http and https are allowed as protocol, - // anything else will be replaced with http - const exitProtocol = protos[protos.length - 1].name - return { - host: nodeAddr.address, - port: nodeAddr.port, - protocol: exitProtocol.startsWith('http') ? exitProtocol : 'http' - } -} + yield file + } + }), + getPullStream: pullify.source(async function * (path, options) { + for await (const file of get(path, options)) { + if (file.content) { + const { content } = file + file.content = toPullStream((async function * () { + for await (const chunk of content) { + yield chunk.slice() // Convert bl to Buffer + } + })()) + } -function urlToOptions (url) { - return { - host: url.hostname, - port: url.port || (url.protocol.startsWith('https') ? 443 : 80), - protocol: url.protocol.startsWith('http') ? url.protocol.split(':')[0] : 'http' + yield file + } + }), + _getAsyncIterator: get, + id: callbackify.variadic(require('./id')(config)), + key: require('./key')(config), + log: require('./log')(config), + ls: callbackify.variadic((path, options) => collectify(ls)(path, options)), + lsReadableStream: streamify.readable(ls), + lsPullStream: pullify.source(ls), + _lsAsyncIterator: ls, + mount: callbackify.variadic(require('./mount')(config)), + name: require('./name')(config), + object: require('./object')(config), + pin: require('./pin')(config), + ping: callbackify.variadic(collectify(ping)), + pingReadableStream: streamify.readable(ping), + pingPullStream: pullify.source(ping), + pubsub: require('./pubsub')(config), + refs: callbackify.variadic((path, options) => collectify(refs)(path, options)), + refsReadableStream: streamify.readable(refs), + refsPullStream: pullify.source(refs), + _refsAsyncIterator: refs, + repo: require('./repo')(config), + resolve: callbackify.variadic(require('./resolve')(config)), + stats: require('./stats')(config), + stop: callbackify.variadic(require('./stop')(config)), + shutdown: callbackify.variadic(require('./stop')(config)), + swarm: require('./swarm')(config), + version: callbackify.variadic(require('./version')(config)) } + + Object.assign(api.refs, { + local: callbackify.variadic(options => collectify(refs.local)(options)), + localReadableStream: streamify.readable(refs.local), + localPullStream: pullify.source(refs.local), + _localAsyncIterator: refs.local + }) + + return api } -module.exports = ipfsClient +Object.assign(ipfsClient, { isIPFS, Buffer, CID, multiaddr, multibase, multicodec, multihash, PeerId, PeerInfo }) -Object.assign(module.exports, { isIPFS, Buffer, CID, multiaddr, multibase, multicodec, multihash, PeerId, PeerInfo }) +module.exports = ipfsClient diff --git a/src/key/export.js b/src/key/export.js index f19db4022..b5f315580 100644 --- a/src/key/export.js +++ b/src/key/export.js @@ -1,16 +1,25 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../lib/configure') -module.exports = (send) => { - return promisify((name, password, callback) => { - send({ - path: 'key/export', - args: name, - qs: { password: password } - }, (err, pem) => { - if (err) return callback(err) - callback(null, pem.toString()) - }) - }) -} +module.exports = configure(({ ky }) => { + return (name, password, options) => { + if (typeof password !== 'string') { + options = password + password = null + } + + options = options || {} + + const searchParams = new URLSearchParams(options.searchParams) + searchParams.set('arg', name) + if (password) searchParams.set('password', password) + + return ky.post('key/export', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).text() + } +}) diff --git a/src/key/gen.js b/src/key/gen.js index 38612d9af..5fd6acb86 100644 --- a/src/key/gen.js +++ b/src/key/gen.js @@ -1,25 +1,24 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../lib/configure') +const toCamel = require('../lib/object-to-camel') -const transform = function (res, callback) { - callback(null, { - id: res.Id, - name: res.Name - }) -} +module.exports = configure(({ ky }) => { + return async (name, options) => { + options = options || {} -module.exports = (send) => { - return promisify((args, opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } + const searchParams = new URLSearchParams(options.searchParams) + searchParams.set('arg', name) + if (options.type) searchParams.set('type', options.type) + if (options.size != null) searchParams.set('size', options.size) - send.andTransform({ - path: 'key/gen', - args: args, - qs: opts - }, transform, callback) - }) -} + const res = await ky.post('key/gen', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return toCamel(res) + } +}) diff --git a/src/key/import.js b/src/key/import.js index 9cea80e27..7cc8f5ddc 100644 --- a/src/key/import.js +++ b/src/key/import.js @@ -1,23 +1,29 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../lib/configure') +const toCamel = require('../lib/object-to-camel') -const transform = function (res, callback) { - callback(null, { - id: res.Id, - name: res.Name - }) -} +module.exports = configure(({ ky }) => { + return async (name, pem, password, options) => { + if (typeof password !== 'string') { + options = password + password = null + } -module.exports = (send) => { - return promisify((name, pem, password, callback) => { - send.andTransform({ - path: 'key/import', - args: name, - qs: { - pem: pem, - password: password - } - }, transform, callback) - }) -} + options = options || {} + + const searchParams = new URLSearchParams(options.searchParams) + searchParams.set('arg', name) + searchParams.set('pem', pem) + if (password) searchParams.set('password', password) + + const res = await ky.post('key/import', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return toCamel(res) + } +}) diff --git a/src/key/index.js b/src/key/index.js index 717d719c3..7293236f1 100644 --- a/src/key/index.js +++ b/src/key/index.js @@ -1,16 +1,12 @@ 'use strict' -const moduleConfig = require('../utils/module-config') +const callbackify = require('callbackify') -module.exports = (arg) => { - const send = moduleConfig(arg) - - return { - gen: require('./gen')(send), - list: require('./list')(send), - rename: require('./rename')(send), - rm: require('./rm')(send), - export: require('./export')(send), - import: require('./import')(send) - } -} +module.exports = config => ({ + gen: callbackify.variadic(require('./gen')(config)), + list: callbackify.variadic(require('./list')(config)), + rename: callbackify.variadic(require('./rename')(config)), + rm: callbackify.variadic(require('./rm')(config)), + export: callbackify.variadic(require('./export')(config)), + import: callbackify.variadic(require('./import')(config)) +}) diff --git a/src/key/list.js b/src/key/list.js index bcd9bc8e2..80e5069aa 100644 --- a/src/key/list.js +++ b/src/key/list.js @@ -1,26 +1,19 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../lib/configure') +const toCamel = require('../lib/object-to-camel') -const transform = function (res, callback) { - callback(null, res.Keys.map(key => { - return { - id: key.Id, - name: key.Name - } - })) -} +module.exports = configure(({ ky }) => { + return async options => { + options = options || {} -module.exports = (send) => { - return promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } + const res = await ky.post('key/list', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams: options.searchParams + }).json() - send.andTransform({ - path: 'key/list', - qs: opts - }, transform, callback) - }) -} + return (res.Keys || []).map(k => toCamel(k)) + } +}) diff --git a/src/key/rename.js b/src/key/rename.js index 68b45f010..18e069768 100644 --- a/src/key/rename.js +++ b/src/key/rename.js @@ -1,21 +1,24 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../lib/configure') +const toCamel = require('../lib/object-to-camel') -const transform = function (res, callback) { - callback(null, { - id: res.Id, - was: res.Was, - now: res.Now, - overwrite: res.Overwrite - }) -} +module.exports = configure(({ ky }) => { + return async (oldName, newName, options) => { + options = options || {} -module.exports = (send) => { - return promisify((oldName, newName, callback) => { - send.andTransform({ - path: 'key/rename', - args: [oldName, newName] - }, transform, callback) - }) -} + const searchParams = new URLSearchParams(options.searchParams) + searchParams.set('arg', oldName) + searchParams.append('arg', newName) + if (options.force != null) searchParams.set('force', options.force) + + const res = await ky.post('key/rename', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return toCamel(res) + } +}) diff --git a/src/key/rm.js b/src/key/rm.js index 7e4e98500..edab61060 100644 --- a/src/key/rm.js +++ b/src/key/rm.js @@ -1,19 +1,22 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../lib/configure') +const toCamel = require('../lib/object-to-camel') -const transform = function (res, callback) { - callback(null, { - id: res.Keys[0].Id, - name: res.Keys[0].Name - }) -} +module.exports = configure(({ ky }) => { + return async (name, options) => { + options = options || {} -module.exports = (send) => { - return promisify((args, callback) => { - send.andTransform({ - path: 'key/rm', - args: args - }, transform, callback) - }) -} + const searchParams = new URLSearchParams(options.searchParams) + searchParams.set('arg', name) + + const res = await ky.post('key/rm', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return toCamel(res.Keys[0]) + } +}) diff --git a/src/lib/configure.js b/src/lib/configure.js index b1a1f8948..9e6c9465f 100644 --- a/src/lib/configure.js +++ b/src/lib/configure.js @@ -3,7 +3,7 @@ const ky = require('ky-universal').default const { isBrowser, isWebWorker } = require('ipfs-utils/src/env') -const { toUri } = require('./multiaddr') +const toUri = require('multiaddr-to-uri') const errorHandler = require('./error-handler') const mergeOptions = require('merge-options').bind({ ignoreUndefined: true }) const parseDuration = require('parse-duration') @@ -22,10 +22,17 @@ module.exports = create => config => { config.apiAddr = (config.apiAddr || getDefaultApiAddr(config)).toString() config.apiAddr = config.apiAddr.startsWith('/') ? toUri(config.apiAddr) : config.apiAddr - config.apiPath = config.apiPath || config['api-path'] || '/api/v0' + config.apiAddr = trimEnd(config.apiAddr, '/') + + const apiAddrPath = getNonRootPath(config.apiAddr) + + // Use configured apiPath, or path on the end of apiAddr (if there is one) or default to /api/v0 + config.apiPath = config.apiPath || config['api-path'] || apiAddrPath || '/api/v0' + config.apiPath = trimEnd(config.apiPath, '/') + + // If user passed apiAddr with a path, trim it from the end (it is now apiPath) + config.apiAddr = apiAddrPath ? trimEnd(config.apiAddr, apiAddrPath) : config.apiAddr - // TODO configure ky to use config.fetch when this is released: - // https://github.com/sindresorhus/ky/pull/153 const defaults = { prefixUrl: config.apiAddr + config.apiPath, timeout: parseTimeout(config.timeout) || 60000 * 20, @@ -50,13 +57,9 @@ module.exports = create => config => { function getDefaultApiAddr ({ protocol, host, port }) { if (isBrowser || isWebWorker) { - if (!protocol && !host && !port) { // Use current origin - return '' - } - if (!protocol) { protocol = location.protocol.startsWith('http') - ? location.protocol.split(':')[0] + ? trimEnd(location.protocol, ':') : 'http' } @@ -81,3 +84,13 @@ function wrap (fn, defaults) { function parseTimeout (value) { return typeof value === 'string' ? parseDuration(value) : value } + +const trimEnd = (str, end) => str.endsWith(end) ? str.slice(0, -end.length) : str + +// Get the path from a URL is it is not / +function getNonRootPath (url) { + if (url) { + const { pathname } = new URL(url) + return pathname === '/' ? null : pathname + } +} diff --git a/src/lib/multiaddr.js b/src/lib/multiaddr.js deleted file mode 100644 index 09462ab34..000000000 --- a/src/lib/multiaddr.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict' - -// Convert a multiaddr to a URI -// Assumes multiaddr is in a format that can be converted to a HTTP(s) URI -exports.toUri = ma => { - const parts = `${ma}`.split('/') - const port = getPort(parts) - return `${getProtocol(parts)}://${parts[2]}${port == null ? '' : ':' + port}` -} - -function getProtocol (maParts) { - return maParts.indexOf('https') === -1 ? 'http' : 'https' -} - -function getPort (maParts) { - const tcpIndex = maParts.indexOf('tcp') - return tcpIndex === -1 ? null : maParts[tcpIndex + 1] -} diff --git a/src/log/index.js b/src/log/index.js index 94597bdc6..f7d94f910 100644 --- a/src/log/index.js +++ b/src/log/index.js @@ -1,13 +1,9 @@ 'use strict' -const moduleConfig = require('../utils/module-config') +const callbackify = require('callbackify') -module.exports = (arg) => { - const send = moduleConfig(arg) - - return { - tail: require('./tail')(send), - ls: require('./ls')(send), - level: require('./level')(send) - } -} +module.exports = config => ({ + tail: require('./tail')(config), + ls: callbackify.variadic(require('./ls')(config)), + level: callbackify.variadic(require('./level')(config)) +}) diff --git a/src/log/level.js b/src/log/level.js index 4304ff90f..dcc20c7bd 100644 --- a/src/log/level.js +++ b/src/log/level.js @@ -1,27 +1,23 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../lib/configure') +const toCamel = require('../lib/object-to-camel') -module.exports = (send) => { - return promisify((subsystem, level, opts, callback) => { - if (typeof opts === 'function') { - callback = opts - opts = {} - } - if (typeof subsystem !== 'string') { - return callback(new Error('Invalid subsystem type')) - } +module.exports = configure(({ ky }) => { + return async (subsystem, level, options) => { + options = options || {} - if (typeof level !== 'string') { - return callback(new Error('Invalid level type')) - } + const searchParams = new URLSearchParams(options.searchParams) + searchParams.set('arg', subsystem) + searchParams.append('arg', level) - send({ - path: 'log/level', - args: [subsystem, level], - qs: opts, - files: undefined, - buffer: true - }, callback) - }) -} + const res = await ky.post('log/level', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return toCamel(res) + } +}) diff --git a/src/log/ls.js b/src/log/ls.js index ab243605b..0a8d69c6c 100644 --- a/src/log/ls.js +++ b/src/log/ls.js @@ -1,17 +1,18 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../lib/configure') -module.exports = (send) => { - return promisify((callback) => { - send({ - path: 'log/ls' - }, (err, result) => { - if (err) { - return callback(err) - } +module.exports = configure(({ ky }) => { + return async options => { + options = options || {} - callback(null, result.Strings) - }) - }) -} + const res = await ky.post('log/ls', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams: options.searchParams + }).json() + + return res.Strings + } +}) diff --git a/src/log/tail.js b/src/log/tail.js index bad4e4d34..00708e9b9 100644 --- a/src/log/tail.js +++ b/src/log/tail.js @@ -1,20 +1,20 @@ 'use strict' -const promisify = require('promisify-es6') -const pump = require('pump') -const ndjson = require('ndjson') +const ndjson = require('iterable-ndjson') +const configure = require('../lib/configure') +const toIterable = require('../lib/stream-to-iterable') -module.exports = (send) => { - return promisify((callback) => { - return send({ - path: 'log/tail' - }, (err, response) => { - if (err) { - return callback(err) - } - const outputStream = ndjson.parse() - pump(response, outputStream) - callback(null, outputStream) +module.exports = configure(({ ky }) => { + return async function * tail (options) { + options = options || {} + + const res = await ky.post('log/tail', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams: options.searchParams }) - }) -} + + yield * ndjson(toIterable(res.body)) + } +}) diff --git a/src/ls.js b/src/ls.js index fc9921963..a9cd476f9 100644 --- a/src/ls.js +++ b/src/ls.js @@ -1,23 +1,15 @@ 'use strict' -const IsIpfs = require('is-ipfs') -const cleanCID = require('./utils/clean-cid') +const { Buffer } = require('buffer') +const CID = require('cids') const configure = require('./lib/configure') module.exports = configure(({ ky }) => { return async function * ls (path, options) { options = options || {} - try { - path = cleanCID(path) - } catch (err) { - if (!IsIpfs.ipfsPath(path)) { - throw err - } - } - const searchParams = new URLSearchParams() - searchParams.set('arg', path.toString()) + searchParams.set('arg', `${Buffer.isBuffer(path) ? new CID(path) : path}`) if (options.long !== undefined) { searchParams.set('long', options.long) @@ -31,7 +23,7 @@ module.exports = configure(({ ky }) => { searchParams.set('recursive', options.recursive) } - const res = await ky.get('ls', { + const res = await ky.post('ls', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/mount.js b/src/mount.js index 7c2e92cab..a5d2faef1 100644 --- a/src/mount.js +++ b/src/mount.js @@ -1,30 +1,23 @@ 'use strict' -const promisify = require('promisify-es6') -const moduleConfig = require('./utils/module-config') +const configure = require('./lib/configure') +const toCamel = require('./lib/object-to-camel') -module.exports = (arg) => { - const send = moduleConfig(arg) +module.exports = configure(({ ky }) => { + return async options => { + options = options || {} - return promisify((ipfs, ipns, callback) => { - if (typeof ipfs === 'function') { - callback = ipfs - ipfs = null - } else if (typeof ipns === 'function') { - callback = ipns - ipns = null - } - const opts = {} - if (ipfs) { - opts.f = ipfs - } - if (ipns) { - opts.n = ipns - } + const searchParams = new URLSearchParams(options.searchParams) + if (options.ipfsPath != null) searchParams.set('ipfs-path', options.ipfsPath) + if (options.ipnsPath != null) searchParams.set('ipns-path', options.ipnsPath) - send({ - path: 'mount', - qs: opts - }, callback) - }) -} + const res = await ky.post('dns', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return toCamel(res) + } +}) diff --git a/src/name/index.js b/src/name/index.js index 8f823311a..7a6837b82 100644 --- a/src/name/index.js +++ b/src/name/index.js @@ -1,13 +1,9 @@ 'use strict' -const moduleConfig = require('../utils/module-config') +const callbackify = require('callbackify') -module.exports = (arg) => { - const send = moduleConfig(arg) - - return { - publish: require('./publish')(send), - resolve: require('./resolve')(send), - pubsub: require('./pubsub')(send) - } -} +module.exports = config => ({ + publish: callbackify.variadic(require('./publish')(config)), + resolve: callbackify.variadic(require('./resolve')(config)), + pubsub: require('./pubsub')(config) +}) diff --git a/src/name/publish.js b/src/name/publish.js index cfc7482e3..e470606f9 100644 --- a/src/name/publish.js +++ b/src/name/publish.js @@ -1,25 +1,28 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../lib/configure') +const toCamel = require('../lib/object-to-camel') -const transform = function (res, callback) { - callback(null, { - name: res.Name, - value: res.Value - }) -} +module.exports = configure(({ ky }) => { + return async (path, options) => { + options = options || {} -module.exports = (send) => { - return promisify((args, opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } + const searchParams = new URLSearchParams(options.searchParams) + searchParams.set('arg', path) + if (options.allowOffline != null) searchParams.set('allow-offline', options.allowOffline) + if (options.key) searchParams.set('key', options.key) + if (options.lifetime) searchParams.set('lifetime', options.lifetime) + if (options.quieter != null) searchParams.set('quieter', options.quieter) + if (options.resolve != null) searchParams.set('resolve', options.resolve) + if (options.ttl) searchParams.set('ttl', options.ttl) - send.andTransform({ - path: 'name/publish', - args: args, - qs: opts - }, transform, callback) - }) -} + const res = await ky.post('name/publish', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return toCamel(res) + } +}) diff --git a/src/name/pubsub/cancel.js b/src/name/pubsub/cancel.js index 32dbbb3af..ea5391e64 100644 --- a/src/name/pubsub/cancel.js +++ b/src/name/pubsub/cancel.js @@ -1,24 +1,22 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../../lib/configure') +const toCamel = require('../../lib/object-to-camel') -const transform = function (res, callback) { - callback(null, { - canceled: res.Canceled === undefined || res.Canceled === true - }) -} +module.exports = configure(({ ky }) => { + return async (name, options) => { + options = options || {} -module.exports = (send) => { - return promisify((args, opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } + const searchParams = new URLSearchParams(options.searchParams) + searchParams.set('arg', name) - send.andTransform({ - path: 'name/pubsub/cancel', - args: args, - qs: opts - }, transform, callback) - }) -} + const res = await ky.post('name/pubsub/cancel', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return toCamel(res) + } +}) diff --git a/src/name/pubsub/index.js b/src/name/pubsub/index.js index aefc0f880..70db19874 100644 --- a/src/name/pubsub/index.js +++ b/src/name/pubsub/index.js @@ -1,7 +1,9 @@ 'use strict' -module.exports = (send) => ({ - cancel: require('./cancel')(send), - state: require('./state')(send), - subs: require('./subs')(send) +const callbackify = require('callbackify') + +module.exports = config => ({ + cancel: callbackify.variadic(require('./cancel')(config)), + state: callbackify.variadic(require('./state')(config)), + subs: callbackify.variadic(require('./subs')(config)) }) diff --git a/src/name/pubsub/state.js b/src/name/pubsub/state.js index cc9b0b369..03e18aa7f 100644 --- a/src/name/pubsub/state.js +++ b/src/name/pubsub/state.js @@ -1,23 +1,19 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../../lib/configure') +const toCamel = require('../../lib/object-to-camel') -const transform = function (res, callback) { - callback(null, { - enabled: res.Enabled - }) -} +module.exports = configure(({ ky }) => { + return async options => { + options = options || {} -module.exports = (send) => { - return promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } + const res = await ky.post('name/pubsub/state', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams: options.searchParams + }).json() - send.andTransform({ - path: 'name/pubsub/state', - qs: opts - }, transform, callback) - }) -} + return toCamel(res) + } +}) diff --git a/src/name/pubsub/subs.js b/src/name/pubsub/subs.js index 3a3a54c2a..9bc6c2208 100644 --- a/src/name/pubsub/subs.js +++ b/src/name/pubsub/subs.js @@ -1,21 +1,18 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../../lib/configure') -const transform = function (res, callback) { - callback(null, res.Strings || []) -} +module.exports = configure(({ ky }) => { + return async (name, options) => { + options = options || {} -module.exports = (send) => { - return promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } + const res = await ky.post('name/pubsub/subs', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams: options.searchParams + }).json() - send.andTransform({ - path: 'name/pubsub/subs', - qs: opts - }, transform, callback) - }) -} + return res.Strings || [] + } +}) diff --git a/src/name/resolve.js b/src/name/resolve.js index addb567d6..b6e8db47e 100644 --- a/src/name/resolve.js +++ b/src/name/resolve.js @@ -1,22 +1,25 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../lib/configure') -const transform = function (res, callback) { - callback(null, res.Path) -} +module.exports = configure(({ ky }) => { + return async (path, options) => { + options = options || {} -module.exports = (send) => { - return promisify((args, opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } + const searchParams = new URLSearchParams(options.searchParams) + searchParams.set('arg', path) + if (options.dhtRecordCount != null) searchParams.set('dht-record-count', options.dhtRecordCount) + if (options.dhtTimeout != null) searchParams.set('dht-timeout', options.dhtTimeout) + if (options.noCache != null) searchParams.set('nocache', options.noCache) + if (options.recursive != null) searchParams.set('recursive', options.recursive) - send.andTransform({ - path: 'name/resolve', - args: args, - qs: opts - }, transform, callback) - }) -} + const res = await ky.post('name/resolve', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return res.Path + } +}) diff --git a/src/object/data.js b/src/object/data.js index 8f1e42b7a..48291f722 100644 --- a/src/object/data.js +++ b/src/object/data.js @@ -6,13 +6,13 @@ const configure = require('../lib/configure') const toIterable = require('../lib/stream-to-iterable') module.exports = configure(({ ky }) => { - return async function * (cid, options) { + return async function * data (cid, options) { options = options || {} const searchParams = new URLSearchParams(options.searchParams) searchParams.set('arg', `${Buffer.isBuffer(cid) ? new CID(cid) : cid}`) - const res = await ky.get('object/data', { + const res = await ky.post('object/data', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/object/get.js b/src/object/get.js index 5ed7468dc..8dd2b638d 100644 --- a/src/object/get.js +++ b/src/object/get.js @@ -13,7 +13,7 @@ module.exports = configure(({ ky }) => { searchParams.set('arg', `${Buffer.isBuffer(cid) ? new CID(cid) : cid}`) searchParams.set('data-encoding', 'base64') - const res = await ky.get('object/get', { + const res = await ky.post('object/get', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/object/links.js b/src/object/links.js index 49b088254..f05ddb630 100644 --- a/src/object/links.js +++ b/src/object/links.js @@ -12,7 +12,7 @@ module.exports = configure(({ ky }) => { const searchParams = new URLSearchParams(options.searchParams) searchParams.set('arg', `${Buffer.isBuffer(cid) ? new CID(cid) : cid}`) - const res = await ky.get('object/links', { + const res = await ky.post('object/links', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/pin/ls.js b/src/pin/ls.js index bf1746d63..cd1cc07f1 100644 --- a/src/pin/ls.js +++ b/src/pin/ls.js @@ -15,7 +15,7 @@ module.exports = configure(({ ky }) => { if (path) searchParams.set('arg', `${path}`) if (options.type) searchParams.set('type', options.type) - const { Keys } = await ky.get('pin/ls', { + const { Keys } = await ky.post('pin/ls', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/ping-pull-stream.js b/src/ping-pull-stream.js deleted file mode 100644 index a7871faa3..000000000 --- a/src/ping-pull-stream.js +++ /dev/null @@ -1,34 +0,0 @@ -'use strict' - -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) - - return (id, opts = {}) => { - // Default number of packtes to 1 - if (!opts.n && !opts.count) { - opts.n = 1 - } - const request = { - path: 'ping', - args: id, - qs: opts - } - const p = deferred.source() - const response = new PingMessageStream() - - send(request, (err, stream) => { - if (err) { return p.abort(err) } - - pump(stream, response) - p.resolve(toPull.source(response)) - }) - - return p - } -} diff --git a/src/ping-readable-stream.js b/src/ping-readable-stream.js deleted file mode 100644 index df4f70401..000000000 --- a/src/ping-readable-stream.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict' - -const pump = require('pump') -const moduleConfig = require('./utils/module-config') -const PingMessageStream = require('./utils/ping-message-stream') - -module.exports = (arg) => { - const send = moduleConfig(arg) - - return (id, opts = {}) => { - // Default number of packtes to 1 - if (!opts.n && !opts.count) { - opts.n = 1 - } - const request = { - path: 'ping', - args: id, - qs: opts - } - - const response = new PingMessageStream() - - send(request, (err, stream) => { - if (err) { return response.emit('error', err) } - pump(stream, response) - }) - - return response - } -} diff --git a/src/ping.js b/src/ping.js index f3ff63ec8..33b275617 100644 --- a/src/ping.js +++ b/src/ping.js @@ -1,60 +1,27 @@ 'use strict' -const promisify = require('promisify-es6') -const pump = require('pump') -const Writable = require('readable-stream').Writable -const moduleConfig = require('./utils/module-config') -const PingMessageStream = require('./utils/ping-message-stream') - -module.exports = (arg) => { - const send = moduleConfig(arg) - - return promisify((id, opts, callback) => { - if (typeof opts === 'function') { - callback = opts - opts = {} - } - - if (opts.n && opts.count) { - return callback(new Error('Use either n or count, not both')) - } - - // Default number of packtes to 1 - if (!opts.n && !opts.count) { - opts.n = 1 +const ndjson = require('iterable-ndjson') +const configure = require('./lib/configure') +const toIterable = require('./lib/stream-to-iterable') +const toCamel = require('./lib/object-to-camel') + +module.exports = configure(({ ky }) => { + return async function * ping (peerId, options) { + options = options || {} + + const searchParams = new URLSearchParams(options.searchParams) + searchParams.set('arg', `${peerId}`) + if (options.count != null) searchParams.set('count', options.count) + + const res = await ky.post('ping', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }) + + for await (const chunk of ndjson(toIterable(res.body))) { + yield toCamel(chunk) } - - const request = { - path: 'ping', - args: id, - qs: opts - } - - // Transform the response stream to a value: - // [{ 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) => { - if (err) { - return callback(err) - } - callback(null, responses) - } - ) - } - - send.andTransform(request, transform, callback) - }) -} + } +}) diff --git a/src/pubsub/ls.js b/src/pubsub/ls.js index 177dcd491..d2bc8f68d 100644 --- a/src/pubsub/ls.js +++ b/src/pubsub/ls.js @@ -6,7 +6,7 @@ module.exports = configure(({ ky }) => { return async (options) => { options = options || {} - const { Strings } = await ky.get('pubsub/ls', { + const { Strings } = await ky.post('pubsub/ls', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/pubsub/peers.js b/src/pubsub/peers.js index bdeca60e4..5fa5b2436 100644 --- a/src/pubsub/peers.js +++ b/src/pubsub/peers.js @@ -14,7 +14,7 @@ module.exports = configure(({ ky }) => { const searchParams = new URLSearchParams(options.searchParams) searchParams.set('arg', topic) - const { Strings } = await ky.get('pubsub/peers', { + const { Strings } = await ky.post('pubsub/peers', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/refs/index.js b/src/refs/index.js index d86944eb2..b15f2cd0c 100644 --- a/src/refs/index.js +++ b/src/refs/index.js @@ -1,8 +1,8 @@ 'use strict' const configure = require('../lib/configure') -const cleanCID = require('../utils/clean-cid') -const IsIpfs = require('is-ipfs') +const { Buffer } = require('buffer') +const CID = require('cids') const ndjson = require('iterable-ndjson') const toIterable = require('../lib/stream-to-iterable') const toCamel = require('../lib/object-to-camel') @@ -38,19 +38,11 @@ module.exports = config => { args = [args] } - for (let arg of args) { - try { - arg = cleanCID(arg) - } catch (err) { - if (!IsIpfs.ipfsPath(arg)) { - throw err - } - } - - searchParams.append('arg', arg.toString()) + for (const arg of args) { + searchParams.append('arg', `${Buffer.isBuffer(arg) ? new CID(arg) : arg}`) } - const res = await ky.get('refs', { + const res = await ky.post('refs', { timeout: options.timeout, signal: options.signal, headers: options.headers, diff --git a/src/refs/local.js b/src/refs/local.js index efb8d32d2..afa1630ea 100644 --- a/src/refs/local.js +++ b/src/refs/local.js @@ -9,7 +9,7 @@ module.exports = configure(({ ky }) => { return async function * refsLocal (options) { options = options || {} - const res = await ky.get('refs/local', { + const res = await ky.post('refs/local', { timeout: options.timeout, signal: options.signal, headers: options.headers diff --git a/src/repo/gc.js b/src/repo/gc.js index 35d4288b0..3d92dee4c 100644 --- a/src/repo/gc.js +++ b/src/repo/gc.js @@ -1,33 +1,29 @@ 'use strict' -const promisify = require('promisify-es6') -const streamToValueWithTransformer = require('../utils/stream-to-value-with-transformer') const CID = require('cids') +const ndjson = require('iterable-ndjson') +const configure = require('../lib/configure') +const toIterable = require('../lib/stream-to-iterable') -const transform = function (res, callback) { - callback(null, res.map(r => ({ - err: r.Err ? new Error(r.Err) : null, - cid: (r.Key || {})['/'] ? new CID(r.Key['/']) : null - }))) -} +module.exports = configure(({ ky }) => { + return async function * gc (peerId, options) { + options = options || {} -module.exports = (send) => { - return promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } - - const request = { - path: 'repo/gc', - qs: opts - } - send(request, (err, result) => { - if (err) { - return callback(err) - } + const searchParams = new URLSearchParams(options.searchParams) + if (options.streamErrors) searchParams.set('stream-errors', options.streamErrors) - streamToValueWithTransformer(result, transform, callback) + const res = await ky.post('repo/gc', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams }) - }) -} + + for await (const gcResult of ndjson(toIterable(res.body))) { + yield { + err: gcResult.Error ? new Error(gcResult.Error) : null, + cid: (gcResult.Key || {})['/'] ? new CID(gcResult.Key['/']) : null + } + } + } +}) diff --git a/src/repo/index.js b/src/repo/index.js index d3ac72785..fe58504ad 100644 --- a/src/repo/index.js +++ b/src/repo/index.js @@ -1,13 +1,10 @@ 'use strict' -const moduleConfig = require('../utils/module-config') +const callbackify = require('callbackify') +const { collectify } = require('../lib/converters') -module.exports = (arg) => { - const send = moduleConfig(arg) - - return { - gc: require('./gc')(send), - stat: require('./stat')(send), - version: require('./version')(send) - } -} +module.exports = config => ({ + gc: callbackify.variadic(collectify(require('./gc')(config))), + stat: callbackify.variadic(require('./stat')(config)), + version: callbackify.variadic(require('./version')(config)) +}) diff --git a/src/repo/stat.js b/src/repo/stat.js index 2b922de03..17895e353 100644 --- a/src/repo/stat.js +++ b/src/repo/stat.js @@ -1,28 +1,28 @@ 'use strict' -const promisify = require('promisify-es6') const Big = require('bignumber.js') +const configure = require('../lib/configure') -const transform = function (res, callback) { - callback(null, { - numObjects: new Big(res.NumObjects), - repoSize: new Big(res.RepoSize), - repoPath: res.RepoPath, - version: res.Version, - storageMax: new Big(res.StorageMax) - }) -} +module.exports = configure(({ ky }) => { + return async options => { + options = options || {} -module.exports = (send) => { - return promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } + const searchParams = new URLSearchParams(options.searchParams) + if (options.sizeOnly) searchParams.set('size-only', options.sizeOnly) + + const res = await ky.post('repo/stat', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() - send.andTransform({ - path: 'repo/stat', - qs: opts - }, transform, callback) - }) -} + return { + numObjects: new Big(res.NumObjects), + repoSize: new Big(res.RepoSize), + repoPath: res.RepoPath, + version: res.Version, + storageMax: new Big(res.StorageMax) + } + } +}) diff --git a/src/repo/version.js b/src/repo/version.js index 84e2a0008..1bfc708e0 100644 --- a/src/repo/version.js +++ b/src/repo/version.js @@ -1,21 +1,21 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../lib/configure') -const transform = function (res, callback) { - callback(null, res.Version) -} +module.exports = configure(({ ky }) => { + return async options => { + options = options || {} -module.exports = (send) => { - return promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } + const searchParams = new URLSearchParams(options.searchParams) + if (options.sizeOnly) searchParams.set('size-only', options.sizeOnly) - send.andTransform({ - path: 'repo/version', - qs: opts - }, transform, callback) - }) -} + const res = await ky.post('repo/version', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return res.Version + } +}) diff --git a/src/resolve.js b/src/resolve.js index f48a3b02b..33c44b6e6 100644 --- a/src/resolve.js +++ b/src/resolve.js @@ -1,54 +1,25 @@ 'use strict' -const promisify = require('promisify-es6') -const multibase = require('multibase') -const CID = require('cids') - -module.exports = (send) => { - return promisify((args, opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } - - opts = opts || {} - - if (opts.cidBase) { - opts['cid-base'] = opts.cidBase - delete opts.cidBase - } - - const transform = (res, callback) => { - if (!opts['cid-base']) { - return callback(null, res.Path) - } - - // FIXME: remove when go-ipfs supports ?cid-base for /api/v0/resolve - // https://github.com/ipfs/go-ipfs/pull/5777#issuecomment-439838555 - const parts = res.Path.split('/') // ['', 'ipfs', 'QmHash', ...] - - if (multibase.isEncoded(parts[2]) !== opts['cid-base']) { - try { - let cid = new CID(parts[2]) - - if (cid.version === 0 && opts['cid-base'] !== 'base58btc') { - cid = cid.toV1() - } - - parts[2] = cid.toBaseEncodedString(opts['cid-base']) - res.Path = parts.join('/') - } catch (err) { - return callback(err) - } - } - - callback(null, res.Path) - } - - send.andTransform({ - path: 'resolve', - args: args, - qs: opts - }, transform, callback) - }) -} +const configure = require('./lib/configure') + +module.exports = configure(({ ky }) => { + return async (path, options) => { + options = options || {} + + const searchParams = new URLSearchParams(options.searchParams) + searchParams.set('arg', `${path}`) + if (options.cidBase) searchParams.set('cid-base', options.cidBase) + if (options.dhtRecordCount) searchParams.set('dht-record-count', options.dhtRecordCount) + if (options.dhtTimeout) searchParams.set('dht-timeout', options.dhtTimeout) + if (options.recursive != null) searchParams.set('recursive', options.recursive) + + const res = await ky.post('resolve', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return res.Path + } +}) diff --git a/src/stats/bitswap.js b/src/stats/bitswap.js deleted file mode 100644 index 3f641f680..000000000 --- a/src/stats/bitswap.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict' - -const promisify = require('promisify-es6') -const Big = require('bignumber.js') - -const transform = function (res, callback) { - callback(null, { - provideBufLen: res.ProvideBufLen, - wantlist: res.Wantlist || [], - peers: res.Peers || [], - blocksReceived: new Big(res.BlocksReceived), - dataReceived: new Big(res.DataReceived), - blocksSent: new Big(res.BlocksSent), - dataSent: new Big(res.DataSent), - dupBlksReceived: new Big(res.DupBlksReceived), - dupDataReceived: new Big(res.DupDataReceived) - }) -} - -module.exports = (send) => { - return promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } - - send.andTransform({ - path: 'stats/bitswap', - qs: opts - }, transform, callback) - }) -} diff --git a/src/stats/bw-pull-stream.js b/src/stats/bw-pull-stream.js deleted file mode 100644 index 26a4eb311..000000000 --- a/src/stats/bw-pull-stream.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict' - -const toPull = require('stream-to-pull-stream') -const map = require('pull-stream/throughs/map') -const pull = require('pull-stream/pull') -const transformChunk = require('./bw-util') -const deferred = require('pull-defer') - -module.exports = (send) => { - return (opts) => { - opts = opts || {} - - const p = deferred.source() - - send({ - path: 'stats/bw', - qs: opts - }, (err, stream) => { - if (err) { - return p.end(err) - } - - p.resolve(pull( - toPull.source(stream), - map(transformChunk) - )) - }) - - return p - } -} diff --git a/src/stats/bw-readable-stream.js b/src/stats/bw-readable-stream.js deleted file mode 100644 index c36fea518..000000000 --- a/src/stats/bw-readable-stream.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict' - -const Stream = require('readable-stream') -const pump = require('pump') -const transformChunk = require('./bw-util') - -module.exports = (send) => { - return (opts) => { - opts = opts || {} - - const pt = new Stream.Transform({ - objectMode: true, - transform (chunk, encoding, cb) { - cb(null, transformChunk(chunk)) - } - }) - - send({ - path: 'stats/bw', - qs: opts - }, (err, stream) => { - if (err) { - return pt.destroy(err) - } - - pump(stream, pt) - }) - - return pt - } -} diff --git a/src/stats/bw-util.js b/src/stats/bw-util.js deleted file mode 100644 index 928ee0c3c..000000000 --- a/src/stats/bw-util.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' - -const Big = require('bignumber.js') - -module.exports = (chunk) => { - return { - totalIn: new Big(chunk.TotalIn), - totalOut: new Big(chunk.TotalOut), - rateIn: new Big(chunk.RateIn), - rateOut: new Big(chunk.RateOut) - } -} diff --git a/src/stats/bw.js b/src/stats/bw.js index 1db636a25..f68ad23ba 100644 --- a/src/stats/bw.js +++ b/src/stats/bw.js @@ -1,29 +1,34 @@ 'use strict' -const promisify = require('promisify-es6') -const streamToValue = require('../utils/stream-to-value') -const transformChunk = require('./bw-util') +const ndjson = require('iterable-ndjson') +const Big = require('bignumber.js') +const configure = require('../lib/configure') +const toIterable = require('../lib/stream-to-iterable') -const transform = (res, callback) => { - return streamToValue(res, (err, data) => { - if (err) { - return callback(err) - } +module.exports = configure(({ ky }) => { + return async function * bw (options) { + options = options || {} - callback(null, transformChunk(data[0])) - }) -} + const searchParams = new URLSearchParams(options.searchParams) + if (options.interval) searchParams.set('interval', options.interval) + if (options.peer) searchParams.set('peer', options.peer) + if (options.poll != null) searchParams.set('poll', options.poll) + if (options.proto) searchParams.set('proto', options.proto) -module.exports = (send) => { - return promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } + const res = await ky.post('stats/bw', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }) - send.andTransform({ - path: 'stats/bw', - qs: opts - }, transform, callback) - }) -} + for await (const stats of ndjson(toIterable(res.body))) { + yield { + totalIn: new Big(stats.TotalIn), + totalOut: new Big(stats.TotalOut), + rateIn: new Big(stats.RateIn), + rateOut: new Big(stats.RateOut) + } + } + } +}) diff --git a/src/stats/index.js b/src/stats/index.js index 445a39835..4351d79e2 100644 --- a/src/stats/index.js +++ b/src/stats/index.js @@ -1,15 +1,19 @@ 'use strict' -const moduleConfig = require('../utils/module-config') - -module.exports = (arg) => { - const send = moduleConfig(arg) +const callbackify = require('callbackify') +const { streamify, pullify } = require('../lib/converters') +module.exports = config => { + const bw = require('./bw')(config) return { - bitswap: require('./bitswap')(send), - bw: require('./bw')(send), - bwReadableStream: require('./bw-readable-stream')(send), - bwPullStream: require('./bw-pull-stream')(send), - repo: require('./repo')(send) + bitswap: callbackify.variadic(require('../bitswap/stat')(config)), + bw: callbackify.variadic(async options => { + for await (const stats of bw(options)) { + return stats + } + }), + bwReadableStream: streamify.readable(bw), + bwPullStream: pullify.source(bw), + repo: callbackify.variadic(require('../repo/stat')(config)) } } diff --git a/src/stats/repo.js b/src/stats/repo.js deleted file mode 100644 index 81f808951..000000000 --- a/src/stats/repo.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict' - -const promisify = require('promisify-es6') -const Big = require('bignumber.js') - -const transform = function (res, callback) { - callback(null, { - numObjects: new Big(res.NumObjects), - repoSize: new Big(res.RepoSize), - repoPath: res.RepoPath, - version: res.Version, - storageMax: new Big(res.StorageMax) - }) -} - -module.exports = (send) => { - return promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } - - send.andTransform({ - path: 'stats/repo', - qs: opts - }, transform, callback) - }) -} diff --git a/src/stop.js b/src/stop.js index 0da69eaa1..7cae46880 100644 --- a/src/stop.js +++ b/src/stop.js @@ -1,12 +1,16 @@ 'use strict' -const promisify = require('promisify-es6') -const moduleConfig = require('./utils/module-config') +const configure = require('./lib/configure') -module.exports = (arg) => { - const send = moduleConfig(arg) +module.exports = configure(({ ky }) => { + return options => { + options = options || {} - return promisify((callback) => { - send({ path: 'shutdown' }, callback) - }) -} + return ky.post('shutdown', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams: options.searchParams + }).text() + } +}) diff --git a/src/swarm/addrs.js b/src/swarm/addrs.js index 103df148b..a786d32cb 100644 --- a/src/swarm/addrs.js +++ b/src/swarm/addrs.js @@ -1,33 +1,25 @@ 'use strict' -const promisify = require('promisify-es6') const PeerInfo = require('peer-info') const PeerId = require('peer-id') const multiaddr = require('multiaddr') +const configure = require('../lib/configure') -module.exports = (send) => { - return promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } - send({ - path: 'swarm/addrs', - qs: opts - }, (err, result) => { - if (err) { - return callback(err) - } +module.exports = configure(({ ky }) => { + return async options => { + options = options || {} - const peers = Object.keys(result.Addrs).map((id) => { - const peerInfo = new PeerInfo(PeerId.createFromB58String(id)) - result.Addrs[id].forEach((addr) => { - peerInfo.multiaddrs.add(multiaddr(addr)) - }) - return peerInfo - }) + const res = await ky.post('swarm/addrs', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams: options.searchParams + }).json() - callback(null, peers) + return Object.keys(res.Addrs).map(id => { + const peerInfo = new PeerInfo(PeerId.createFromB58String(id)) + res.Addrs[id].forEach(addr => peerInfo.multiaddrs.add(multiaddr(addr))) + return peerInfo }) - }) -} + } +}) diff --git a/src/swarm/connect.js b/src/swarm/connect.js index 9875af411..f47ae6974 100644 --- a/src/swarm/connect.js +++ b/src/swarm/connect.js @@ -1,17 +1,22 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../lib/configure') -module.exports = (send) => { - return promisify((args, opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } - send({ - path: 'swarm/connect', - args: args, - qs: opts - }, callback) - }) -} +module.exports = configure(({ ky }) => { + return async (addrs, options) => { + addrs = Array.isArray(addrs) ? addrs : [addrs] + options = options || {} + + const searchParams = new URLSearchParams(options.searchParams) + addrs.forEach(addr => searchParams.append('arg', addr)) + + const res = await ky.post('swarm/connect', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return res.Strings || [] + } +}) diff --git a/src/swarm/disconnect.js b/src/swarm/disconnect.js index 84b800f7e..a3d60d172 100644 --- a/src/swarm/disconnect.js +++ b/src/swarm/disconnect.js @@ -1,17 +1,22 @@ 'use strict' -const promisify = require('promisify-es6') +const configure = require('../lib/configure') -module.exports = (send) => { - return promisify((args, opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } - send({ - path: 'swarm/disconnect', - args: args, - qs: opts - }, callback) - }) -} +module.exports = configure(({ ky }) => { + return async (addrs, options) => { + addrs = Array.isArray(addrs) ? addrs : [addrs] + options = options || {} + + const searchParams = new URLSearchParams(options.searchParams) + addrs.forEach(addr => searchParams.append('arg', addr)) + + const res = await ky.post('swarm/disconnect', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return res.Strings || [] + } +}) diff --git a/src/swarm/index.js b/src/swarm/index.js index fe8c88b35..e86a7c22c 100644 --- a/src/swarm/index.js +++ b/src/swarm/index.js @@ -1,15 +1,11 @@ 'use strict' -const moduleConfig = require('../utils/module-config') +const callbackify = require('callbackify') -module.exports = (arg) => { - const send = moduleConfig(arg) - - return { - peers: require('./peers')(send), - connect: require('./connect')(send), - disconnect: require('./disconnect')(send), - addrs: require('./addrs')(send), - localAddrs: require('./localAddrs')(send) - } -} +module.exports = config => ({ + addrs: callbackify.variadic(require('./addrs')(config)), + connect: callbackify.variadic(require('./connect')(config)), + disconnect: callbackify.variadic(require('./disconnect')(config)), + localAddrs: callbackify.variadic(require('./localAddrs')(config)), + peers: callbackify.variadic(require('./peers')(config)) +}) diff --git a/src/swarm/localAddrs.js b/src/swarm/localAddrs.js index 4798aad52..41c32db2d 100644 --- a/src/swarm/localAddrs.js +++ b/src/swarm/localAddrs.js @@ -1,24 +1,22 @@ 'use strict' -const promisify = require('promisify-es6') const multiaddr = require('multiaddr') +const configure = require('../lib/configure') -module.exports = (send) => { - return promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } - send({ - path: 'swarm/addrs/local', - qs: opts - }, (err, result) => { - if (err) { - return callback(err) - } - callback(null, result.Strings.map((addr) => { - return multiaddr(addr) - })) - }) - }) -} +module.exports = configure(({ ky }) => { + return async options => { + options = options || {} + + const searchParams = new URLSearchParams(options.searchParams) + if (options.id != null) searchParams.append('id', options.id) + + const res = await ky.post('swarm/addrs/local', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() + + return (res.Strings || []).map(a => multiaddr(a)) + } +}) diff --git a/src/swarm/peers.js b/src/swarm/peers.js index 37d11cd7e..3b897348c 100644 --- a/src/swarm/peers.js +++ b/src/swarm/peers.js @@ -1,74 +1,48 @@ 'use strict' -const promisify = require('promisify-es6') const multiaddr = require('multiaddr') const PeerId = require('peer-id') +const configure = require('../lib/configure') -module.exports = (send) => { - return promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } - const verbose = opts.v || opts.verbose - send({ - path: 'swarm/peers', - qs: opts - }, (err, response) => { - if (err) { - return callback(err) - } - const peerInfo = parsePeersResponse(verbose, response) - callback(null, peerInfo) - }) - }) -} +module.exports = configure(({ ky }) => { + return async options => { + options = options || {} -function parsePeersResponse (verbose, response) { - // go-ipfs <= 0.4.4 - if (Array.isArray(response.Strings)) { - return response.Strings.map(parseLegacyPeer.bind(null, verbose)) - } - // go-ipfs >= 0.4.5 - if (Array.isArray(response.Peers)) { - return response.Peers.map(parsePeer.bind(null, verbose)) - } - return [] -} + const searchParams = new URLSearchParams(options.searchParams) + if (options.direction != null) searchParams.append('direction', options.direction) + if (options.latency != null) searchParams.append('latency', options.latency) + if (options.streams != null) searchParams.append('streams', options.streams) + if (options.verbose != null) searchParams.append('verbose', options.verbose) -function parseLegacyPeer (verbose, peer) { - const res = {} - try { - if (verbose) { - const parts = peer.split(' ') - res.addr = multiaddr(parts[0]) - res.latency = parts[1] - } else { - res.addr = multiaddr(peer) - } - res.peer = PeerId.createFromB58String(res.addr.getPeerId()) - } catch (error) { - res.error = error - res.rawPeerInfo = peer - } - return res -} + const res = await ky.post('swarm/peers', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams + }).json() -function parsePeer (verbose, peer) { - const res = {} - try { - res.addr = multiaddr(peer.Addr) - res.peer = PeerId.createFromB58String(peer.Peer) - res.muxer = peer.Muxer - } catch (error) { - res.error = error - res.rawPeerInfo = peer - } - if (peer.Latency) { - res.latency = peer.Latency - } - if (peer.Streams) { - res.streams = peer.Streams + return (res.Peers || []).map(peer => { + const info = {} + try { + info.addr = multiaddr(peer.Addr) + info.peer = PeerId.createFromB58String(peer.Peer) + } catch (error) { + info.error = error + info.rawPeerInfo = peer + } + if (peer.Muxer) { + info.muxer = peer.Muxer + } + if (peer.Latency) { + info.latency = peer.Latency + } + if (peer.Streams) { + info.streams = peer.Streams + } + if (peer.Direction != null) { + info.direction = peer.Direction + } + return info + }) } - return res -} +}) diff --git a/src/update.js b/src/update.js index aee1a64a6..91bea6f7f 100644 --- a/src/update.js +++ b/src/update.js @@ -1,41 +1,16 @@ 'use strict' -const promisify = require('promisify-es6') -const moduleConfig = require('./utils/module-config') +const configure = require('./lib/configure') -module.exports = (arg) => { - const send = moduleConfig(arg) +module.exports = configure(({ ky }) => { + return options => { + options = options || {} - return { - apply: promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } - send({ - path: 'update', - qs: opts - }, callback) - }), - check: promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } - send({ - path: 'update/check', - qs: opts - }, callback) - }), - log: promisify((opts, callback) => { - if (typeof (opts) === 'function') { - callback = opts - opts = {} - } - send({ - path: 'update/log', - qs: opts - }, callback) - }) + return ky.post('update', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams: options.searchParams + }).text() } -} +}) diff --git a/src/utils/clean-cid.js b/src/utils/clean-cid.js deleted file mode 100644 index 1767c9ac2..000000000 --- a/src/utils/clean-cid.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict' - -const CID = require('cids') - -module.exports = function (cid) { - if (Buffer.isBuffer(cid)) { - return new CID(cid).toString() - } - if (CID.isCID(cid)) { - return cid.toString() - } - if (typeof cid !== 'string') { - throw new Error('unexpected cid type: ' + typeof cid) - } - new CID(cid.split('/')[0]) // eslint-disable-line no-new - return cid -} diff --git a/src/utils/clean-multihash.js b/src/utils/clean-multihash.js deleted file mode 100644 index 230135ad7..000000000 --- a/src/utils/clean-multihash.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict' - -const bs58 = require('bs58') -const CID = require('cids') -const isIPFS = require('is-ipfs') - -module.exports = function (multihash) { - if (Buffer.isBuffer(multihash)) { - multihash = bs58.encode(multihash) - } - if (CID.isCID(multihash)) { - multihash = multihash.toBaseEncodedString() - } - if (typeof multihash !== 'string') { - throw new Error('unexpected multihash type: ' + typeof multihash) - } - if (!isIPFS.multihash(multihash.split('/')[0])) { - throw new Error('not valid multihash') - } - return multihash -} diff --git a/src/utils/default-config.js b/src/utils/default-config.js deleted file mode 100644 index 5ae6ae82e..000000000 --- a/src/utils/default-config.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -const pkg = require('../../package.json') - -exports = module.exports = () => { - return { - 'api-path': '/api/v0/', - 'user-agent': `/node-${pkg.name}/${pkg.version}/`, - host: 'localhost', - port: '5001', - protocol: 'http' - } -} diff --git a/src/utils/load-commands.js b/src/utils/load-commands.js deleted file mode 100644 index a4a6dcd07..000000000 --- a/src/utils/load-commands.js +++ /dev/null @@ -1,161 +0,0 @@ -'use strict' - -const nodeify = require('promise-nodeify') -const callbackify = require('callbackify') -const all = require('async-iterator-all') -const { concatify, collectify, pullify, streamify } = require('../lib/converters') -const toPullStream = require('async-iterator-to-pull-stream') -const pull = require('pull-stream/pull') -const map = require('pull-stream/throughs/map') -const toStream = require('it-to-stream') -const BufferList = require('bl/BufferList') - -function requireCommands (send, config) { - const add = require('../add')(config) - const addFromFs = require('../add-from-fs')(config) - const addFromURL = require('../add-from-url')(config) - const cat = require('../cat')(config) - const get = require('../get')(config) - const ls = require('../ls')(config) - const refs = require('../refs')(config) - - const cmds = { - add: (input, options, callback) => { - if (typeof options === 'function') { - callback = options - options = {} - } - return nodeify(collectify(add)(input, options), callback) - }, - addReadableStream: streamify.transform(add), - addPullStream: pullify.transform(add), - addFromFs: (path, options, callback) => { - if (typeof options === 'function') { - callback = options - options = {} - } - return nodeify(collectify(addFromFs)(path, options), callback) - }, - addFromURL: (url, options, callback) => { - if (typeof options === 'function') { - callback = options - options = {} - } - return nodeify(collectify(addFromURL)(url, options), callback) - }, - addFromStream: (input, options, callback) => { - if (typeof options === 'function') { - callback = options - options = {} - } - return nodeify(collectify(add)(input, options), callback) - }, - _addAsyncIterator: add, - cat: callbackify.variadic((path, options) => concatify(cat)(path, options)), - catReadableStream: streamify.readable(cat), - catPullStream: pullify.source(cat), - _catAsyncIterator: cat, - get: callbackify.variadic(async (path, options) => { - const output = [] - - for await (const entry of get(path, options)) { - if (entry.content) { - entry.content = new BufferList(await all(entry.content)).slice() - } - - output.push(entry) - } - - return output - }), - getReadableStream: streamify.readable((path, options) => (async function * () { - for await (const file of get(path, options)) { - if (file.content) { - const { content } = file - file.content = toStream((async function * () { - for await (const chunk of content) { - yield chunk.slice() // Convert bl to Buffer - } - })()) - } - - yield file - } - })()), - getPullStream: (path, options) => { - return pull( - toPullStream(get(path, options)), - map(file => { - if (file.content) { - file.content = pull( - toPullStream(file.content), - map(chunk => chunk.slice()) // Convert bl to Buffer - ) - } - - return file - }) - ) - }, - _getAsyncIterator: get, - ls: callbackify.variadic((path, options) => collectify(ls)(path, options)), - lsReadableStream: streamify.readable(ls), - lsPullStream: pullify.source(ls), - _lsAsyncIterator: ls, - object: require('../object')(config), - refs: callbackify.variadic((path, options) => collectify(refs)(path, options)), - refsReadableStream: streamify.readable(refs), - refsPullStream: pullify.source(refs), - _refsAsyncIterator: refs, - getEndpointConfig: require('../get-endpoint-config')(config), - bitswap: require('../bitswap')(config), - block: require('../block')(config), - bootstrap: require('../bootstrap')(config), - config: require('../config')(config), - dag: require('../dag')(config), - dht: require('../dht')(config), - diag: require('../diag')(config), - files: require('../files')(config), - pin: require('../pin')(config) - } - - Object.assign(cmds.refs, { - local: callbackify.variadic(options => collectify(refs.local)(options)), - localReadableStream: streamify.readable(refs.local), - localPullStream: pullify.source(refs.local), - _localAsyncIterator: refs.local - }) - - const subCmds = { - // Network - name: require('../name'), - ping: require('../ping'), - pingReadableStream: require('../ping-readable-stream'), - pingPullStream: require('../ping-pull-stream'), - swarm: require('../swarm'), - pubsub: require('../pubsub'), - dns: require('../dns'), - - // Miscellaneous - commands: require('../commands'), - id: require('../id'), - key: require('../key'), - log: require('../log'), - mount: require('../mount'), - repo: require('../repo'), - stop: require('../stop'), - shutdown: require('../stop'), - stats: require('../stats'), - update: require('../update'), - version: require('../version'), - resolve: require('../resolve') - } - - Object.keys(subCmds).forEach((file) => { - cmds[file] = subCmds[file](send, config) - }) - - return cmds -} - -module.exports = requireCommands diff --git a/src/utils/module-config.js b/src/utils/module-config.js deleted file mode 100644 index 4e1b0e6a1..000000000 --- a/src/utils/module-config.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict' - -const getConfig = require('./default-config') -const sendRequest = require('./send-request') -const multiaddr = require('multiaddr') - -module.exports = (arg) => { - const config = getConfig() - - if (typeof arg === 'function') { - return arg - } else if (typeof arg === 'object') { - return sendRequest(arg) - } else if (typeof arg === 'string') { - const maddr = multiaddr(arg).nodeAddress() - config.host = maddr.address - config.port = maddr.port - return sendRequest(config) - } else { - throw new Error('Argument must be a send function or a config object.') - } -} diff --git a/src/utils/multipart.js b/src/utils/multipart.js deleted file mode 100644 index 78bead247..000000000 --- a/src/utils/multipart.js +++ /dev/null @@ -1,121 +0,0 @@ -'use strict' - -const Transform = require('readable-stream').Transform -const isNode = require('detect-node') - -const PADDING = '--' -const NEW_LINE = '\r\n' -const NEW_LINE_BUFFER = Buffer.from(NEW_LINE) - -class Multipart extends Transform { - constructor (options) { - super(Object.assign({}, options, { objectMode: true, highWaterMark: 1 })) - - this._boundary = this._generateBoundary() - this._files = [] - this._draining = false - } - - _flush () { - this.push(Buffer.from(PADDING + this._boundary + PADDING + NEW_LINE)) - this.push(null) - } - - _generateBoundary () { - var boundary = '--------------------------' - for (var i = 0; i < 24; i++) { - boundary += Math.floor(Math.random() * 10).toString(16) - } - - return boundary - } - - _transform (file, encoding, callback) { - if (Buffer.isBuffer(file)) { - this.push(file) - return callback() // early - } - // not a buffer, must be a file - this._files.push(file) - this._maybeDrain(callback) - } - - _maybeDrain (callback) { - if (!this._draining) { - if (this._files.length) { - this._draining = true - const file = this._files.shift() - this._pushFile(file, (err) => { - this._draining = false - if (err) { - this.emit('error', err) - } else { - this._maybeDrain(callback) - } - }) - } else { - this.emit('drained all files') - callback() - } - } else { - this.once('drained all files', callback) - } - } - - _pushFile (file, callback) { - const leading = this._leading(file.headers || {}) - - this.push(leading) - - const content = file.content || Buffer.alloc(0) - - if (Buffer.isBuffer(content)) { - this.push(content) - this.push(NEW_LINE_BUFFER) - return callback() // early - } - - // From now on we assume content is a stream - content.once('error', this.emit.bind(this, 'error')) - - content.once('end', () => { - this.push(NEW_LINE_BUFFER) - callback() - - // TODO: backpressure!!! wait once self is drained so we can proceed - // This does not work - // this.once('drain', () => { - // callback() - // }) - }) - - content.on('data', (data) => { - const drained = this.push(data) - // Only do the drain dance on Node.js. - // In browserland, the underlying stream - // does NOT drain because the request is only sent - // once this stream ends. - if (!drained && isNode) { - content.pause() - this.once('drain', () => content.resume()) - } - }) - } - - _leading (headers) { - var leading = [PADDING + this._boundary] - - Object.keys(headers).forEach((header) => { - leading.push(header + ': ' + headers[header]) - }) - - leading.push('') - leading.push('') - - const leadingStr = leading.join(NEW_LINE) - - return Buffer.from(leadingStr) - } -} - -module.exports = Multipart diff --git a/src/utils/ping-message-converter.js b/src/utils/ping-message-converter.js deleted file mode 100644 index 79d9fc3be..000000000 --- a/src/utils/ping-message-converter.js +++ /dev/null @@ -1,23 +0,0 @@ -'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 deleted file mode 100644 index 944e2d9cf..000000000 --- a/src/utils/ping-message-stream.js +++ /dev/null @@ -1,27 +0,0 @@ -'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/prepare-file.js b/src/utils/prepare-file.js deleted file mode 100644 index 9a02f8338..000000000 --- a/src/utils/prepare-file.js +++ /dev/null @@ -1,153 +0,0 @@ -'use strict' - -const isNode = require('detect-node') -const flatmap = require('flatmap') -const { Readable } = require('readable-stream') -const kindOf = require('kind-of') -const { isSource } = require('is-pull-stream') -const isStream = require('is-stream') -const pullToStream = require('pull-to-stream') -const { supportsFileReader } = require('ipfs-utils/src/supports') -const streamFromFileReader = require('ipfs-utils/src/streams/stream-from-filereader') - -function loadPaths (opts, file) { - const path = require('path') - const fs = require('fs') - const glob = require('glob') - - const followSymlinks = opts.followSymlinks != null ? opts.followSymlinks : true - - file = path.resolve(file) - const stats = fs.statSync(file) - - if (stats.isDirectory() && !opts.recursive) { - throw new Error('Can only add directories using --recursive') - } - - if (stats.isDirectory() && opts.recursive) { - // glob requires a POSIX filename - file = file.split(path.sep).join('/') - const fullDir = file + (file.endsWith('/') ? '' : '/') - let dirName = fullDir.split('/') - dirName = dirName[dirName.length - 2] + '/' - const mg = new glob.sync.GlobSync('**/*', { - cwd: file, - follow: followSymlinks, - dot: opts.hidden, - ignore: opts.ignore - }) - - return mg.found - .map((name) => { - const fqn = fullDir + name - // symlinks - if (mg.symlinks[fqn] === true) { - return { - path: dirName + name, - symlink: true, - dir: false, - content: fs.readlinkSync(fqn) - } - } - - // files - if (mg.cache[fqn] === 'FILE') { - return { - path: dirName + name, - symlink: false, - dir: false, - content: fs.createReadStream(fqn) - } - } - - // directories - if (mg.cache[fqn] === 'DIR' || mg.cache[fqn] instanceof Array) { - return { - path: dirName + name, - symlink: false, - dir: true - } - } - // files inside symlinks and others - }) - // filter out null files - .filter(Boolean) - } - - return { - path: path.basename(file), - content: fs.createReadStream(file) - } -} - -function contentToStream (content) { - if (supportsFileReader && kindOf(content) === 'file') { - return streamFromFileReader(content) - } - - if (kindOf(content) === 'buffer') { - return new Readable({ - read () { - this.push(content) - this.push(null) - } - }) - } - - if (isSource(content)) { - return pullToStream.readable(content) - } - - if (isStream.readable(content)) { - return content - } - - throw new Error(`Input not supported. Expected Buffer|ReadableStream|PullStream|File got ${kindOf(content)}. Check the documentation for more info https://github.com/ipfs/interface-js-ipfs-core/blob/master/SPEC/FILES.md#add`) -} - -function prepareFile (file, opts) { - const files = [].concat(file) - - return flatmap(files, (file) => { - // add from fs with file path - if (typeof file === 'string') { - if (!isNode) { - throw new Error('Can only add file paths in node') - } - - return loadPaths(opts, file) - } - - // add with object syntax { path : , content: {}) - } - - static fromStream (track, stream) { - const prog = new ProgressStream({ track }) - return stream.pipe(prog) - } - - _transform (chunk, encoding, callback) { - if (chunk && - typeof chunk.Bytes !== 'undefined' && - typeof chunk.Hash === 'undefined') { - this._track(chunk.Bytes) - return callback() - } - - callback(null, chunk) - } -} - -module.exports = ProgressStream diff --git a/src/utils/send-files-stream.js b/src/utils/send-files-stream.js deleted file mode 100644 index 09c55d376..000000000 --- a/src/utils/send-files-stream.js +++ /dev/null @@ -1,161 +0,0 @@ -'use strict' - -const { Duplex } = require('readable-stream') -const eachSeries = require('async/eachSeries') -const isStream = require('is-stream') -const once = require('once') -const prepareFile = require('./prepare-file') -const Multipart = require('./multipart') - -function headers (file, i) { - const filename = file.path - ? encodeURIComponent(file.path) - : '' - - const header = { 'Content-Disposition': `form-data; name="data${i}"; filename="${filename}"` } - - if (!file.content) { - header['Content-Type'] = 'application/x-directory' - } else if (file.symlink) { - header['Content-Type'] = 'application/symlink' - } else { - header['Content-Type'] = 'application/octet-stream' - } - - return header -} - -module.exports = (send, path) => { - return (options) => { - let ended = false - let writing = false - - options = options ? Object.assign({}, options, options.qs) : {} - - const multipart = new Multipart() - - const retStream = new Duplex({ objectMode: true }) - - retStream._read = (n) => {} - - retStream._write = (file, enc, _next) => { - const next = once(_next) - try { - const files = prepareFile(file, options) - .map((file, i) => Object.assign({ headers: headers(file, i) }, file)) - - writing = true - eachSeries( - files, - (file, cb) => multipart.write(file, enc, cb), - (err) => { - writing = false - if (err) { - return next(err) - } - if (ended) { - multipart.end() - } - next() - }) - } catch (err) { - next(err) - } - } - - retStream.once('finish', () => { - if (!ended) { - ended = true - if (!writing) { - multipart.end() - } - } - }) - - const qs = options.qs || {} - - qs['cid-version'] = propOrProp(options, 'cid-version', 'cidVersion') - qs['raw-leaves'] = propOrProp(options, 'raw-leaves', 'rawLeaves') - qs['only-hash'] = propOrProp(options, 'only-hash', 'onlyHash') - qs['wrap-with-directory'] = propOrProp(options, 'wrap-with-directory', 'wrapWithDirectory') - qs.pin = propOrProp(options, 'pin') - qs.preload = propOrProp(options, 'preload') - qs.hash = propOrProp(options, 'hash', 'hashAlg') - - if (options.strategy === 'trickle' || options.trickle) { - qs.trickle = 'true' - } - - const args = { - path: path, - qs: qs, - args: options.args, - multipart: true, - multipartBoundary: multipart._boundary, - stream: true, - recursive: true, - progress: options.progress - } - - multipart.on('error', (err) => { - retStream.emit('error', err) - }) - - const request = send(args, (err, response) => { - if (err) { - return retStream.emit('error', err) - } - - if (!response) { - // no response, which means everything is ok, so we end the retStream - return retStream.push(null) // early - } - - if (!isStream(response)) { - retStream.push(response) - retStream.push(null) - return - } - - response.on('error', (err) => retStream.emit('error', err)) - - if (options.converter) { - response.on('data', (d) => { - if (d.Bytes && options.progress) { - options.progress(d.Bytes) - } - }) - - const Converter = options.converter - const convertedResponse = new Converter() - convertedResponse.once('end', () => retStream.push(null)) - convertedResponse.on('data', (d) => retStream.push(d)) - response.pipe(convertedResponse) - } else { - response.on('data', (d) => { - if (d.Bytes && options.progress) { - options.progress(d.Bytes) - } - retStream.push(d) - }) - response.once('end', () => retStream.push(null)) - } - }) - - // signal the multipart that the underlying stream has drained and that - // it can continue producing data.. - request.on('drain', () => multipart.emit('drain')) - - multipart.pipe(request) - - return retStream - } -} - -function propOrProp (source, prop1, prop2) { - if (prop1 in source) { - return source[prop1] - } else if (prop2 in source) { - return source[prop2] - } -} diff --git a/src/utils/send-one-file-multiple-results.js b/src/utils/send-one-file-multiple-results.js deleted file mode 100644 index 180a9ad34..000000000 --- a/src/utils/send-one-file-multiple-results.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict' - -const once = require('once') -const ConcatStream = require('concat-stream') -const SendFilesStream = require('./send-files-stream') - -module.exports = (send, path) => { - const sendFilesStream = SendFilesStream(send, path) - return (file, options, _callback) => { - const callback = once(_callback) - const stream = sendFilesStream(options) - const concat = ConcatStream((results) => callback(null, results)) - stream.once('error', callback) - stream.pipe(concat) - stream.write(file) - stream.end() - } -} diff --git a/src/utils/send-one-file.js b/src/utils/send-one-file.js deleted file mode 100644 index 7b510f19d..000000000 --- a/src/utils/send-one-file.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict' - -const SendOneFileMultipleResults = require('./send-one-file-multiple-results') - -module.exports = (send, path) => { - const sendFile = SendOneFileMultipleResults(send, path) - return (file, options, callback) => { - sendFile(file, options, (err, results) => { - if (err) { - return callback(err) - } - callback(null, results[0]) - }) - } -} diff --git a/src/utils/send-request.js b/src/utils/send-request.js deleted file mode 100644 index 1645969f2..000000000 --- a/src/utils/send-request.js +++ /dev/null @@ -1,239 +0,0 @@ -'use strict' - -const Qs = require('qs') -const qsDefaultEncoder = require('qs/lib/utils').encode -const isNode = require('detect-node') -const ndjson = require('ndjson') -const pump = require('pump') -const once = require('once') -const { getRequest } = require('iso-stream-http') -const streamToValue = require('./stream-to-value') -const streamToJsonValue = require('./stream-to-json-value') -const log = require('debug')('ipfs-http-client:request') - -// -- Internal - -function hasJSONHeaders (res) { - return res.headers['content-type'] && - res.headers['content-type'].indexOf('application/json') === 0 -} - -function parseError (res, cb) { - const error = new Error(`Server responded with ${res.statusCode}`) - error.statusCode = res.statusCode - - if (!hasJSONHeaders(res)) { - return streamToValue(res, (err, data) => { // eslint-disable-line handle-callback-err - // the `err` here refers to errors in stream processing, which - // we ignore here, since we already have a valid `error` response - // from the server above that we have to report to the caller. - if (data && data.length) { - error.message = data.toString() - } - cb(error) - }) - } - - streamToJsonValue(res, (err, payload) => { - if (err) { - return cb(err) - } - - if (payload) { - error.code = payload.Code - error.message = payload.Message || payload.toString() - error.type = payload.Type - } - cb(error) - }) -} - -function onRes (buffer, cb) { - return (res) => { - const stream = Boolean(res.headers['x-stream-output']) - const chunkedObjects = Boolean(res.headers['x-chunked-output']) - const isJson = hasJSONHeaders(res) - - 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) - } - - // Return the response stream directly - if (stream && !buffer) { - return cb(null, res) - } - - // Return a stream of JSON objects - if (chunkedObjects && isJson) { - const outputStream = ndjson.parse() - pump(res, outputStream) - res.on('end', () => { - let err = res.trailers['x-stream-error'] - if (err) { - // Not all errors are JSON - try { - err = JSON.parse(err) - } catch (e) { - err = { Message: err } - } - outputStream.emit('error', new Error(err.Message)) - } - }) - return cb(null, outputStream) - } - - // Return a JSON object - if (isJson) { - return streamToJsonValue(res, cb) - } - - // Return a value - return streamToValue(res, cb) - } -} - -function requestAPI (config, options, callback) { - callback = once(callback) - options.qs = options.qs || {} - - if (Array.isArray(options.path)) { - options.path = options.path.join('/') - } - if (options.args && !Array.isArray(options.args)) { - options.args = [options.args] - } - if (options.args) { - options.qs.arg = options.args - } - if (options.progress) { - options.qs.progress = true - } - - if (options.qs.r) { - options.qs.recursive = options.qs.r - // From IPFS 0.4.0, it throws an error when both r and recursive are passed - delete options.qs.r - } - - options.qs['stream-channels'] = true - - if (options.stream) { - options.buffer = false - } - - // this option is only used internally, not passed to daemon - delete options.qs.followSymlinks - - const method = 'POST' - const headers = Object.assign({}, config.headers) - - if (isNode) { - // Browsers do not allow you to modify the user agent - headers['User-Agent'] = config['user-agent'] - } - - if (options.multipart) { - if (!options.multipartBoundary) { - return callback(new Error('No multipartBoundary')) - } - - headers['Content-Type'] = `multipart/form-data; boundary=${options.multipartBoundary}` - } - - const qs = Qs.stringify(options.qs, { - arrayFormat: 'repeat', - encoder: data => { - // TODO: future releases of qs will provide the default - // encoder as a 2nd argument to this function; it will - // no longer be necessary to import qsDefaultEncoder - if (Buffer.isBuffer(data)) { - let uriEncoded = '' - for (const byte of data) { - // https://tools.ietf.org/html/rfc3986#page-14 - // ALPHA (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) - if ( - (byte >= 0x41 && byte <= 0x5A) || - (byte >= 0x61 && byte <= 0x7A) || - (byte >= 0x30 && byte <= 0x39) || - (byte === 0x2D) || - (byte === 0x2E) || - (byte === 0x5F) || - (byte === 0x7E) - ) { - uriEncoded += String.fromCharCode(byte) - } else { - const hex = byte.toString(16) - // String.prototype.padStart() not widely supported yet - const padded = hex.length === 1 ? `0${hex}` : hex - uriEncoded += `%${padded}` - } - } - return uriEncoded - } - return qsDefaultEncoder(data) - } - }) - const reqOptions = { - hostname: config.host, - path: `${config['api-path']}${options.path}?${qs}`, - port: config.port, - method: method, - headers: headers, - protocol: `${config.protocol}:` - } - - const req = getRequest(reqOptions, onRes(options.buffer, callback)) - - req.on('error', (err) => { - callback(err) - }) - - if (!options.stream) { - req.end() - } - - return req -} - -// -// -- Module Interface - -exports = module.exports = (config) => { - /* - * options: { - * path: // API path (like /add or /config) - type: string - * args: // Arguments to the command - type: object - * qs: // Opts as query string opts to the command --something - type: object - * files: // files to be sent - type: string, buffer or array of strings or buffers - * buffer: // buffer the request before sending it - type: bool - * } - */ - const send = (options, callback) => { - if (typeof options !== 'object') { - return callback(new Error('no options were passed')) - } - - return requestAPI(config, options, callback) - } - - // Send a HTTP request and pass via a transform function - // to convert the response data to wanted format before - // returning it to the callback. - // Eg. send.andTransform({}, (e) => JSON.parse(e), (err, res) => ...) - send.andTransform = (options, transform, callback) => { - return send(options, (err, res) => { - if (err) { - return callback(err) - } - transform(res, callback) - }) - } - - return send -} diff --git a/src/utils/stream-to-json-value.js b/src/utils/stream-to-json-value.js deleted file mode 100644 index 2ae83e50d..000000000 --- a/src/utils/stream-to-json-value.js +++ /dev/null @@ -1,34 +0,0 @@ -'use strict' - -const streamToValue = require('./stream-to-value') - -/* - Converts a stream to a single JSON value -*/ -function streamToJsonValue (res, cb) { - streamToValue(res, (err, data) => { - if (err) { - return cb(err) - } - - if (!data || data.length === 0) { - return cb() - } - - // TODO: check if needed, afaik JSON.parse can parse Buffers - if (Buffer.isBuffer(data)) { - data = data.toString() - } - - let res - try { - res = JSON.parse(data) - } catch (err) { - return cb(new Error(`Invalid JSON: ${data}`)) - } - - cb(null, res) - }) -} - -module.exports = streamToJsonValue diff --git a/src/utils/stream-to-value-with-transformer.js b/src/utils/stream-to-value-with-transformer.js deleted file mode 100644 index 402148667..000000000 --- a/src/utils/stream-to-value-with-transformer.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict' - -const streamToValue = require('./stream-to-value') - -function streamToValueWithTransformer (response, transformer, callback) { - if (typeof response.pipe === 'function') { - streamToValue(response, (err, res) => { - if (err) { - return callback(err) - } - transformer(res, callback) - }) - } else { - transformer(response, callback) - } -} - -module.exports = streamToValueWithTransformer diff --git a/src/utils/stream-to-value.js b/src/utils/stream-to-value.js deleted file mode 100644 index d28fd6130..000000000 --- a/src/utils/stream-to-value.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict' - -const pump = require('pump') -const concat = require('concat-stream') - -/* - Concatenate a stream to a single value. -*/ -function streamToValue (response, callback) { - let data - pump( - response, - concat((d) => { data = d }), - (err) => callback(err, data) - ) -} - -module.exports = streamToValue diff --git a/src/version.js b/src/version.js index 438cdd000..8faee147a 100644 --- a/src/version.js +++ b/src/version.js @@ -1,30 +1,19 @@ 'use strict' -const promisify = require('promisify-es6') -const moduleConfig = require('./utils/module-config') +const configure = require('./lib/configure') +const toCamel = require('./lib/object-to-camel') -module.exports = (arg) => { - const send = moduleConfig(arg) +module.exports = configure(({ ky }) => { + return async options => { + options = options || {} - return promisify((opts, callback) => { - if (typeof opts === 'function') { - callback = opts - opts = {} - } + const res = await ky.post('version', { + timeout: options.timeout, + signal: options.signal, + headers: options.headers, + searchParams: options.searchParams + }).json() - send({ - path: 'version', - qs: opts - }, (err, result) => { - if (err) { - return callback(err) - } - const version = { - version: result.Version, - commit: result.Commit, - repo: result.Repo - } - callback(null, version) - }) - }) -} + return toCamel(res) + } +}) diff --git a/test/constructor.spec.js b/test/constructor.spec.js index e4a7eb1aa..60bfc9f33 100644 --- a/test/constructor.spec.js +++ b/test/constructor.spec.js @@ -44,15 +44,6 @@ describe('ipfs-http-client constructor tests', () => { expectConfig(ipfs, { host, port, protocol }) }) - it('multiaddr dns4 string, explicit https in opts', () => { - const host = 'foo.com' - const port = '1001' - const protocol = 'https' - const addr = `/dns4/${host}/tcp/${port}` - const ipfs = ipfsClient(addr, { protocol }) - expectConfig(ipfs, { host, port, protocol }) - }) - it('multiaddr ipv4 string (implicit http)', () => { const host = '101.101.101.101' const port = '1001' @@ -82,7 +73,7 @@ describe('ipfs-http-client constructor tests', () => { it('host and port strings', () => { const host = '1.1.1.1' const port = '9999' - const ipfs = ipfsClient(host, port) + const ipfs = ipfsClient({ host, port }) expectConfig(ipfs, { host, port }) }) @@ -90,14 +81,14 @@ describe('ipfs-http-client constructor tests', () => { const host = '10.100.100.255' const port = '9999' const apiPath = '/future/api/v1/' - const ipfs = ipfsClient(host, port, { 'api-path': apiPath }) - expectConfig(ipfs, { host, port, apiPath }) + const ipfs = ipfsClient({ host, port, apiPath }) + expectConfig(ipfs, { host, port, apiPath: apiPath.slice(0, -1) }) }) it('throws on invalid multiaddr', () => { expect(() => ipfsClient('/dns4')).to.throw('invalid address') expect(() => ipfsClient('/hello')).to.throw('no protocol with name') - expect(() => ipfsClient('/dns4/ipfs.io')).to.throw('multiaddr must have a valid format') + expect(() => ipfsClient('/dns4/ipfs.io')).to.throw() }) }) @@ -134,7 +125,7 @@ async function clientWorks (client) { function expectConfig (ipfs, { host, port, protocol, apiPath }) { const conf = ipfs.getEndpointConfig() expect(conf.host).to.be.oneOf([host, 'localhost', '']) - expect(conf.port).to.be.oneOf([port, '5001', 80]) + expect(conf.port).to.be.oneOf([port, '5001', '80']) expect(conf.protocol).to.equal(protocol || 'http') - expect(conf['api-path']).to.equal(apiPath || '/api/v0/') + expect(conf['api-path']).to.equal(apiPath || '/api/v0') } diff --git a/test/custom-headers.spec.js b/test/custom-headers.spec.js index 0780c23b9..ce14a01e5 100644 --- a/test/custom-headers.spec.js +++ b/test/custom-headers.spec.js @@ -4,23 +4,13 @@ const isNode = require('detect-node') const { expect } = require('interface-ipfs-core/src/utils/mocha') const ipfsClient = 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(async () => { - ipfsd = await f.spawn({ - initOptions: { - bits: 1024, - profile: 'test' - } - }) - + before(() => { ipfs = ipfsClient({ host: 'localhost', port: 6001, @@ -37,6 +27,7 @@ describe('custom headers', function () { req.on('data', () => {}) req.on('end', () => { res.writeHead(200) + res.write(JSON.stringify({})) res.end() // ensure custom headers are present expect(req.headers.authorization).to.equal('Bearer ' + 'YOLO') @@ -48,16 +39,10 @@ describe('custom headers', function () { server.listen(6001, () => { ipfs.id((err, res) => { if (err) { - throw new Error('Unexpected error.') + throw err } // this call is used to test that headers are being sent. }) }) }) - - after(async () => { - if (ipfsd) { - await ipfsd.stop() - } - }) }) diff --git a/test/endpoint-config.spec.js b/test/endpoint-config.spec.js index c867717b9..a44de3e1c 100644 --- a/test/endpoint-config.spec.js +++ b/test/endpoint-config.spec.js @@ -3,43 +3,16 @@ 'use strict' const { expect } = require('interface-ipfs-core/src/utils/mocha') -const isNode = require('detect-node') const ipfsClient = require('../src') -const f = require('./utils/factory') describe('.getEndpointConfig', () => { - if (!isNode) { return } - - let ipfsd - let ipfs - - before(async function () { - this.timeout(20 * 1000) // slow CI - - ipfsd = await f.spawn({ - initOptions: { - bits: 1024, - profile: 'test' - } - }) - ipfs = ipfsClient(ipfsd.apiAddr) - }) - - after(async function () { - this.timeout(10 * 1000) - - if (ipfsd) { - await ipfsd.stop() - } - }) - it('should return the endpoint configuration', function () { + const ipfs = ipfsClient('https://127.0.0.1:5501/ipfs/api/') const endpoint = ipfs.getEndpointConfig() expect(endpoint.host).to.equal('127.0.0.1') - expect(endpoint.protocol).to.equal('http') - expect(endpoint['api-path']).to.equal('/api/v0/') - // changes per test run so we just assert it exists. - expect(endpoint).to.have.property('port') + expect(endpoint.protocol).to.equal('https') + expect(endpoint['api-path']).to.equal('/ipfs/api') + expect(endpoint.port).to.equal('5501') }) }) diff --git a/test/lib.configure.spec.js b/test/lib.configure.spec.js index 8cb56be5f..550165035 100644 --- a/test/lib.configure.spec.js +++ b/test/lib.configure.spec.js @@ -10,7 +10,7 @@ describe('lib/configure', () => { it('should accept no config', () => { configure(config => { if (isBrowser || isWebWorker) { - expect(config.apiAddr).to.eql('') + expect(config.apiAddr).to.eql(location.origin) } else { expect(config.apiAddr).to.eql('http://localhost:5001') } @@ -24,10 +24,17 @@ describe('lib/configure', () => { })(input) }) + it('should accept string url', () => { + const input = 'http://127.0.0.1:5001' + configure(config => { + expect(config.apiAddr).to.eql('http://127.0.0.1:5001') + })(input) + }) + it('should accept multiaddr instance', () => { - const input = Multiaddr('/ip4/127.0.0.1') + const input = Multiaddr('/ip4/127.0.0.1/tcp/5001') configure(config => { - expect(config.apiAddr).to.eql('http://127.0.0.1') + expect(config.apiAddr).to.eql('http://127.0.0.1:5001') })(input) }) diff --git a/test/log.spec.js b/test/log.spec.js index a9dbc0274..7f8e2c608 100644 --- a/test/log.spec.js +++ b/test/log.spec.js @@ -37,20 +37,11 @@ describe('.log', function () { } }, 1000) - const res = await ipfs.log.tail() - - return new Promise((resolve, reject) => { - res.on('error', (err) => { - reject(err) - }) - - res.once('data', (obj) => { - clearInterval(i) - expect(obj).to.be.an('object') - res.end() - resolve() - }) - }) + for await (const message of ipfs.log.tail()) { + clearInterval(i) + expect(message).to.be.an('object') + break + } }) it('.log.ls', async () => { @@ -65,7 +56,7 @@ describe('.log', function () { expect(res).to.exist() expect(res).to.be.an('object') - expect(res).to.not.have.property('Error') - expect(res).to.have.property('Message') + expect(res).to.not.have.property('error') + expect(res).to.have.property('message') }) }) diff --git a/test/node/swarm.js b/test/node/swarm.js index 27d377904..9e0252a2c 100644 --- a/test/node/swarm.js +++ b/test/node/swarm.js @@ -29,24 +29,6 @@ describe('.swarm.peers', function () { expect(scope.isDone()).to.equal(true) }) - it('handles a go-ipfs <= 0.4.4 peer response', async () => { - const response = { Strings: ['/ip4/73.109.217.59/tcp/49311/ipfs/QmWjxEGC7BthJrCf7QTModrcsRweHbupdPTY4oGMVoDZXm'] } - - const scope = nock(apiUrl) - .post('/api/v0/swarm/peers') - .query(true) - .reply(200, response) - - const res = await ipfs.swarm.peers() - - expect(res).to.be.a('array') - expect(res.length).to.equal(1) - expect(res[0].error).to.not.exist() - expect(res[0].addr.toString()).to.equal('/ip4/73.109.217.59/tcp/49311/ipfs/QmWjxEGC7BthJrCf7QTModrcsRweHbupdPTY4oGMVoDZXm') - expect(res[0].peer.toB58String()).to.equal('QmWjxEGC7BthJrCf7QTModrcsRweHbupdPTY4oGMVoDZXm') - expect(scope.isDone()).to.equal(true) - }) - it('handles an ip6 quic peer', async () => { const response = { Peers: [{ Addr: '/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/udp/4001/quic', Peer: 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC', Latency: '', Muxer: '', Streams: null }] } diff --git a/test/ping.spec.js b/test/ping.spec.js index 46c58c890..10c131b75 100644 --- a/test/ping.spec.js +++ b/test/ping.spec.js @@ -6,7 +6,6 @@ const pull = require('pull-stream/pull') const collect = require('pull-stream/sinks/collect') const ipfsClient = 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 @@ -58,23 +57,20 @@ describe('.ping', function () { } }) - it('.ping with default n', async () => { + it('.ping with default count', async () => { const res = await ipfs.ping(otherId) - expect(res).to.be.an('array') - expect(res.filter(isPong)).to.have.lengthOf(1) + expect(res.filter(isPong)).to.have.lengthOf(10) res.forEach(packet => { 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')) expect(resultMsg).to.exist() }) it('.ping with count = 2', async () => { const res = await ipfs.ping(otherId, { count: 2 }) - expect(res).to.be.an('array') expect(res.filter(isPong)).to.have.lengthOf(2) res.forEach(packet => { @@ -85,44 +81,13 @@ describe('.ping', function () { expect(resultMsg).to.exist() }) - it('.ping with n = 2', async () => { - const res = await ipfs.ping(otherId, { n: 2 }) - - expect(res).to.be.an('array') - 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') - }) - const resultMsg = res.find(packet => packet.text.includes('Average latency')) - expect(resultMsg).to.exist() - }) - - it('.ping fails with count & n', async function () { - this.timeout(20 * 1000) - - await expect(ipfs.ping(otherId, { count: 2, n: 2 })).to.be.rejected() - }) - - it('.ping with Promises', async () => { - const res = await ipfs.ping(otherId) - expect(res).to.be.an('array') - 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') - }) - const resultMsg = res.find(packet => packet.text.includes('Average latency')) - expect(resultMsg).to.exist() - }) - it('.pingPullStream', (done) => { pull( - ipfs.pingPullStream(otherId), + ipfs.pingPullStream(otherId, { count: 2 }), collect((err, data) => { expect(err).to.not.exist() expect(data).to.be.an('array') - expect(data.filter(isPong)).to.have.lengthOf(1) + expect(data.filter(isPong)).to.have.lengthOf(2) data.forEach(packet => { expect(packet).to.have.keys('success', 'time', 'text') expect(packet.time).to.be.a('number') @@ -136,7 +101,7 @@ describe('.ping', function () { it('.pingReadableStream', (done) => { let packetNum = 0 - ipfs.pingReadableStream(otherId) + ipfs.pingReadableStream(otherId, { count: 2 }) .on('data', data => { expect(data).to.be.an('object') expect(data).to.have.keys('success', 'time', 'text') @@ -146,15 +111,8 @@ describe('.ping', function () { expect(err).not.to.exist() }) .on('end', () => { - expect(packetNum).to.equal(1) + expect(packetNum).to.equal(2) 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/sub-modules.spec.js b/test/sub-modules.spec.js index 62d05ce8e..ee8f6d93b 100644 --- a/test/sub-modules.spec.js +++ b/test/sub-modules.spec.js @@ -2,14 +2,10 @@ 'use strict' const { expect } = require('interface-ipfs-core/src/utils/mocha') -const defaultConfig = require('../src/utils/default-config.js') -const config = defaultConfig() -config.host = 'test' -config.port = '1111' describe('submodules', () => { it('bitswap', () => { - const bitswap = require('../src/bitswap')(config) + const bitswap = require('../src/bitswap')() expect(bitswap.wantlist).to.be.a('function') expect(bitswap.stat).to.be.a('function') @@ -17,7 +13,7 @@ describe('submodules', () => { }) it('block', () => { - const block = require('../src/block')(config) + const block = require('../src/block')() expect(block.get).to.be.a('function') expect(block.stat).to.be.a('function') @@ -25,7 +21,7 @@ describe('submodules', () => { }) it('bootstrap', () => { - const bootstrap = require('../src/bootstrap')(config) + const bootstrap = require('../src/bootstrap')() expect(bootstrap.add).to.be.a('function') expect(bootstrap.rm).to.be.a('function') @@ -33,7 +29,7 @@ describe('submodules', () => { }) it('config', () => { - const cfg = require('../src/config')(config) + const cfg = require('../src/config')() expect(cfg.get).to.be.a('function') expect(cfg.set).to.be.a('function') @@ -44,7 +40,7 @@ describe('submodules', () => { }) it('dht', () => { - const dht = require('../src/dht')(config) + const dht = require('../src/dht')() expect(dht.get).to.be.a('function') expect(dht.put).to.be.a('function') @@ -55,21 +51,21 @@ describe('submodules', () => { }) it('id', () => { - const id = require('../src/id')(config) + const id = require('../src/id')() expect(id).to.be.a('function') }) it('version', () => { - const version = require('../src/version')(config) + const version = require('../src/version')() expect(version).to.be.a('function') }) it('ping', () => { - const ping = require('../src/ping')(config) - const pingPullStream = require('../src/ping-pull-stream')(config) - const pingReadableStream = require('../src/ping-readable-stream')(config) + const ping = require('../src')().ping + const pingPullStream = require('../src')().pingPullStream + const pingReadableStream = require('../src')().pingReadableStream expect(ping).to.be.a('function') expect(pingPullStream).to.be.a('function') @@ -77,7 +73,7 @@ describe('submodules', () => { }) it('log', () => { - const log = require('../src/log')(config) + const log = require('../src/log')() expect(log.ls).to.be.a('function') expect(log.tail).to.be.a('function') @@ -85,21 +81,21 @@ describe('submodules', () => { }) it('key', () => { - const key = require('../src/key')(config) + const key = require('../src/key')() expect(key.gen).to.be.a('function') expect(key.list).to.be.a('function') }) it('name', () => { - const name = require('../src/name')(config) + const name = require('../src/name')() expect(name.publish).to.be.a('function') expect(name.resolve).to.be.a('function') }) it('pin', () => { - const pin = require('../src/pin')(config) + const pin = require('../src/pin')() expect(pin.add).to.be.a('function') expect(pin.rm).to.be.a('function') @@ -107,14 +103,14 @@ describe('submodules', () => { }) it('repo', () => { - const repo = require('../src/repo')(config) + const repo = require('../src/repo')() expect(repo.gc).to.be.a('function') expect(repo.stat).to.be.a('function') }) it('stats', () => { - const stats = require('../src/stats')(config) + const stats = require('../src/stats')() expect(stats.bitswap).to.be.a('function') expect(stats.bw).to.be.a('function') @@ -122,7 +118,7 @@ describe('submodules', () => { }) it('swarm', () => { - const swarm = require('../src/swarm')(config) + const swarm = require('../src/swarm')() expect(swarm.peers).to.be.a('function') expect(swarm.connect).to.be.a('function') @@ -132,7 +128,7 @@ describe('submodules', () => { }) it('diag', () => { - const diag = require('../src/diag')(config) + const diag = require('../src/diag')() expect(diag.net).to.be.a('function') expect(diag.sys).to.be.a('function') @@ -140,7 +136,7 @@ describe('submodules', () => { }) it('object', () => { - const object = require('../src/object')(config) + const object = require('../src/object')() expect(object.get).to.be.a('function') expect(object.put).to.be.a('function') @@ -155,7 +151,7 @@ describe('submodules', () => { }) it('pubsub', () => { - const pubsub = require('../src/pubsub')(config) + const pubsub = require('../src/pubsub')() expect(pubsub.subscribe).to.be.a('function') expect(pubsub.unsubscribe).to.be.a('function') @@ -165,7 +161,7 @@ describe('submodules', () => { }) it('files regular API', () => { - const filesRegular = require('../src')(config) + const filesRegular = require('../src')() expect(filesRegular.add).to.be.a('function') expect(filesRegular.addReadableStream).to.be.a('function') @@ -191,7 +187,7 @@ describe('submodules', () => { }) it('files MFS API', () => { - const files = require('../src/files')(config) + const files = require('../src/files')() expect(files.cp).to.be.a('function') expect(files.ls).to.be.a('function') @@ -204,13 +200,13 @@ describe('submodules', () => { }) it('commands', () => { - const commands = require('../src/commands')(config) + const commands = require('../src/commands')() expect(commands).to.be.a('function') }) it('mount', () => { - const mount = require('../src/mount')(config) + const mount = require('../src/mount')() expect(mount).to.be.a('function') })