From 41ea529316907bb16568be9a334c183e2cd37b53 Mon Sep 17 00:00:00 2001 From: Hugo Dias Date: Wed, 11 Mar 2020 19:47:10 +0000 Subject: [PATCH] feat: remove ky from http-client and utils (#2810) - we now use a simpler http lib - bundle size reduced - some tests are now more stable - search params handling is cleaner closes #2801 --- .aegir.js | 2 +- examples/files-api/files-api.js | 2 +- examples/name-api/index.js | 1 + package.json | 6 +- src/add/form-data.browser.js | 23 +++-- src/add/form-data.js | 8 -- src/add/index.js | 57 +++++-------- src/bitswap/stat.js | 33 ++++--- src/bitswap/unwant.js | 23 ++--- src/bitswap/wantlist.js | 23 ++--- src/block/get.js | 18 ++-- src/block/put.js | 23 ++--- src/block/rm.js | 28 +++--- src/block/stat.js | 22 ++--- src/bootstrap/add.js | 19 ++--- src/bootstrap/list.js | 15 ++-- src/bootstrap/rm.js | 19 ++--- src/cat.js | 33 +++---- src/commands.js | 18 ++-- src/config/get.js | 17 ++-- src/config/profiles/apply.js | 19 ++--- src/config/profiles/list.js | 19 ++--- src/config/replace.js | 17 ++-- src/config/set.js | 23 +++-- src/dag/get.js | 46 +++++----- src/dag/put.js | 30 +++---- src/dag/resolve.js | 22 ++--- src/dht/find-peer.js | 45 ++++------ src/dht/find-provs.js | 22 ++--- src/dht/get.js | 19 ++--- src/dht/provide.js | 19 ++--- src/dht/put.js | 27 ++---- src/dht/query.js | 22 ++--- src/diag/cmds.js | 19 ++--- src/diag/net.js | 13 ++- src/diag/sys.js | 14 ++- src/dns.js | 21 ++--- src/files/chmod.js | 27 +++--- src/files/cp.js | 17 ++-- src/files/flush.js | 23 +++-- src/files/ls.js | 22 ++--- src/files/mkdir.js | 31 +++---- src/files/mv.js | 18 ++-- src/files/read.js | 19 ++--- src/files/rm.js | 22 ++--- src/files/stat.js | 26 +++--- src/files/touch.js | 20 ++--- src/files/utils.js | 1 + src/files/write.js | 30 ++----- src/get-endpoint-config.js | 20 +++-- src/get.js | 36 ++------ src/id.js | 16 ++-- src/index.js | 77 +++++++++-------- src/key/export.js | 23 +++-- src/key/gen.js | 24 ++---- src/key/import.js | 22 +++-- src/key/list.js | 16 ++-- src/key/rename.js | 18 ++-- src/key/rm.js | 18 ++-- src/lib/buffer-to-form-data.js | 11 +-- src/lib/configure.js | 102 +++------------------- src/lib/core.js | 133 +++++++++++++++++++++++++++++ src/lib/error-handler.js | 49 ----------- src/log/level.js | 19 ++--- src/log/ls.js | 14 ++- src/log/tail.js | 15 ++-- src/ls.js | 21 ++--- src/mount.js | 21 ++--- src/name/publish.js | 23 ++--- src/name/pubsub/cancel.js | 17 ++-- src/name/pubsub/state.js | 15 ++-- src/name/pubsub/subs.js | 17 ++-- src/name/resolve.js | 21 ++--- src/object/data.js | 14 ++- src/object/get.js | 18 ++-- src/object/links.js | 16 ++-- src/object/new.js | 19 ++--- src/object/patch/add-link.js | 13 ++- src/object/patch/append-data.js | 15 ++-- src/object/patch/rm-link.js | 15 ++-- src/object/patch/set-data.js | 15 ++-- src/object/put.js | 22 ++--- src/object/stat.js | 13 ++- src/pin/add.js | 13 ++- src/pin/ls.js | 32 +++---- src/pin/rm.js | 14 ++- src/ping.js | 24 ++---- src/pubsub/ls.js | 11 +-- src/pubsub/peers.js | 15 ++-- src/pubsub/publish.js | 16 ++-- src/pubsub/subscribe.js | 22 ++--- src/pubsub/subscription-tracker.js | 2 + src/pubsub/unsubscribe.js | 5 +- src/refs/index.js | 68 +++++---------- src/refs/local.js | 19 ++--- src/repo/gc.js | 30 +++---- src/repo/stat.js | 24 ++---- src/repo/version.js | 16 ++-- src/resolve.js | 25 ++---- src/stats/bw.js | 37 +++----- src/stop.js | 13 ++- src/swarm/addrs.js | 11 +-- src/swarm/connect.js | 12 ++- src/swarm/disconnect.js | 12 ++- src/swarm/localAddrs.js | 16 ++-- src/swarm/peers.js | 19 ++--- src/update.js | 13 ++- src/version.js | 13 ++- test/constructor.spec.js | 28 +++--- test/dag.spec.js | 1 + test/endpoint-config.spec.js | 4 +- test/files-mfs.spec.js | 4 +- test/fixtures/test-folder/add | 1 + test/get.spec.js | 1 + test/interface.spec.js | 33 ++++++- test/lib.configure.spec.js | 80 ----------------- test/lib.error-handler.spec.js | 10 +-- test/log.spec.js | 1 + test/request-api.spec.js | 1 + 119 files changed, 1040 insertions(+), 1557 deletions(-) create mode 100644 src/lib/core.js delete mode 100644 src/lib/error-handler.js delete mode 100644 test/lib.configure.spec.js diff --git a/.aegir.js b/.aegir.js index 10be576e8..cbe19e93b 100644 --- a/.aegir.js +++ b/.aegir.js @@ -14,7 +14,7 @@ let echoServer const webpack = require('webpack') module.exports = { - bundlesize: { maxSize: '94kB' }, + bundlesize: { maxSize: '89kB' }, webpack: { resolve: { mainFields: ['browser', 'main'] diff --git a/examples/files-api/files-api.js b/examples/files-api/files-api.js index 308c3fc9e..06bf6bf4b 100644 --- a/examples/files-api/files-api.js +++ b/examples/files-api/files-api.js @@ -1,6 +1,6 @@ /* eslint-disable no-console */ 'use strict' - +const { Buffer } = require('buffer') // Run `ipfs daemon` in your terminal to start the IPFS daemon // Look for `API server listening on /ip4/127.0.0.1/tcp/5001` const ipfs = require('../../src')('/ip4/127.0.0.1/tcp/5001') diff --git a/examples/name-api/index.js b/examples/name-api/index.js index b65c43fd3..10d7758b4 100644 --- a/examples/name-api/index.js +++ b/examples/name-api/index.js @@ -1,5 +1,6 @@ /* eslint-disable no-console */ 'use strict' +const { Buffer } = require('buffer') const ipfsHttp = require('ipfs-http-client') const ipfs = ipfsHttp('/ip4/127.0.0.1/tcp/5001') diff --git a/package.json b/package.json index 850d29576..5343144cf 100644 --- a/package.json +++ b/package.json @@ -51,23 +51,21 @@ "ipld-dag-cbor": "^0.15.1", "ipld-dag-pb": "^0.18.2", "ipld-raw": "^4.0.1", + "iso-url": "^0.4.6", "it-tar": "^1.2.1", "it-to-stream": "^0.1.1", - "iterable-ndjson": "^1.1.0", - "ky": "^0.15.0", - "ky-universal": "^0.3.0", "merge-options": "^2.0.0", "multiaddr": "^7.2.1", "multiaddr-to-uri": "^5.1.0", "multibase": "^0.6.0", "multicodec": "^1.0.0", "multihashes": "^0.4.14", + "node-fetch": "^2.6.0", "parse-duration": "^0.1.2", "stream-to-it": "^0.2.0" }, "devDependencies": { "aegir": "^21.3.0", - "async": "^3.1.0", "browser-process-platform": "^0.1.1", "cross-env": "^7.0.0", "go-ipfs-dep": "0.4.23-3", diff --git a/src/add/form-data.browser.js b/src/add/form-data.browser.js index 484f67c6c..2b26f7abe 100644 --- a/src/add/form-data.browser.js +++ b/src/add/form-data.browser.js @@ -10,6 +10,7 @@ exports.toFormData = async input => { let i = 0 for await (const file of files) { + // TODO FormData.append doesnt have a 4th arg const headers = {} if (file.mtime !== undefined && file.mtime !== null) { @@ -34,13 +35,23 @@ exports.toFormData = async input => { bufs.push(chunk) } - formData.append(`file-${i}`, new Blob(bufs, { type: 'application/octet-stream' }), encodeURIComponent(file.path), { - header: headers - }) + formData.append( + `file-${i}`, + new Blob(bufs, { type: 'application/octet-stream' }), + encodeURIComponent(file.path) + // { + // header: headers + // } + ) } else { - formData.append(`dir-${i}`, new Blob([], { type: 'application/x-directory' }), encodeURIComponent(file.path), { - header: headers - }) + formData.append( + `dir-${i}`, + new Blob([], { type: 'application/x-directory' }), + encodeURIComponent(file.path) + // { + // header: headers + // } + ) } i++ diff --git a/src/add/form-data.js b/src/add/form-data.js index 1ce5050da..80411c3c6 100644 --- a/src/add/form-data.js +++ b/src/add/form-data.js @@ -4,7 +4,6 @@ const FormData = require('form-data') const { Buffer } = require('buffer') const toStream = require('it-to-stream') const normaliseInput = require('ipfs-utils/src/files/normalise-input') -const { isElectronRenderer } = require('ipfs-utils/src/env') const mtimeToObject = require('../lib/mtime-to-object') exports.toFormData = async input => { @@ -59,10 +58,3 @@ exports.toFormData = async input => { return formData } - -// TODO remove this when upstream fix for ky-universal is merged -// https://github.com/sindresorhus/ky-universal/issues/9 -// also this should only be necessary when nodeIntegration is false in electron renderer -if (isElectronRenderer) { - exports.toFormData = require('./form-data.browser').toFormData -} diff --git a/src/add/index.js b/src/add/index.js index cd162c2f9..94e3fd6dc 100644 --- a/src/add/index.js +++ b/src/add/index.js @@ -1,51 +1,36 @@ 'use strict' -const ndjson = require('iterable-ndjson') const CID = require('cids') -const configure = require('../lib/configure') -const toIterable = require('stream-to-it/source') +const merge = require('merge-options') const { toFormData } = require('./form-data') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async function * add (input, options) { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - - searchParams.set('stream-channels', true) - if (options.chunker) searchParams.set('chunker', options.chunker) - if (options.cidVersion) searchParams.set('cid-version', options.cidVersion) - if (options.cidBase) searchParams.set('cid-base', options.cidBase) - if (options.enableShardingExperiment != null) searchParams.set('enable-sharding-experiment', options.enableShardingExperiment) - if (options.hashAlg) searchParams.set('hash', options.hashAlg) - if (options.onlyHash != null) searchParams.set('only-hash', options.onlyHash) - if (options.pin != null) searchParams.set('pin', options.pin) - if (options.progress) searchParams.set('progress', true) - if (options.quiet != null) searchParams.set('quiet', options.quiet) - if (options.quieter != null) searchParams.set('quieter', options.quieter) - if (options.rawLeaves != null) searchParams.set('raw-leaves', options.rawLeaves) - if (options.shardSplitThreshold) searchParams.set('shard-split-threshold', options.shardSplitThreshold) - if (options.silent) searchParams.set('silent', options.silent) - if (options.trickle != null) searchParams.set('trickle', options.trickle) - if (options.wrapWithDirectory != null) searchParams.set('wrap-with-directory', options.wrapWithDirectory) - if (options.preload != null) searchParams.set('preload', options.preload) - if (options.fileImportConcurrency != null) searchParams.set('file-import-concurrency', options.fileImportConcurrency) - if (options.blockWriteConcurrency != null) searchParams.set('block-write-concurrency', options.blockWriteConcurrency) +module.exports = configure((api) => { + return async function * add (input, options = {}) { + const progressFn = options.progress + options = merge( + options, + { + 'stream-channels': true, + progress: Boolean(progressFn), + hash: options.hashAlg // TODO fix this either is hash or hashAlg + } + ) - const res = await ky.post('add', { + const res = await api.ndjson('add', { + method: 'POST', + searchParams: options, + body: await toFormData(input), timeout: options.timeout, - signal: options.signal, - headers: options.headers, - searchParams, - body: await toFormData(input) + signal: options.signal }) - for await (let file of ndjson(toIterable(res.body))) { + for await (let file of res) { file = toCamel(file) - if (options.progress && file.bytes) { - options.progress(file.bytes) + if (progressFn && file.bytes) { + progressFn(file.bytes) } else { yield toCoreInterface(file) } diff --git a/src/bitswap/stat.js b/src/bitswap/stat.js index 36101a1f4..13c82816d 100644 --- a/src/bitswap/stat.js +++ b/src/bitswap/stat.js @@ -1,21 +1,18 @@ 'use strict' -const configure = require('../lib/configure') -const Big = require('bignumber.js') +const { BigNumber } = require('bignumber.js') const CID = require('cids') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (options) => { - options = options || {} - - const res = await ky.post('bitswap/stat', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('bitswap/stat', { + searchParams: options, timeout: options.timeout, - signal: options.signal, - headers: options.headers, - searchParams: options.searchParams - }).json() + signal: options.signal + }) - return toCoreInterface(res) + return toCoreInterface(await res.json()) } }) @@ -24,11 +21,11 @@ function toCoreInterface (res) { provideBufLen: res.ProvideBufLen, wantlist: (res.Wantlist || []).map(k => new CID(k['/'])), 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) + blocksReceived: new BigNumber(res.BlocksReceived), + dataReceived: new BigNumber(res.DataReceived), + blocksSent: new BigNumber(res.BlocksSent), + dataSent: new BigNumber(res.DataSent), + dupBlksReceived: new BigNumber(res.DupBlksReceived), + dupDataReceived: new BigNumber(res.DupDataReceived) } } diff --git a/src/bitswap/unwant.js b/src/bitswap/unwant.js index a66653d69..50b2c2f54 100644 --- a/src/bitswap/unwant.js +++ b/src/bitswap/unwant.js @@ -3,25 +3,16 @@ const CID = require('cids') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (cid, options) => { - options = options || {} +module.exports = configure(api => { + return async (cid, options = {}) => { + options.arg = typeof cid === 'string' ? cid : new CID(cid).toString() - const searchParams = new URLSearchParams(options.searchParams) - - if (typeof cid === 'string') { - searchParams.set('arg', cid) - } else { - searchParams.set('arg', new CID(cid).toString()) - } - - const res = await ky.post('bitswap/unwant', { + const res = await api.post('bitswap/unwant', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + }) - return res + return res.json() } }) diff --git a/src/bitswap/wantlist.js b/src/bitswap/wantlist.js index d917d6747..62763d062 100644 --- a/src/bitswap/wantlist.js +++ b/src/bitswap/wantlist.js @@ -3,26 +3,17 @@ const CID = require('cids') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (peerId, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - - if (peerId) { - if (typeof peerId === 'string') { - searchParams.set('peer', peerId) - } else { - searchParams.set('peer', new CID(peerId).toString()) - } +module.exports = configure(api => { + return async (peer, options = {}) => { + if (peer) { + options.peer = typeof peer === 'string' ? peer : new CID(peer).toString() } - const res = await ky.post('bitswap/wantlist', { + const res = await (await api.post('bitswap/wantlist', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + })).json() return (res.Keys || []).map(k => new CID(k['/'])) } diff --git a/src/block/get.js b/src/block/get.js index b53b38f64..3a2e36109 100644 --- a/src/block/get.js +++ b/src/block/get.js @@ -5,21 +5,17 @@ const CID = require('cids') const { Buffer } = require('buffer') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (cid, options) => { +module.exports = configure(api => { + return async (cid, options = {}) => { cid = new CID(cid) - options = options || {} + options.arg = cid.toString() - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('arg', `${cid}`) - - const data = await ky.post('block/get', { + const rsp = await api.post('block/get', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).arrayBuffer() + searchParams: options + }) - return new Block(Buffer.from(data), cid) + return new Block(Buffer.from(await rsp.arrayBuffer()), cid) } }) diff --git a/src/block/put.js b/src/block/put.js index 39e3b6f1a..8adcd2946 100644 --- a/src/block/put.js +++ b/src/block/put.js @@ -3,13 +3,11 @@ const Block = require('ipfs-block') const CID = require('cids') const multihash = require('multihashes') -const configure = require('../lib/configure') const toFormData = require('../lib/buffer-to-form-data') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - async function put (data, options) { - options = options || {} - +module.exports = configure(api => { + async function put (data, options = {}) { if (Block.isBlock(data)) { const { name, length } = multihash.decode(data.cid.multihash) options = { @@ -33,22 +31,15 @@ module.exports = configure(({ ky }) => { delete options.cid } - const searchParams = new URLSearchParams(options.searchParams) - if (options.format) searchParams.set('format', options.format) - if (options.mhtype) searchParams.set('mhtype', options.mhtype) - if (options.mhlen) searchParams.set('mhlen', options.mhlen) - if (options.pin != null) searchParams.set('pin', options.pin) - if (options.version != null) searchParams.set('version', options.version) - let res try { - res = await ky.post('block/put', { + const response = await api.post('block/put', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams, + searchParams: options, body: toFormData(data) - }).json() + }) + res = await response.json() } catch (err) { // Retry with "protobuf"/"cbor" format for go-ipfs // TODO: remove when https://github.com/ipfs/go-cid/issues/75 resolved diff --git a/src/block/rm.js b/src/block/rm.js index f8fc8c103..8e0a1d49d 100644 --- a/src/block/rm.js +++ b/src/block/rm.js @@ -1,35 +1,35 @@ 'use strict' const CID = require('cids') -const ndjson = require('iterable-ndjson') +const merge = require('merge-options') const configure = require('../lib/configure') -const toIterable = require('stream-to-it/source') - -module.exports = configure(({ ky }) => { - return async function * rm (cid, options) { - options = options || {} +module.exports = configure(api => { + return async function * rm (cid, options = {}) { if (!Array.isArray(cid)) { cid = [cid] } - const searchParams = new URLSearchParams() - searchParams.set('stream-channels', true) - searchParams.set('force', options.force || false) - searchParams.set('quiet', options.quiet || false) + options = merge( + options, + { + 'stream-channels': true + } + ) + + const searchParams = new URLSearchParams(options) cid.forEach(cid => { searchParams.append('arg', new CID(cid).toString()) }) - const res = await ky.post('block/rm', { + const res = await api.ndjson('block/rm', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams + searchParams: searchParams }) - for await (const removed of ndjson(toIterable(res.body))) { + for await (const removed of res) { yield toCoreInterface(removed) } } diff --git a/src/block/stat.js b/src/block/stat.js index 24b4256fc..1a4bb3f85 100644 --- a/src/block/stat.js +++ b/src/block/stat.js @@ -1,26 +1,18 @@ 'use strict' const CID = require('cids') -const { Buffer } = require('buffer') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (cid, options) => { - options = options || {} +module.exports = configure(api => { + return async (cid, options = {}) => { + options.arg = (new CID(cid)).toString() - if (Buffer.isBuffer(cid)) { - cid = new CID(cid) - } - - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('arg', `${cid}`) - - const res = await ky.post('block/stat', { + const response = await api.post('block/stat', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + }) + const res = await response.json() return { cid: new CID(res.Key), size: res.Size } } diff --git a/src/bootstrap/add.js b/src/bootstrap/add.js index 29dd46cc3..f48120578 100644 --- a/src/bootstrap/add.js +++ b/src/bootstrap/add.js @@ -3,26 +3,21 @@ const Multiaddr = require('multiaddr') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (addr, options) => { +module.exports = configure(api => { + return async (addr, options = {}) => { if (addr && typeof addr === 'object' && !Multiaddr.isMultiaddr(addr)) { options = addr addr = null } - options = options || {} + options.arg = addr - const searchParams = new URLSearchParams(options.searchParams) - if (addr) searchParams.set('arg', `${addr}`) - if (options.default != null) searchParams.set('default', options.default) - - const res = await ky.post('bootstrap/add', { + const res = await api.post('bootstrap/add', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + }) - return res + return res.json() } }) diff --git a/src/bootstrap/list.js b/src/bootstrap/list.js index 2a6bbef4b..4831964fd 100644 --- a/src/bootstrap/list.js +++ b/src/bootstrap/list.js @@ -2,17 +2,14 @@ const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (options) => { - options = options || {} - - const res = await ky.post('bootstrap/list', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('bootstrap/list', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams: options.searchParams - }).json() + searchParams: options + }) - return res + return res.json() } }) diff --git a/src/bootstrap/rm.js b/src/bootstrap/rm.js index 4c2597d1d..46879fa67 100644 --- a/src/bootstrap/rm.js +++ b/src/bootstrap/rm.js @@ -3,26 +3,21 @@ const Multiaddr = require('multiaddr') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (addr, options) => { +module.exports = configure(api => { + return async (addr, options = {}) => { if (addr && typeof addr === 'object' && !Multiaddr.isMultiaddr(addr)) { options = addr addr = null } - options = options || {} + options.arg = addr - const searchParams = new URLSearchParams(options.searchParams) - if (addr) searchParams.set('arg', `${addr}`) - if (options.all != null) searchParams.set('all', options.all) - - const res = await ky.post('bootstrap/rm', { + const res = await api.post('bootstrap/rm', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + }) - return res + return res.json() } }) diff --git a/src/cat.js b/src/cat.js index 3d4971a1c..bb73c63de 100644 --- a/src/cat.js +++ b/src/cat.js @@ -2,32 +2,25 @@ const CID = require('cids') const { Buffer } = require('buffer') +const merge = require('merge-options') const configure = require('./lib/configure') -const toIterable = require('stream-to-it/source') -module.exports = configure(({ ky }) => { - return async function * cat (path, options) { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - - if (typeof path === 'string') { - searchParams.set('arg', path) - } else { - searchParams.set('arg', new CID(path).toString()) - } - - if (options.offset) searchParams.set('offset', options.offset) - if (options.length) searchParams.set('length', options.length) - - const res = await ky.post('cat', { +module.exports = configure(api => { + return async function * cat (path, options = {}) { + options = merge( + options, + { + arg: typeof path === 'string' ? path : new CID(path).toString() + } + ) + const res = await api.iterator('cat', { + method: 'POST', timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams + searchParams: options }) - for await (const chunk of toIterable(res.body)) { + for await (const chunk of res) { yield Buffer.from(chunk) } } diff --git a/src/commands.js b/src/commands.js index 4f8463fe9..55663b3e2 100644 --- a/src/commands.js +++ b/src/commands.js @@ -2,18 +2,14 @@ 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', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('commands', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + }) + + return res.json() } }) diff --git a/src/config/get.js b/src/config/get.js index e4a7b5c2d..98ef36158 100644 --- a/src/config/get.js +++ b/src/config/get.js @@ -2,25 +2,20 @@ const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (key, options) => { +module.exports = configure(api => { + return async (key, options = {}) => { if (key && typeof key === 'object') { options = key key = null } - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - if (key) searchParams.set('arg', key) - const url = key ? 'config' : 'config/show' - const data = await ky.post(url, { + const rsp = await api.post(url, { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: { arg: key } + }) + const data = await rsp.json() return key ? data.Value : data } diff --git a/src/config/profiles/apply.js b/src/config/profiles/apply.js index deac884fe..1ee02f737 100644 --- a/src/config/profiles/apply.js +++ b/src/config/profiles/apply.js @@ -2,20 +2,15 @@ const configure = require('../../lib/configure') -module.exports = configure(({ ky }) => { - return async (profile, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('arg', profile) - if (options.dryRun != null) searchParams.set('dry-run', options.dryRun) - - const res = await ky.post('config/profile/apply', { +module.exports = configure(api => { + return async (profile, options = {}) => { + options.arg = profile + const response = await api.post('config/profile/apply', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + }) + const res = await response.json() return { original: res.OldCfg, updated: res.NewCfg diff --git a/src/config/profiles/list.js b/src/config/profiles/list.js index 0261070bf..3f4774d18 100644 --- a/src/config/profiles/list.js +++ b/src/config/profiles/list.js @@ -1,19 +1,18 @@ 'use strict' -const configure = require('../../lib/configure') const toCamel = require('../../lib/object-to-camel') +const configure = require('../../lib/configure') -module.exports = configure(({ ky }) => { - return async (options) => { - options = options || {} - - const res = await ky.post('config/profile/list', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('config/profile/list', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams: options.searchParams - }).json() + searchParams: options + }) + + const data = await res.json() - return res.map(profile => toCamel(profile)) + return data.map(profile => toCamel(profile)) } }) diff --git a/src/config/replace.js b/src/config/replace.js index ccca80beb..55d86fc90 100644 --- a/src/config/replace.js +++ b/src/config/replace.js @@ -1,21 +1,18 @@ 'use strict' const { Buffer } = require('buffer') -const configure = require('../lib/configure') const toFormData = require('../lib/buffer-to-form-data') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (config, options) => { - options = options || {} - - const res = await ky.post('config/replace', { +module.exports = configure(api => { + return async (config, options = {}) => { + const res = await api.post('config/replace', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams: options.searchParams, + searchParams: options, body: toFormData(Buffer.from(JSON.stringify(config))) - }).text() + }) - return res + return res.text() } }) diff --git a/src/config/set.js b/src/config/set.js index f9e3309f2..3a30c0d56 100644 --- a/src/config/set.js +++ b/src/config/set.js @@ -1,36 +1,33 @@ 'use strict' -const configure = require('../lib/configure') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (key, value, options) => { - options = options || {} - +module.exports = configure(api => { + return async (key, value, options = {}) => { if (typeof key !== 'string') { throw new Error('Invalid key type') } - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) if (typeof value === 'boolean') { - searchParams.set('bool', true) + searchParams.set('bool', 'true') value = value.toString() } else if (typeof value !== 'string') { - searchParams.set('json', true) + searchParams.set('json', 'true') value = JSON.stringify(value) } - searchParams.set('arg', key) + searchParams.append('arg', key) searchParams.append('arg', value) - const res = await ky.post('config', { + const res = await api.post('config', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + }) - return toCamel(res) + return toCamel(await res.json()) } }) diff --git a/src/dag/get.js b/src/dag/get.js index 93847b2e6..8a82385d6 100644 --- a/src/dag/get.js +++ b/src/dag/get.js @@ -11,31 +11,27 @@ const resolvers = { raw: raw.resolver } -module.exports = config => { - const getBlock = require('../block/get')(config) - const dagResolve = require('./resolve')(config) - - return configure(({ ky }) => { - return async (cid, path, options) => { - if (typeof path === 'object') { - options = path - path = null - } - - options = options || {} - - const resolved = await dagResolve(cid, path, options) - const block = await getBlock(resolved.cid, options) - const dagResolver = resolvers[block.cid.codec] +module.exports = configure((api, options) => { + const getBlock = require('../block/get')(options) + const dagResolve = require('./resolve')(options) + + return async (cid, path, options = {}) => { + if (typeof path === 'object') { + options = path + path = null + } - if (!dagResolver) { - throw Object.assign( - new Error(`Missing IPLD format "${block.cid.codec}"`), - { missingMulticodec: cid.codec } - ) - } + const resolved = await dagResolve(cid, path, options) + const block = await getBlock(resolved.cid, options) + const dagResolver = resolvers[block.cid.codec] - return dagResolver.resolve(block.data, resolved.remPath) + if (!dagResolver) { + throw Object.assign( + new Error(`Missing IPLD format "${block.cid.codec}"`), + { missingMulticodec: cid.codec } + ) } - })(config) -} + + return dagResolver.resolve(block.data, resolved.remPath) + } +}) diff --git a/src/dag/put.js b/src/dag/put.js index d26f8ba9e..05707f4f3 100644 --- a/src/dag/put.js +++ b/src/dag/put.js @@ -3,18 +3,11 @@ const dagCBOR = require('ipld-dag-cbor') const CID = require('cids') const multihash = require('multihashes') -const configure = require('../lib/configure') const toFormData = require('../lib/buffer-to-form-data') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (dagNode, options) => { - options = options || {} - - if (options.hash) { - options.hashAlg = options.hash - delete options.hash - } - +module.exports = configure(api => { + return async (dagNode, options = {}) => { if (options.cid && (options.format || options.hashAlg)) { throw new Error('Failed to put DAG node. Provide either `cid` OR `format` and `hashAlg` options') } else if ((options.format && !options.hashAlg) || (!options.format && options.hashAlg)) { @@ -49,20 +42,19 @@ module.exports = configure(({ ky }) => { serialized = dagNode } - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('format', options.format) - searchParams.set('hash', options.hashAlg) - searchParams.set('input-enc', options.inputEnc) - if (options.pin != null) searchParams.set('pin', options.pin) + // TODO normalize hash property name + options.hash = options.hashAlg + options.hashAlg = null + const searchParams = new URLSearchParams(options) - const res = await ky.post('dag/put', { + const rsp = await api.post('dag/put', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams, body: toFormData(serialized) - }).json() + }) + const data = await rsp.json() - return new CID(res.Cid['/']) + return new CID(data.Cid['/']) } }) diff --git a/src/dag/resolve.js b/src/dag/resolve.js index cb7014a41..118010440 100644 --- a/src/dag/resolve.js +++ b/src/dag/resolve.js @@ -3,29 +3,25 @@ const CID = require('cids') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (cid, path, options) => { +module.exports = configure(api => { + return async (cid, path, options = {}) => { if (typeof path === 'object') { options = path path = null } - options = options || {} - - const cidPath = path + options.arg = path ? [cid, path].join(path.startsWith('/') ? '' : '/') : `${cid}` - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('arg', cidPath) - - const res = await ky.post('dag/resolve', { + const res = await api.post('dag/resolve', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + }) + + const data = await res.json() - return { cid: new CID(res.Cid['/']), remPath: res.RemPath } + return { cid: new CID(data.Cid['/']), remPath: data.RemPath } } }) diff --git a/src/dht/find-peer.js b/src/dht/find-peer.js index ef5c6c92a..695a1843c 100644 --- a/src/dht/find-peer.js +++ b/src/dht/find-peer.js @@ -3,44 +3,29 @@ const { Buffer } = require('buffer') const CID = require('cids') const multiaddr = require('multiaddr') -const ndjson = require('iterable-ndjson') const configure = require('../lib/configure') -const toIterable = require('stream-to-it/source') -module.exports = configure(({ ky }) => { - return async function findPeer (peerId, options) { - options = options || {} +module.exports = configure(api => { + return async function findPeer (peerId, options = {}) { + options.arg = `${Buffer.isBuffer(peerId) ? new CID(peerId) : peerId}` - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('arg', `${Buffer.isBuffer(peerId) ? new CID(peerId) : peerId}`) - if (options.verbose != null) searchParams.set('verbose', options.verbose) - - const res = await ky.post('dht/findpeer', { + const res = await api.post('dht/findpeer', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams + searchParams: options }) - for await (const message of ndjson(toIterable(res.body))) { - // 3 = QueryError - // https://github.com/libp2p/go-libp2p-core/blob/6e566d10f4a5447317a66d64c7459954b969bdab/routing/query.go#L18 - // https://github.com/ipfs/go-ipfs/blob/eb11f569b064b960d1aba4b5b8ca155a3bd2cb21/core/commands/dht.go#L388-L389 - if (message.Type === 3) { - throw new Error(message.Extra) - } + const data = await res.json() + + if (data.Type === 3) { + throw new Error(data.Extra) + } - // 2 = FinalPeer - // https://github.com/libp2p/go-libp2p-core/blob/6e566d10f4a5447317a66d64c7459954b969bdab/routing/query.go#L18 - if (message.Type === 2 && message.Responses) { - // There will only be 1: - // https://github.com/ipfs/go-ipfs/blob/eb11f569b064b960d1aba4b5b8ca155a3bd2cb21/core/commands/dht.go#L395-L396 - for (const { ID, Addrs } of message.Responses) { - return { - id: ID, - addrs: (Addrs || []).map(a => multiaddr(a)) - } - } + if (data.Type === 2 && data.Responses) { + const { ID, Addrs } = data.Responses[0] + return { + id: ID, + addrs: (Addrs || []).map(a => multiaddr(a)) } } diff --git a/src/dht/find-provs.js b/src/dht/find-provs.js index e70935dec..9706106ae 100644 --- a/src/dht/find-provs.js +++ b/src/dht/find-provs.js @@ -2,27 +2,19 @@ const CID = require('cids') const multiaddr = require('multiaddr') -const ndjson = require('iterable-ndjson') const configure = require('../lib/configure') -const toIterable = require('stream-to-it/source') -module.exports = configure(({ ky }) => { - return async function * findProvs (cid, options) { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('arg', `${new CID(cid)}`) - if (options.numProviders) searchParams.set('num-providers', options.numProviders) - if (options.verbose != null) searchParams.set('verbose', options.verbose) - - const res = await ky.post('dht/findprovs', { +module.exports = configure(api => { + return async function * findProvs (cid, options = {}) { + options.arg = `${new CID(cid)}` + const res = await api.ndjson('dht/findprovs', { + method: 'POST', timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams + searchParams: options }) - for await (const message of ndjson(toIterable(res.body))) { + for await (const message of res) { // 3 = QueryError // https://github.com/libp2p/go-libp2p-core/blob/6e566d10f4a5447317a66d64c7459954b969bdab/routing/query.go#L18 // https://github.com/libp2p/go-libp2p-kad-dht/blob/master/routing.go#L525-L526 diff --git a/src/dht/get.js b/src/dht/get.js index 4be7b80c2..88a36476f 100644 --- a/src/dht/get.js +++ b/src/dht/get.js @@ -1,29 +1,24 @@ 'use strict' const { Buffer } = require('buffer') -const ndjson = require('iterable-ndjson') -const toIterable = require('stream-to-it/source') const encodeBufferURIComponent = require('../lib/encode-buffer-uri-component') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async function get (key, options) { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - if (options.verbose != null) searchParams.set('verbose', options.verbose) - +module.exports = configure(api => { + return async function get (key, options = {}) { if (!Buffer.isBuffer(key)) { throw new Error('invalid key') } - const res = await ky.post(`dht/get?key=${encodeBufferURIComponent(key)}&${searchParams}`, { + options.key = encodeBufferURIComponent(key) + const res = await api.ndjson('dht/get', { + method: 'POST', timeout: options.timeout, signal: options.signal, - headers: options.headers + searchParams: options }) - for await (const message of ndjson(toIterable(res.body))) { + for await (const message of res) { // 3 = QueryError // https://github.com/libp2p/go-libp2p-core/blob/6e566d10f4a5447317a66d64c7459954b969bdab/routing/query.go#L18 // https://github.com/ipfs/go-ipfs/blob/eb11f569b064b960d1aba4b5b8ca155a3bd2cb21/core/commands/dht.go#L472-L473 diff --git a/src/dht/provide.js b/src/dht/provide.js index cdcae2f84..2e82868a1 100644 --- a/src/dht/provide.js +++ b/src/dht/provide.js @@ -2,29 +2,24 @@ const CID = require('cids') const multiaddr = require('multiaddr') -const ndjson = require('iterable-ndjson') -const configure = require('../lib/configure') -const toIterable = require('stream-to-it/source') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async function * provide (cids, options) { +module.exports = configure(api => { + return async function * provide (cids, options = {}) { cids = Array.isArray(cids) ? cids : [cids] - options = options || {} - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) cids.forEach(cid => searchParams.append('arg', `${new CID(cid)}`)) - if (options.recursive != null) searchParams.set('recursive', options.recursive) - if (options.verbose != null) searchParams.set('verbose', options.verbose) - const res = await ky.post('dht/provide', { + const res = await api.ndjson('dht/provide', { + method: 'POST', timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams }) - for await (let message of ndjson(toIterable(res.body))) { + for await (let message of res) { // 3 = QueryError // https://github.com/libp2p/go-libp2p-core/blob/6e566d10f4a5447317a66d64c7459954b969bdab/routing/query.go#L18 // https://github.com/ipfs/go-ipfs/blob/eb11f569b064b960d1aba4b5b8ca155a3bd2cb21/core/commands/dht.go#L283-L284 diff --git a/src/dht/put.js b/src/dht/put.js index 8dc924f7a..4d4d1d647 100644 --- a/src/dht/put.js +++ b/src/dht/put.js @@ -1,32 +1,23 @@ 'use strict' -const { Buffer } = require('buffer') const CID = require('cids') const multiaddr = require('multiaddr') -const ndjson = require('iterable-ndjson') -const configure = require('../lib/configure') -const toIterable = require('stream-to-it/source') -const encodeBufferURIComponent = require('../lib/encode-buffer-uri-component') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async function * put (key, value, options) { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - if (options.verbose != null) searchParams.set('verbose', options.verbose) - - key = Buffer.isBuffer(key) ? encodeBufferURIComponent(key) : encodeURIComponent(key) - value = Buffer.isBuffer(value) ? encodeBufferURIComponent(value) : encodeURIComponent(value) +module.exports = configure(api => { + return async function * put (key, value, options = {}) { + const searchParams = new URLSearchParams(options) - const url = `dht/put?arg=${key}&arg=${value}&${searchParams}` - const res = await ky.post(url, { + searchParams.append('arg', key) + searchParams.append('arg', value) + const res = await api.ndjson('dht/put', { timeout: options.timeout, signal: options.signal, - headers: options.headers + searchParams }) - for await (let message of ndjson(toIterable(res.body))) { + for await (let message of res) { // 3 = QueryError // https://github.com/libp2p/go-libp2p-core/blob/6e566d10f4a5447317a66d64c7459954b969bdab/routing/query.go#L18 // https://github.com/ipfs/go-ipfs/blob/eb11f569b064b960d1aba4b5b8ca155a3bd2cb21/core/commands/dht.go#L472-L473 diff --git a/src/dht/query.js b/src/dht/query.js index b2b878572..786d62104 100644 --- a/src/dht/query.js +++ b/src/dht/query.js @@ -1,28 +1,20 @@ 'use strict' const CID = require('cids') -const ndjson = require('iterable-ndjson') const multiaddr = require('multiaddr') -const toIterable = require('stream-to-it/source') -const configure = require('../lib/configure') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async function * query (peerId, options) { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('arg', `${Buffer.isBuffer(peerId) ? new CID(peerId) : peerId}`) - if (options.verbose != null) searchParams.set('verbose', options.verbose) - - const res = await ky.post('dht/query', { +module.exports = configure(api => { + return async function * query (peerId, options = {}) { + options.arg = new CID(peerId) + const res = await api.ndjson('dht/query', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams + searchParams: options }) - for await (let message of ndjson(toIterable(res.body))) { + for await (let message of res) { message = toCamel(message) message.id = new CID(message.id) message.responses = (message.responses || []).map(({ ID, Addrs }) => ({ diff --git a/src/diag/cmds.js b/src/diag/cmds.js index 88bb728ef..b5ce4fe1e 100644 --- a/src/diag/cmds.js +++ b/src/diag/cmds.js @@ -1,19 +1,14 @@ 'use strict' - const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return options => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - if (options.verbose != null) searchParams.set('verbose', options.verbose) - - return ky.post('diag/cmds', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('diag/cmds', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + }) + + return res.json() } }) diff --git a/src/diag/net.js b/src/diag/net.js index 71b971ba7..b4cd70635 100644 --- a/src/diag/net.js +++ b/src/diag/net.js @@ -1,16 +1,13 @@ 'use strict' - const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return options => { - options = options || {} - - return ky.post('diag/net', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('diag/net', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams: options.searchParams - }).json() + }) + return res.json() } }) diff --git a/src/diag/sys.js b/src/diag/sys.js index 768d13d4d..5a25699d4 100644 --- a/src/diag/sys.js +++ b/src/diag/sys.js @@ -1,16 +1,14 @@ 'use strict' - const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return options => { - options = options || {} - - return ky.post('diag/sys', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('diag/sys', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams: options.searchParams - }).json() + }) + + return res.json() } }) diff --git a/src/dns.js b/src/dns.js index 5032e3fb5..7e748486f 100644 --- a/src/dns.js +++ b/src/dns.js @@ -2,21 +2,16 @@ const configure = require('./lib/configure') -module.exports = configure(({ ky }) => { - return async (domain, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('arg', domain) - if (options.recursive != null) searchParams.set('recursive', options.recursive) - - const res = await ky.post('dns', { +module.exports = configure(api => { + return async (domain, options = {}) => { + options.arg = domain + const res = await api.post('dns', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + }) + const data = await res.json() - return res.Path + return data.Path } }) diff --git a/src/files/chmod.js b/src/files/chmod.js index 3979d4622..cc1a3f3a4 100644 --- a/src/files/chmod.js +++ b/src/files/chmod.js @@ -1,24 +1,21 @@ 'use strict' -const configure = require('../lib/configure') const modeToString = require('../lib/mode-to-string') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return function chmod (path, mode, options) { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - searchParams.append('arg', path) - searchParams.append('mode', modeToString(mode)) - if (options.flush != null) searchParams.set('flush', options.flush) - if (options.hashAlg) searchParams.set('hash', options.hashAlg) - if (options.parents != null) searchParams.set('parents', options.parents) +module.exports = configure(api => { + return async function chmod (path, mode, options = {}) { + options.arg = path + options.mode = modeToString(mode) + options.hash = options.hashAlg + options.hashAlg = null - return ky.post('files/chmod', { + const res = await api.post('files/chmod', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).text() + searchParams: options + }) + + return res.text() } }) diff --git a/src/files/cp.js b/src/files/cp.js index ce68aa588..571e3dd1b 100644 --- a/src/files/cp.js +++ b/src/files/cp.js @@ -1,25 +1,22 @@ 'use strict' const CID = require('cids') -const configure = require('../lib/configure') const { findSources } = require('./utils') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return (...args) => { +module.exports = configure(api => { + return async (...args) => { const { sources, options } = findSources(args) - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) sources.forEach(src => searchParams.append('arg', CID.isCID(src) ? `/ipfs/${src}` : src)) - if (options.flush != null) searchParams.set('flush', options.flush) if (options.hashAlg) searchParams.set('hash', options.hashAlg) - if (options.parents != null) searchParams.set('parents', options.parents) - if (options.shardSplitThreshold != null) searchParams.set('shardSplitThreshold', options.shardSplitThreshold) - return ky.post('files/cp', { + const res = await api.post('files/cp', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).text() + }) + return res.text() } }) diff --git a/src/files/flush.js b/src/files/flush.js index 34e725814..cc9eb1ec7 100644 --- a/src/files/flush.js +++ b/src/files/flush.js @@ -1,27 +1,24 @@ 'use strict' -const configure = require('../lib/configure') const CID = require('cids') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (path, options) => { +module.exports = configure(api => { + return async (path, options = {}) => { if (typeof path !== 'string') { - options = path + options = path || {} path = '/' } - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('arg', path) + options.arg = path - const res = await ky.post('files/flush', { + const res = await api.post('files/flush', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + }) + const data = await res.json() - return new CID(res.Cid) + return new CID(data.Cid) } }) diff --git a/src/files/ls.js b/src/files/ls.js index f07c65c09..639c46674 100644 --- a/src/files/ls.js +++ b/src/files/ls.js @@ -1,36 +1,32 @@ 'use strict' const CID = require('cids') -const ndjson = require('iterable-ndjson') -const toIterable = require('stream-to-it/source') -const configure = require('../lib/configure') const toCamelWithMetadata = require('../lib/object-to-camel-with-metadata') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async function * ls (path, options) { +module.exports = configure(api => { + return async function * ls (path, options = {}) { if (typeof path !== 'string') { - options = path + options = path || {} path = '/' } - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) searchParams.set('arg', CID.isCID(path) ? `/ipfs/${path}` : path) + // TODO the args below are not in the go-ipfs or interface core searchParams.set('stream', options.stream == null ? true : options.stream) - if (options.cidBase) searchParams.set('cid-base', options.cidBase) searchParams.set('long', options.long == null ? true : options.long) // TODO: remove after go-ipfs 0.5 is released searchParams.set('l', options.long == null ? true : options.long) - const res = await ky.post('files/ls', { + const res = await api.ndjson('files/ls', { + method: 'POST', timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams }) - for await (const result of ndjson(toIterable(res.body))) { + for await (const result of res) { // go-ipfs does not yet support the "stream" option if ('Entries' in result) { for (const entry of result.Entries || []) { diff --git a/src/files/mkdir.js b/src/files/mkdir.js index 7083d4b40..2eaebb795 100644 --- a/src/files/mkdir.js +++ b/src/files/mkdir.js @@ -1,35 +1,28 @@ 'use strict' -const configure = require('../lib/configure') const modeToString = require('../lib/mode-to-string') const mtimeToObject = require('../lib/mtime-to-object') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return (path, options) => { - options = options || {} +module.exports = configure(api => { + return async (path, options = {}) => { const mtime = mtimeToObject(options.mtime) - const searchParams = new URLSearchParams(options.searchParams) - searchParams.append('arg', path) - if (options.cidVersion != null) searchParams.set('cid-version', options.cidVersion) - if (options.flush != null) searchParams.set('flush', options.flush) - if (options.hashAlg) searchParams.set('hash', options.hashAlg) - if (options.parents != null) searchParams.set('parents', options.parents) - if (options.shardSplitThreshold != null) searchParams.set('shardSplitThreshold', options.shardSplitThreshold) + const searchParams = new URLSearchParams(options) + searchParams.set('arg', path) + searchParams.set('mode', modeToString(options.mode)) + searchParams.set('hash', options.hashAlg) + searchParams.set('hashAlg', null) if (mtime) { searchParams.set('mtime', mtime.secs) - - if (mtime.nsecs != null) { - searchParams.set('mtimeNsecs', mtime.nsecs) - } + searchParams.set('mtimeNsecs', mtime.nsecs) } - if (options.mode != null) searchParams.set('mode', modeToString(options.mode)) - return ky.post('files/mkdir', { + const res = await api.post('files/mkdir', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).text() + }) + return res.text() } }) diff --git a/src/files/mv.js b/src/files/mv.js index 5b0efbc89..ce4d8c381 100644 --- a/src/files/mv.js +++ b/src/files/mv.js @@ -1,25 +1,23 @@ 'use strict' const CID = require('cids') -const configure = require('../lib/configure') const { findSources } = require('./utils') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return (...args) => { +module.exports = configure(api => { + return async (...args) => { const { sources, options } = findSources(args) - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) sources.forEach(src => searchParams.append('arg', CID.isCID(src) ? `/ipfs/${src}` : src)) - if (options.flush != null) searchParams.set('flush', options.flush) if (options.hashAlg) searchParams.set('hash', options.hashAlg) - if (options.parents != null) searchParams.set('parents', options.parents) - if (options.shardSplitThreshold != null) searchParams.set('shardSplitThreshold', options.shardSplitThreshold) - return ky.post('files/mv', { + const res = await api.post('files/mv', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).text() + }) + + return res.text() } }) diff --git a/src/files/read.js b/src/files/read.js index 1800609d0..38a51f3f6 100644 --- a/src/files/read.js +++ b/src/files/read.js @@ -1,23 +1,16 @@ 'use strict' const { Buffer } = require('buffer') -const configure = require('../lib/configure') const toIterable = require('stream-to-it/source') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async function * read (path, options) { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - searchParams.append('arg', `${path}`) - if (options.length != null) searchParams.set('length', options.length) - if (options.offset != null) searchParams.set('offset', options.offset) - - const res = await ky.post('files/read', { +module.exports = configure(api => { + return async function * read (path, options = {}) { + options.arg = path + const res = await api.post('files/read', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams + searchParams: options }) for await (const chunk of toIterable(res.body)) { diff --git a/src/files/rm.js b/src/files/rm.js index ebfbd4061..dfa2609fe 100644 --- a/src/files/rm.js +++ b/src/files/rm.js @@ -2,21 +2,15 @@ const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return (path, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - searchParams.append('arg', path) - if (options.recursive != null) searchParams.set('recursive', options.recursive) - if (options.force != null) searchParams.set('force', options.force) - if (options.shardSplitThreshold != null) searchParams.set('shardSplitThreshold', options.shardSplitThreshold) - - return ky.post('files/rm', { +module.exports = configure(api => { + return async (path, options = {}) => { + options.arg = path + const res = await api.post('files/rm', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).text() + searchParams: options + }) + + return res.text() } }) diff --git a/src/files/stat.js b/src/files/stat.js index 0d8c9caa1..cdf7e51e9 100644 --- a/src/files/stat.js +++ b/src/files/stat.js @@ -1,34 +1,28 @@ 'use strict' const CID = require('cids') -const configure = require('../lib/configure') const toCamelWithMetadata = require('../lib/object-to-camel-with-metadata') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (path, options) => { +module.exports = configure(api => { + return async (path, options = {}) => { if (typeof path !== 'string') { - options = path + options = path || {} path = '/' } - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) searchParams.set('arg', path) - if (options.cidBase) searchParams.set('cid-base', options.cidBase) - if (options.hash != null) searchParams.set('hash', options.hash) - if (options.size != null) searchParams.set('size', options.size) - if (options.withLocal != null) searchParams.set('with-local', options.withLocal) - const res = await ky.post('files/stat', { + const res = await api.post('files/stat', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + }) + const data = await res.json() - res.WithLocality = res.WithLocality || false - return toCoreInterface(toCamelWithMetadata(res)) + data.WithLocality = data.WithLocality || false + return toCoreInterface(toCamelWithMetadata(data)) } }) diff --git a/src/files/touch.js b/src/files/touch.js index c4189ecab..11568bb4f 100644 --- a/src/files/touch.js +++ b/src/files/touch.js @@ -1,28 +1,26 @@ 'use strict' -const configure = require('../lib/configure') const mtimeToObject = require('../lib/mtime-to-object') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return function touch (path, options) { - options = options || {} +module.exports = configure(api => { + return async function touch (path, options = {}) { const mtime = mtimeToObject(options.mtime) - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) searchParams.append('arg', path) if (mtime) { searchParams.set('mtime', mtime.secs) searchParams.set('mtimeNsecs', mtime.nsecs) } - if (options.flush != null) searchParams.set('flush', options.flush) - if (options.hashAlg) searchParams.set('hash', options.hashAlg) - if (options.parents != null) searchParams.set('parents', options.parents) + searchParams.set('hash', options.hashAlg) + searchParams.set('hashAlg', null) - return ky.post('files/touch', { + const res = await api.post('files/touch', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).text() + }) + return res.text() } }) diff --git a/src/files/utils.js b/src/files/utils.js index 6dc2c499d..4856b30f5 100644 --- a/src/files/utils.js +++ b/src/files/utils.js @@ -1,6 +1,7 @@ 'use strict' exports.findSources = (args) => { + /** @type {Record} */ let options = {} let sources = [] diff --git a/src/files/write.js b/src/files/write.js index a91c920a7..06c43ab59 100644 --- a/src/files/write.js +++ b/src/files/write.js @@ -1,39 +1,27 @@ 'use strict' -const configure = require('../lib/configure') const toFormData = require('../lib/buffer-to-form-data') const modeToString = require('../lib/mode-to-string') const mtimeToObject = require('../lib/mtime-to-object') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (path, input, options) => { - options = options || {} +module.exports = configure(api => { + return async (path, input, options = {}) => { const mtime = mtimeToObject(options.mtime) - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) searchParams.set('arg', path) - searchParams.set('stream-channels', true) - if (options.cidVersion) searchParams.set('cid-version', options.cidVersion) - if (options.create != null) searchParams.set('create', options.create) - if (options.hashAlg) searchParams.set('hash', options.hashAlg) - if (options.length != null) searchParams.set('length', options.length) - if (options.offset != null) searchParams.set('offset', options.offset) - if (options.parents != null) searchParams.set('parents', options.parents) - if (options.rawLeaves != null) searchParams.set('raw-leaves', options.rawLeaves) - if (options.truncate != null) searchParams.set('truncate', options.truncate) - if (options.shardSplitThreshold != null) searchParams.set('shardSplitThreshold', options.shardSplitThreshold) + searchParams.set('stream-channels', 'true') + searchParams.set('hash', options.hashAlg) + searchParams.set('hashAlg', null) if (mtime) { searchParams.set('mtime', mtime.secs) - - if (mtime.nsecs != null) { - searchParams.set('mtimeNsecs', mtime.nsecs) - } + searchParams.set('mtimeNsecs', mtime.nsecs) } - const res = await ky.post('files/write', { + const res = await api.post('files/write', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams, body: toFormData(input, { mode: options.mode != null ? modeToString(options.mode) : undefined, diff --git a/src/get-endpoint-config.js b/src/get-endpoint-config.js index cf7125e70..3dbfcffdc 100644 --- a/src/get-endpoint-config.js +++ b/src/get-endpoint-config.js @@ -1,13 +1,15 @@ 'use strict' - const configure = require('./lib/configure') -module.exports = configure(({ apiAddr, apiPath }) => { - const url = new URL(apiAddr) - return () => ({ - host: url.hostname, - port: url.port, - protocol: url.protocol.split(':')[0], // remove ":" - 'api-path': apiPath - }) +module.exports = configure(api => { + return () => { + const url = new URL(api.opts.base) + return { + host: url.hostname, + port: url.port, + protocol: url.protocol, + pathname: url.pathname, + 'api-path': url.pathname + } + } }) diff --git a/src/get.js b/src/get.js index 635f8b34f..b8ff34ac0 100644 --- a/src/get.js +++ b/src/get.js @@ -1,44 +1,24 @@ 'use strict' -const configure = require('./lib/configure') const Tar = require('it-tar') const { Buffer } = require('buffer') const CID = require('cids') -const toIterable = require('stream-to-it/source') - -module.exports = configure(({ ky }) => { - return async function * get (path, options) { - options = options || {} - - const searchParams = new URLSearchParams() - searchParams.set('arg', `${Buffer.isBuffer(path) ? new CID(path) : path}`) - - if (options.compress !== undefined) { - searchParams.set('compress', options.compress) - } - - if (options.compressionLevel !== undefined) { - searchParams.set('compression-level', options.compressionLevel) - } - - if (options.offset) { - searchParams.set('offset', options.offset) - } +const configure = require('./lib/configure') - if (options.length) { - searchParams.set('length', options.length) - } +module.exports = configure(api => { + return async function * get (path, options = {}) { + options.arg = `${Buffer.isBuffer(path) ? new CID(path) : path}` - const res = await ky.post('get', { + const res = await api.iterator('get', { + method: 'POST', timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams + searchParams: options }) const extractor = Tar.extract() - for await (const { header, body } of extractor(toIterable(res.body))) { + for await (const { header, body } of extractor(res)) { if (header.type === 'directory') { yield { path: header.name diff --git a/src/id.js b/src/id.js index cfec69d3d..899f9f364 100644 --- a/src/id.js +++ b/src/id.js @@ -1,21 +1,19 @@ 'use strict' -const configure = require('./lib/configure') const toCamel = require('./lib/object-to-camel') const multiaddr = require('multiaddr') +const configure = require('./lib/configure') -module.exports = configure(({ ky }) => { - return async options => { - options = options || {} - - const res = await ky.post('id', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('id', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams: options.searchParams - }).json() + }) + const data = await res.json() - const output = toCamel(res) + const output = toCamel(data) if (output.addresses) { output.addresses = output.addresses.map(ma => multiaddr(ma)) diff --git a/src/index.js b/src/index.js index 320a5a9a8..850575efc 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,5 @@ 'use strict' - +/* eslint-env browser */ const { Buffer } = require('buffer') const CID = require('cids') const multiaddr = require('multiaddr') @@ -9,40 +9,49 @@ const multihash = require('multihashes') const globSource = require('ipfs-utils/src/files/glob-source') const urlSource = require('ipfs-utils/src/files/url-source') -function ipfsClient (config) { +/** + * @typedef { import("./lib/core").ClientOptions } ClientOptions + */ + +/** + * + * @param {ClientOptions } options + * @return {Object} + */ +function ipfsClient (options = {}) { return { - add: require('./add')(config), - bitswap: require('./bitswap')(config), - block: require('./block')(config), - bootstrap: require('./bootstrap')(config), - cat: require('./cat')(config), - commands: require('./commands')(config), - config: require('./config')(config), - dag: require('./dag')(config), - dht: require('./dht')(config), - diag: require('./diag')(config), - dns: require('./dns')(config), - files: require('./files')(config), - get: require('./get')(config), - getEndpointConfig: require('./get-endpoint-config')(config), - id: require('./id')(config), - key: require('./key')(config), - log: require('./log')(config), - ls: require('./ls')(config), - mount: require('./mount')(config), - name: require('./name')(config), - object: require('./object')(config), - pin: require('./pin')(config), - ping: require('./ping')(config), - pubsub: require('./pubsub')(config), - refs: require('./refs')(config), - repo: require('./repo')(config), - resolve: require('./resolve')(config), - stats: require('./stats')(config), - stop: require('./stop')(config), - shutdown: require('./stop')(config), - swarm: require('./swarm')(config), - version: require('./version')(config) + add: require('./add')(options), + bitswap: require('./bitswap')(options), + block: require('./block')(options), + bootstrap: require('./bootstrap')(options), + cat: require('./cat')(options), + commands: require('./commands')(options), + config: require('./config')(options), + dag: require('./dag')(options), + dht: require('./dht')(options), + diag: require('./diag')(options), + dns: require('./dns')(options), + files: require('./files')(options), + get: require('./get')(options), + getEndpointConfig: require('./get-endpoint-config')(options), + id: require('./id')(options), + key: require('./key')(options), + log: require('./log')(options), + ls: require('./ls')(options), + mount: require('./mount')(options), + name: require('./name')(options), + object: require('./object')(options), + pin: require('./pin')(options), + ping: require('./ping')(options), + pubsub: require('./pubsub')(options), + refs: require('./refs')(options), + repo: require('./repo')(options), + resolve: require('./resolve')(options), + stats: require('./stats')(options), + stop: require('./stop')(options), + shutdown: require('./stop')(options), + swarm: require('./swarm')(options), + version: require('./version')(options) } } diff --git a/src/key/export.js b/src/key/export.js index b5f315580..01219bc75 100644 --- a/src/key/export.js +++ b/src/key/export.js @@ -1,25 +1,22 @@ 'use strict' - const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return (name, password, options) => { +module.exports = configure(api => { + return async (name, password, options = {}) => { if (typeof password !== 'string') { - options = password + options = password || {} password = null } - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('arg', name) - if (password) searchParams.set('password', password) + options.arg = name + options.password = password - return ky.post('key/export', { + const res = await api.post('key/export', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).text() + searchParams: options + }) + + return res.text() } }) diff --git a/src/key/gen.js b/src/key/gen.js index 5fd6acb86..48a11a89a 100644 --- a/src/key/gen.js +++ b/src/key/gen.js @@ -1,24 +1,18 @@ 'use strict' -const configure = require('../lib/configure') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (name, options) => { - options = options || {} - - 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) - - const res = await ky.post('key/gen', { +module.exports = configure(api => { + return async (name, options = {}) => { + options.arg = name + const res = await api.post('key/gen', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + }) + const data = await res.json() - return toCamel(res) + return toCamel(data) } }) diff --git a/src/key/import.js b/src/key/import.js index 7cc8f5ddc..027e2ee5d 100644 --- a/src/key/import.js +++ b/src/key/import.js @@ -1,29 +1,27 @@ 'use strict' -const configure = require('../lib/configure') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (name, pem, password, options) => { +module.exports = configure(api => { + return async (name, pem, password, options = {}) => { if (typeof password !== 'string') { - options = password + options = password || {} password = null } - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) searchParams.set('arg', name) searchParams.set('pem', pem) - if (password) searchParams.set('password', password) + searchParams.set('password', password) - const res = await ky.post('key/import', { + const res = await api.post('key/import', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + }) + const data = await res.json() - return toCamel(res) + return toCamel(data) } }) diff --git a/src/key/list.js b/src/key/list.js index 80e5069aa..18642a7bc 100644 --- a/src/key/list.js +++ b/src/key/list.js @@ -1,19 +1,17 @@ 'use strict' -const configure = require('../lib/configure') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async options => { - options = options || {} - - const res = await ky.post('key/list', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('key/list', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams: options.searchParams - }).json() + }) + const data = await res.json() - return (res.Keys || []).map(k => toCamel(k)) + return (data.Keys || []).map(k => toCamel(k)) } }) diff --git a/src/key/rename.js b/src/key/rename.js index 18e069768..569edd496 100644 --- a/src/key/rename.js +++ b/src/key/rename.js @@ -1,24 +1,20 @@ 'use strict' -const configure = require('../lib/configure') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (oldName, newName, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return async (oldName, newName, options = {}) => { + const searchParams = new URLSearchParams(options) searchParams.set('arg', oldName) searchParams.append('arg', newName) - if (options.force != null) searchParams.set('force', options.force) - const res = await ky.post('key/rename', { + const res = await api.post('key/rename', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + }) - return toCamel(res) + return toCamel(await res.json()) } }) diff --git a/src/key/rm.js b/src/key/rm.js index edab61060..81744c53c 100644 --- a/src/key/rm.js +++ b/src/key/rm.js @@ -1,22 +1,20 @@ 'use strict' -const configure = require('../lib/configure') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (name, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return async (name, options = {}) => { + const searchParams = new URLSearchParams(options) searchParams.set('arg', name) - const res = await ky.post('key/rm', { + const res = await api.post('key/rm', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + }) + const data = await res.json() - return toCamel(res.Keys[0]) + return toCamel(data.Keys[0]) } }) diff --git a/src/lib/buffer-to-form-data.js b/src/lib/buffer-to-form-data.js index 1a4830361..695c052c2 100644 --- a/src/lib/buffer-to-form-data.js +++ b/src/lib/buffer-to-form-data.js @@ -1,8 +1,10 @@ 'use strict' const FormData = require('form-data') -const { isElectronRenderer } = require('ipfs-utils/src/env') +// TODO form data append doesnt have header option + +// @ts-ignore module.exports = (buf, { mode, mtime, mtimeNsecs } = {}) => { const headers = {} @@ -24,10 +26,3 @@ module.exports = (buf, { mode, mtime, mtimeNsecs } = {}) => { }) return formData } - -// TODO remove this when upstream fix for ky-universal is merged -// https://github.com/sindresorhus/ky-universal/issues/9 -// also this should only be necessary when nodeIntegration is false in electron renderer -if (isElectronRenderer) { - module.exports = require('./buffer-to-form-data.browser') -} diff --git a/src/lib/configure.js b/src/lib/configure.js index 9e6c9465f..49b2d2f5a 100644 --- a/src/lib/configure.js +++ b/src/lib/configure.js @@ -1,96 +1,20 @@ 'use strict' /* eslint-env browser */ -const ky = require('ky-universal').default -const { isBrowser, isWebWorker } = require('ipfs-utils/src/env') -const toUri = require('multiaddr-to-uri') -const errorHandler = require('./error-handler') -const mergeOptions = require('merge-options').bind({ ignoreUndefined: true }) -const parseDuration = require('parse-duration') +const Client = require('./core') // Set default configuration and call create function with them -module.exports = create => config => { - config = config || {} - - if (typeof config === 'string') { - config = { apiAddr: config } - } else if (config.constructor && config.constructor.isMultiaddr) { - config = { apiAddr: config } - } else { - config = { ...config } - } - - config.apiAddr = (config.apiAddr || getDefaultApiAddr(config)).toString() - config.apiAddr = config.apiAddr.startsWith('/') ? toUri(config.apiAddr) : config.apiAddr - 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 - - const defaults = { - prefixUrl: config.apiAddr + config.apiPath, - timeout: parseTimeout(config.timeout) || 60000 * 20, - headers: config.headers, - hooks: { - afterResponse: [errorHandler] - } - } - const k = ky.extend(defaults) - const client = ['get', 'post', 'put', 'delete', 'patch', 'head'] - .reduce((client, key) => { - client[key] = wrap(k[key], defaults) - - return client - }, wrap(k, defaults)) - - return create({ - ky: client, - ...config - }) -} - -function getDefaultApiAddr ({ protocol, host, port }) { - if (isBrowser || isWebWorker) { - if (!protocol) { - protocol = location.protocol.startsWith('http') - ? trimEnd(location.protocol, ':') - : 'http' - } - - host = host || location.hostname - port = port || location.port - - return `${protocol}://${host}${port ? ':' + port : ''}` - } - - return `${protocol || 'http'}://${host || 'localhost'}:${port || 5001}` -} - -// returns the passed function wrapped in a function that ignores -// undefined values in the passed `options` object -function wrap (fn, defaults) { - return (input, options) => { - if (options.timeout) options.timeout = parseTimeout(options.timeout) - return fn(input, mergeOptions(defaults, options)) - } -} - -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 +/** + * @typedef { import("./core").ClientOptions } ClientOptions + */ + +/** + * @param {function(Client, ClientOptions): void} fn + * @returns {function(ClientOptions): void} + */ +const configure = (fn) => { + return (options) => { + return fn(new Client(options), options) } } +module.exports = configure diff --git a/src/lib/core.js b/src/lib/core.js new file mode 100644 index 000000000..33ae8d14b --- /dev/null +++ b/src/lib/core.js @@ -0,0 +1,133 @@ +'use strict' +/* eslint-env browser */ +const Multiaddr = require('multiaddr') +const toUri = require('multiaddr-to-uri') +const { isBrowser, isWebWorker } = require('ipfs-utils/src/env') +const { URL } = require('iso-url') +const parseDuration = require('parse-duration') +const log = require('debug')('ipfs-http-client:lib:error-handler') +const HTTP = require('ipfs-utils/src/http') + +const isMultiaddr = (input) => { + try { + Multiaddr(input) // eslint-disable-line no-new + return true + } catch (e) { + return false + } +} + +const normalizeInput = (options = {}) => { + if (isMultiaddr(options)) { + options = { url: toUri(options) } + } else if (typeof options === 'string') { + options = { url: options } + } + + const url = new URL(options.url) + if (options.apiPath) { + url.pathname = options.apiPath + } else if (url.pathname === '/' || url.pathname === undefined) { + url.pathname = 'api/v0' + } + if (!options.url) { + if (isBrowser || isWebWorker) { + url.protocol = options.protocol || location.protocol + url.hostname = options.host || location.hostname + url.port = options.port || location.port + } else { + url.hostname = options.host || 'localhost' + url.port = options.port || '5001' + url.protocol = options.protocol || 'http' + } + } + options.url = url + + return options +} + +const errorHandler = async (response) => { + let msg + + try { + if ((response.headers.get('Content-Type') || '').startsWith('application/json')) { + const data = await response.json() + log(data) + msg = data.Message || data.message + } else { + msg = await response.text() + } + } catch (err) { + log('Failed to parse error response', err) + // Failed to extract/parse error message from response + msg = err.message + } + + const error = new HTTP.HTTPError(response) + + // If we managed to extract a message from the response, use it + if (msg) { + error.message = msg + } + + throw error +} + +const KEBAB_REGEX = /[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g +const kebabCase = (str) => { + return str.replace(KEBAB_REGEX, function (match) { + return '-' + match.toLowerCase() + }) +} + +const parseTimeout = (value) => { + return typeof value === 'string' ? parseDuration(value) : value +} + +/** + * @typedef {Object} ClientOptions + * @prop {string} [host] + * @prop {number} [port] + * @prop {string} [protocol] + * @prop {Headers|Record} [headers] - Request headers. + * @prop {number|string} [timeout] - Amount of time until request should timeout in ms or humand readable. https://www.npmjs.com/package/parse-duration for valid string values. + * @prop {string} [apiPath] - Path to the API. + * @prop {URL|string} [url] - Full API URL. + */ + +class Client extends HTTP { + /** + * + * @param {ClientOptions|URL|Multiaddr|string} options + */ + constructor (options = {}) { + /** @type {ClientOptions} */ + const opts = normalizeInput(options) + super({ + timeout: parseTimeout(opts.timeout) || 60000 * 20, + headers: opts.headers, + base: normalizeInput(opts.url).toString(), + handleError: errorHandler, + transformSearchParams: (search) => { + const out = new URLSearchParams() + + // @ts-ignore https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams + for (const [key, value] of search) { + if ( + value !== 'undefined' && + value !== 'null' && + key !== 'signal' && + key !== 'timeout' + ) { + out.append(kebabCase(key), value) + } + } + return out + } + }) + } +} + +Client.errorHandler = errorHandler + +module.exports = Client diff --git a/src/lib/error-handler.js b/src/lib/error-handler.js deleted file mode 100644 index 3aae8a41c..000000000 --- a/src/lib/error-handler.js +++ /dev/null @@ -1,49 +0,0 @@ -'use strict' - -const { HTTPError } = require('ky-universal') -const log = require('debug')('ipfs-http-client:lib:error-handler') -const { isNode, isElectronMain } = require('ipfs-utils/src/env') - -function isJsonResponse (res) { - return (res.headers.get('Content-Type') || '').startsWith('application/json') -} - -module.exports = async function errorHandler (input, options, response) { - if (response.ok) { - // FIXME: remove when fixed https://github.com/sindresorhus/ky-universal/issues/8 - // - // ky clones the response for each handler. In Node.js the response body is - // piped to 2 PassThroughs, one becomes the real body and the other is used - // in the clone. - // - // If the body in the clone is not consumed or destroyed the highwater mark - // will be reached (for large payloads) and stop the real body from flowing. - if (isNode || isElectronMain) response.body.destroy() - return - } - - let msg - - try { - if (isJsonResponse(response)) { - const data = await response.json() - log(data) - msg = data.Message || data.message - } else { - msg = await response.text() - } - } catch (err) { - log('Failed to parse error response', err) - // Failed to extract/parse error message from response - msg = err.message - } - - const error = new HTTPError(response) - - // If we managed to extract a message from the response, use it - if (msg) { - error.message = msg - } - - throw error -} diff --git a/src/log/level.js b/src/log/level.js index dcc20c7bd..3608cd12e 100644 --- a/src/log/level.js +++ b/src/log/level.js @@ -1,23 +1,20 @@ 'use strict' -const configure = require('../lib/configure') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (subsystem, level, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('arg', subsystem) +module.exports = configure(api => { + return async (subsystem, level, options = {}) => { + const searchParams = new URLSearchParams(options) + searchParams.append('arg', subsystem) searchParams.append('arg', level) - const res = await ky.post('log/level', { + const res = await api.post('log/level', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + }) - return toCamel(res) + return toCamel(await res.json()) } }) diff --git a/src/log/ls.js b/src/log/ls.js index 0a8d69c6c..be9d8eef3 100644 --- a/src/log/ls.js +++ b/src/log/ls.js @@ -2,17 +2,15 @@ const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async options => { - options = options || {} - - const res = await ky.post('log/ls', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('log/ls', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams: options.searchParams - }).json() + }) - return res.Strings + const data = await res.json() + return data.Strings } }) diff --git a/src/log/tail.js b/src/log/tail.js index 74b72b2c2..91d00d713 100644 --- a/src/log/tail.js +++ b/src/log/tail.js @@ -1,20 +1,15 @@ 'use strict' -const ndjson = require('iterable-ndjson') const configure = require('../lib/configure') -const toIterable = require('stream-to-it/source') -module.exports = configure(({ ky }) => { - return async function * tail (options) { - options = options || {} - - const res = await ky.post('log/tail', { +module.exports = configure(api => { + return async function * tail (options = {}) { + const res = await api.ndjson('log/tail', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams: options.searchParams + searchParams: options }) - yield * ndjson(toIterable(res.body)) + yield * res } }) diff --git a/src/ls.js b/src/ls.js index ec7e37dfb..f6619dccc 100644 --- a/src/ls.js +++ b/src/ls.js @@ -2,30 +2,21 @@ const { Buffer } = require('buffer') const CID = require('cids') -const ndjson = require('iterable-ndjson') -const toIterable = require('stream-to-it/source') const configure = require('./lib/configure') -module.exports = configure(({ ky }) => { - return async function * ls (path, options) { - options = options || {} - - const searchParams = new URLSearchParams() +module.exports = configure(api => { + return async function * ls (path, options = {}) { + const searchParams = new URLSearchParams(options) searchParams.set('arg', `${Buffer.isBuffer(path) ? new CID(path) : path}`) - searchParams.set('stream', options.stream == null ? true : options.stream) - - if (options.long != null) searchParams.set('long', options.long) - if (options.unsorted != null) searchParams.set('unsorted', options.unsorted) - if (options.recursive != null) searchParams.set('recursive', options.recursive) - const res = await ky.post('ls', { + const res = await api.ndjson('ls', { + method: 'POST', timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams }) - for await (let result of ndjson(toIterable(res.body))) { + for await (let result of res) { result = result.Objects if (!result) { diff --git a/src/mount.js b/src/mount.js index a5d2faef1..13421b924 100644 --- a/src/mount.js +++ b/src/mount.js @@ -1,23 +1,16 @@ 'use strict' -const configure = require('./lib/configure') const toCamel = require('./lib/object-to-camel') +const configure = require('./lib/configure') -module.exports = configure(({ ky }) => { - return async options => { - options = options || {} - - 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) - - const res = await ky.post('dns', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('dns', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + }) - return toCamel(res) + return toCamel(await res.json()) } }) diff --git a/src/name/publish.js b/src/name/publish.js index e470606f9..da6ccddc1 100644 --- a/src/name/publish.js +++ b/src/name/publish.js @@ -1,28 +1,19 @@ 'use strict' -const configure = require('../lib/configure') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (path, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return async (path, options = {}) => { + const searchParams = new URLSearchParams(options) 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) - const res = await ky.post('name/publish', { + const res = await api.post('name/publish', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + }) - return toCamel(res) + return toCamel(await res.json()) } }) diff --git a/src/name/pubsub/cancel.js b/src/name/pubsub/cancel.js index ea5391e64..3d240b307 100644 --- a/src/name/pubsub/cancel.js +++ b/src/name/pubsub/cancel.js @@ -1,22 +1,19 @@ 'use strict' -const configure = require('../../lib/configure') const toCamel = require('../../lib/object-to-camel') +const configure = require('../../lib/configure') -module.exports = configure(({ ky }) => { - return async (name, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return async (name, options = {}) => { + const searchParams = new URLSearchParams(options) searchParams.set('arg', name) - const res = await ky.post('name/pubsub/cancel', { + const res = await api.post('name/pubsub/cancel', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + }) - return toCamel(res) + return toCamel(await res.json()) } }) diff --git a/src/name/pubsub/state.js b/src/name/pubsub/state.js index 03e18aa7f..077c84a19 100644 --- a/src/name/pubsub/state.js +++ b/src/name/pubsub/state.js @@ -1,19 +1,16 @@ 'use strict' -const configure = require('../../lib/configure') const toCamel = require('../../lib/object-to-camel') +const configure = require('../../lib/configure') -module.exports = configure(({ ky }) => { - return async options => { - options = options || {} - - const res = await ky.post('name/pubsub/state', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('name/pubsub/state', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams: options.searchParams - }).json() + }) - return toCamel(res) + return toCamel(await res.json()) } }) diff --git a/src/name/pubsub/subs.js b/src/name/pubsub/subs.js index 9bc6c2208..7428590d7 100644 --- a/src/name/pubsub/subs.js +++ b/src/name/pubsub/subs.js @@ -2,17 +2,14 @@ const configure = require('../../lib/configure') -module.exports = configure(({ ky }) => { - return async (name, options) => { - options = options || {} - - const res = await ky.post('name/pubsub/subs', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('name/pubsub/subs', { timeout: options.timeout, - signal: options.signal, - headers: options.headers, - searchParams: options.searchParams - }).json() + signal: options.signal + }) + const data = await res.json() - return res.Strings || [] + return data.Strings || [] } }) diff --git a/src/name/resolve.js b/src/name/resolve.js index e7eb20b4f..16406bab2 100644 --- a/src/name/resolve.js +++ b/src/name/resolve.js @@ -1,29 +1,20 @@ 'use strict' -const ndjson = require('iterable-ndjson') const configure = require('../lib/configure') -const toIterable = require('stream-to-it/source') -module.exports = configure(({ ky }) => { - return async function * (path, options) { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return async function * (path, options = {}) { + const searchParams = new URLSearchParams(options) searchParams.set('arg', path) - searchParams.set('stream', options.stream == null ? true : options.stream) - 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) + searchParams.set('stream', options.stream || true) - const res = await ky.post('name/resolve', { + const res = await api.ndjson('name/resolve', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams }) - for await (const result of ndjson(toIterable(res.body))) { + for await (const result of res) { yield result.Path } } diff --git a/src/object/data.js b/src/object/data.js index 5f40e0450..6101f0901 100644 --- a/src/object/data.js +++ b/src/object/data.js @@ -4,19 +4,17 @@ const { Buffer } = require('buffer') const CID = require('cids') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async function data (cid, options) { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return async function data (cid, options = {}) { + const searchParams = new URLSearchParams(options) searchParams.set('arg', `${Buffer.isBuffer(cid) ? new CID(cid) : cid}`) - const data = await ky.post('object/data', { + const res = await api.post('object/data', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).arrayBuffer() + }) + const data = await res.arrayBuffer() return Buffer.from(data) } diff --git a/src/object/get.js b/src/object/get.js index 8dd2b638d..6298c0c40 100644 --- a/src/object/get.js +++ b/src/object/get.js @@ -5,24 +5,22 @@ const CID = require('cids') const { DAGNode, DAGLink } = require('ipld-dag-pb') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (cid, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return async (cid, options = {}) => { + const searchParams = new URLSearchParams(options) searchParams.set('arg', `${Buffer.isBuffer(cid) ? new CID(cid) : cid}`) searchParams.set('data-encoding', 'base64') - const res = await ky.post('object/get', { + const res = await api.post('object/get', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + }) + const data = await res.json() return new DAGNode( - Buffer.from(res.Data, 'base64'), - (res.Links || []).map(l => new DAGLink(l.Name, l.Size, l.Hash)) + Buffer.from(data.Data, 'base64'), + (data.Links || []).map(l => new DAGLink(l.Name, l.Size, l.Hash)) ) } }) diff --git a/src/object/links.js b/src/object/links.js index f05ddb630..519f4c7c0 100644 --- a/src/object/links.js +++ b/src/object/links.js @@ -5,20 +5,18 @@ const CID = require('cids') const { DAGLink } = require('ipld-dag-pb') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (cid, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return async (cid, options = {}) => { + const searchParams = new URLSearchParams(options) searchParams.set('arg', `${Buffer.isBuffer(cid) ? new CID(cid) : cid}`) - const res = await ky.post('object/links', { + const res = await api.post('object/links', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + }) + const data = await res.json() - return (res.Links || []).map(l => new DAGLink(l.Name, l.Size, l.Hash)) + return (data.Links || []).map(l => new DAGLink(l.Name, l.Size, l.Hash)) } }) diff --git a/src/object/new.js b/src/object/new.js index d372812a5..377165cf4 100644 --- a/src/object/new.js +++ b/src/object/new.js @@ -3,24 +3,23 @@ const CID = require('cids') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (template, options) => { +module.exports = configure(api => { + return async (template, options = {}) => { if (typeof template !== 'string') { - options = template + options = template || {} template = null } - options = options || {} + const searchParams = new URLSearchParams(options) + searchParams.set('arg', template) - const searchParams = new URLSearchParams(options.searchParams) - if (template) searchParams.set('arg', template) - - const { Hash } = await ky.post('object/new', { + const res = await api.post('object/new', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + }) + + const { Hash } = await res.json() return new CID(Hash) } diff --git a/src/object/patch/add-link.js b/src/object/patch/add-link.js index 55821751d..291bf3527 100644 --- a/src/object/patch/add-link.js +++ b/src/object/patch/add-link.js @@ -4,21 +4,18 @@ const { Buffer } = require('buffer') const CID = require('cids') const configure = require('../../lib/configure') -module.exports = configure(({ ky }) => { - return async (cid, dLink, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return async (cid, dLink, options = {}) => { + const searchParams = new URLSearchParams(options) searchParams.set('arg', `${Buffer.isBuffer(cid) ? new CID(cid) : cid}`) searchParams.append('arg', dLink.Name || dLink.name || null) searchParams.append('arg', (dLink.Hash || dLink.cid || '').toString() || null) - const { Hash } = await ky.post('object/patch/add-link', { + const { Hash } = await (await api.post('object/patch/add-link', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + })).json() return new CID(Hash) } diff --git a/src/object/patch/append-data.js b/src/object/patch/append-data.js index 1ab8d1381..93615e96f 100644 --- a/src/object/patch/append-data.js +++ b/src/object/patch/append-data.js @@ -2,23 +2,20 @@ const { Buffer } = require('buffer') const CID = require('cids') -const configure = require('../../lib/configure') const toFormData = require('../../lib/buffer-to-form-data') +const configure = require('../../lib/configure') -module.exports = configure(({ ky }) => { - return async (cid, data, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return async (cid, data, options = {}) => { + const searchParams = new URLSearchParams(options) searchParams.set('arg', `${Buffer.isBuffer(cid) ? new CID(cid) : cid}`) - const { Hash } = await ky.post('object/patch/append-data', { + const { Hash } = await (await api.post('object/patch/append-data', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams, body: toFormData(data) - }).json() + })).json() return new CID(Hash) } diff --git a/src/object/patch/rm-link.js b/src/object/patch/rm-link.js index 39ea0ea3b..fae91b37f 100644 --- a/src/object/patch/rm-link.js +++ b/src/object/patch/rm-link.js @@ -4,20 +4,17 @@ const { Buffer } = require('buffer') const CID = require('cids') const configure = require('../../lib/configure') -module.exports = configure(({ ky }) => { - return async (cid, dLink, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('arg', `${Buffer.isBuffer(cid) ? new CID(cid) : cid}`) +module.exports = configure(api => { + return async (cid, dLink, options = {}) => { + const searchParams = new URLSearchParams(options) + searchParams.append('arg', `${Buffer.isBuffer(cid) ? new CID(cid) : cid}`) searchParams.append('arg', dLink.Name || dLink.name || null) - const { Hash } = await ky.post('object/patch/rm-link', { + const { Hash } = await (await api.post('object/patch/rm-link', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + })).json() return new CID(Hash) } diff --git a/src/object/patch/set-data.js b/src/object/patch/set-data.js index 7bb131fb7..1169520e6 100644 --- a/src/object/patch/set-data.js +++ b/src/object/patch/set-data.js @@ -2,23 +2,20 @@ const { Buffer } = require('buffer') const CID = require('cids') -const configure = require('../../lib/configure') const toFormData = require('../../lib/buffer-to-form-data') +const configure = require('../../lib/configure') -module.exports = configure(({ ky }) => { - return async (cid, data, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return async (cid, data, options = {}) => { + const searchParams = new URLSearchParams(options) searchParams.set('arg', `${Buffer.isBuffer(cid) ? new CID(cid) : cid}`) - const { Hash } = await ky.post('object/patch/set-data', { + const { Hash } = await (await api.post('object/patch/set-data', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams, body: toFormData(data) - }).json() + })).json() return new CID(Hash) } diff --git a/src/object/put.js b/src/object/put.js index be8660a00..8f9cccd21 100644 --- a/src/object/put.js +++ b/src/object/put.js @@ -3,13 +3,11 @@ const CID = require('cids') const { DAGNode } = require('ipld-dag-pb') const { Buffer } = require('buffer') -const configure = require('../lib/configure') const toFormData = require('../lib/buffer-to-form-data') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (obj, options) => { - options = options || {} - +module.exports = configure(api => { + return async (obj, options = {}) => { let tmpObj = { Data: null, Links: [] @@ -45,18 +43,14 @@ module.exports = configure(({ ky }) => { buf = Buffer.from(JSON.stringify(tmpObj)) } - const searchParams = new URLSearchParams(options.searchParams) - if (options.enc) searchParams.set('inputenc', options.enc) - if (options.pin != null) searchParams.set('pin', options.pin) - if (options.quiet != null) searchParams.set('quiet', options.quiet) - - const { Hash } = await ky.post('object/put', { + const res = await api.post('object/put', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams, + searchParams: options, body: toFormData(buf) - }).json() + }) + + const { Hash } = await res.json() return new CID(Hash) } diff --git a/src/object/stat.js b/src/object/stat.js index c3d2d8edc..04d9d32c6 100644 --- a/src/object/stat.js +++ b/src/object/stat.js @@ -4,21 +4,18 @@ const { Buffer } = require('buffer') const CID = require('cids') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (cid, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return async (cid, options = {}) => { + const searchParams = new URLSearchParams(options) searchParams.set('arg', `${Buffer.isBuffer(cid) ? new CID(cid) : cid}`) let res try { - res = await ky.post('object/stat', { + res = await (await api.post('object/stat', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + })).json() } catch (err) { if (err.name === 'TimeoutError') { err.message = `failed to get block for ${Buffer.isBuffer(cid) ? new CID(cid) : cid}: context deadline exceeded` diff --git a/src/pin/add.js b/src/pin/add.js index 41b119fe8..3bf10a284 100644 --- a/src/pin/add.js +++ b/src/pin/add.js @@ -3,21 +3,18 @@ const CID = require('cids') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (paths, options) => { +module.exports = configure(api => { + return async (paths, options = {}) => { paths = Array.isArray(paths) ? paths : [paths] - options = options || {} - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) paths.forEach(path => searchParams.append('arg', `${path}`)) - if (options.recursive != null) searchParams.set('recursive', options.recursive) - const res = await ky.post('pin/add', { + const res = await (await api.post('pin/add', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + })).json() return (res.Pins || []).map(cid => ({ cid: new CID(cid) })) } diff --git a/src/pin/ls.js b/src/pin/ls.js index f9e0968ac..26cc3bd36 100644 --- a/src/pin/ls.js +++ b/src/pin/ls.js @@ -1,41 +1,37 @@ 'use strict' -const ndjson = require('iterable-ndjson') const CID = require('cids') const configure = require('../lib/configure') -const toIterable = require('stream-to-it/source') -module.exports = configure(({ ky }) => { - return async function * ls (path, options) { +module.exports = configure(api => { + return async function * ls (path, options = {}) { if (path && path.type) { - options = path - path = null + options = path || {} + path = [] } - path = path || [] path = Array.isArray(path) ? path : [path] - options = options || {} - const searchParams = new URLSearchParams(options.searchParams) - searchParams.set('stream', options.stream == null ? true : options.stream) + const searchParams = new URLSearchParams(options) + searchParams.set('stream', options.stream || true) path.forEach(p => searchParams.append('arg', `${p}`)) - if (options.type) searchParams.set('type', options.type) - const res = await ky.post('pin/ls', { + const source = api.ndjson('pin/ls', { + method: 'POST', timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams }) - for await (const pin of ndjson(toIterable(res.body))) { + for await (const pin of source) { if (pin.Keys) { // non-streaming response - for (const cid of Object.keys(pin.Keys)) { - yield { cid: new CID(cid), type: pin.Keys[cid].Type } + // eslint-disable-next-line guard-for-in + for (const key in pin.Keys) { + yield { cid: new CID(key), type: pin.Keys[key].Type } } - return + } else { + yield { cid: new CID(pin.Cid), type: pin.Type } } - yield { cid: new CID(pin.Cid), type: pin.Type } } } }) diff --git a/src/pin/rm.js b/src/pin/rm.js index 83fbca93c..30c8c46d1 100644 --- a/src/pin/rm.js +++ b/src/pin/rm.js @@ -3,20 +3,16 @@ const CID = require('cids') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (path, options) => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return async (path, options = {}) => { + const searchParams = new URLSearchParams(options) searchParams.set('arg', `${path}`) - if (options.recursive != null) searchParams.set('recursive', options.recursive) - const res = await ky.post('pin/rm', { + const res = await (await api.post('pin/rm', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + })).json() return (res.Pins || []).map(cid => ({ cid: new CID(cid) })) } diff --git a/src/ping.js b/src/ping.js index 332120934..373fdfe66 100644 --- a/src/ping.js +++ b/src/ping.js @@ -1,27 +1,19 @@ 'use strict' -const ndjson = require('iterable-ndjson') -const configure = require('./lib/configure') -const toIterable = require('stream-to-it/source') const toCamel = require('./lib/object-to-camel') +const configure = require('./lib/configure') -module.exports = configure(({ ky }) => { - return async function * ping (peerId, options) { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) +module.exports = configure(api => { + return function ping (peerId, options = {}) { + const searchParams = new URLSearchParams(options) searchParams.set('arg', `${peerId}`) - if (options.count != null) searchParams.set('count', options.count) - const res = await ky.post('ping', { + return api.ndjson('ping', { + method: 'POST', timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams + searchParams, + transform: toCamel }) - - for await (const chunk of ndjson(toIterable(res.body))) { - yield toCamel(chunk) - } } }) diff --git a/src/pubsub/ls.js b/src/pubsub/ls.js index d2bc8f68d..23b1c6ab8 100644 --- a/src/pubsub/ls.js +++ b/src/pubsub/ls.js @@ -2,16 +2,13 @@ const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (options) => { - options = options || {} - - const { Strings } = await ky.post('pubsub/ls', { +module.exports = configure(api => { + return async (options = {}) => { + const { Strings } = await (await api.post('pubsub/ls', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams: options.searchParams - }).json() + })).json() return Strings || [] } diff --git a/src/pubsub/peers.js b/src/pubsub/peers.js index 5fa5b2436..8489275c4 100644 --- a/src/pubsub/peers.js +++ b/src/pubsub/peers.js @@ -2,24 +2,21 @@ const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (topic, options) => { +module.exports = configure(api => { + return async (topic, options = {}) => { if (!options && typeof topic === 'object') { - options = topic + options = topic || {} topic = null } - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) searchParams.set('arg', topic) - const { Strings } = await ky.post('pubsub/peers', { + const { Strings } = await (await api.post('pubsub/peers', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + })).json() return Strings || [] } diff --git a/src/pubsub/publish.js b/src/pubsub/publish.js index 10a5017cc..3638f7c46 100644 --- a/src/pubsub/publish.js +++ b/src/pubsub/publish.js @@ -1,22 +1,20 @@ 'use strict' const { Buffer } = require('buffer') -const configure = require('../lib/configure') const encodeBuffer = require('../lib/encode-buffer-uri-component') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (topic, data, options) => { - options = options || {} +module.exports = configure(api => { + return async (topic, data, options = {}) => { data = Buffer.from(data) - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) searchParams.set('arg', topic) - const res = await ky.post(`pubsub/pub?${searchParams}&arg=${encodeBuffer(data)}`, { + const res = await (await api.post(`pubsub/pub?${searchParams}&arg=${encodeBuffer(data)}`, { timeout: options.timeout, - signal: options.signal, - headers: options.headers - }).text() + signal: options.signal + })).text() return res } diff --git a/src/pubsub/subscribe.js b/src/pubsub/subscribe.js index 188a91664..d9a6368c9 100644 --- a/src/pubsub/subscribe.js +++ b/src/pubsub/subscribe.js @@ -1,25 +1,21 @@ 'use strict' -const ndjson = require('iterable-ndjson') const bs58 = require('bs58') const { Buffer } = require('buffer') const log = require('debug')('ipfs-http-client:pubsub:subscribe') -const configure = require('../lib/configure') -const toIterable = require('stream-to-it/source') const SubscriptionTracker = require('./subscription-tracker') +const { streamToAsyncIterator, ndjson } = require('../lib/core') +const configure = require('../lib/configure') -module.exports = configure((config) => { - const ky = config.ky +module.exports = configure((api, options) => { const subsTracker = SubscriptionTracker.singleton() - const publish = require('./publish')(config) + const publish = require('./publish')(options) - return async (topic, handler, options) => { - options = options || {} + return async (topic, handler, options = {}) => { options.signal = subsTracker.subscribe(topic, handler, options.signal) - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) searchParams.set('arg', topic) - if (options.discover != null) searchParams.set('discover', options.discover) let res @@ -36,10 +32,10 @@ module.exports = configure((config) => { }, 1000) try { - res = await ky.post('pubsub/sub', { + res = await api.stream('pubsub/sub', { + method: 'POST', timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams }) } catch (err) { // Initial subscribe fail, ensure we clean up @@ -49,7 +45,7 @@ module.exports = configure((config) => { clearTimeout(ffWorkaround) - readMessages(ndjson(toIterable(res.body)), { + readMessages(ndjson(streamToAsyncIterator(res)), { onMessage: handler, onEnd: () => subsTracker.unsubscribe(topic, handler), onError: options.onError diff --git a/src/pubsub/subscription-tracker.js b/src/pubsub/subscription-tracker.js index bbd7c2d7a..191f832ce 100644 --- a/src/pubsub/subscription-tracker.js +++ b/src/pubsub/subscription-tracker.js @@ -49,4 +49,6 @@ class SubscriptionTracker { } } +SubscriptionTracker.instance = null + module.exports = SubscriptionTracker diff --git a/src/pubsub/unsubscribe.js b/src/pubsub/unsubscribe.js index 6e7c727f4..7d90a02c0 100644 --- a/src/pubsub/unsubscribe.js +++ b/src/pubsub/unsubscribe.js @@ -1,10 +1,9 @@ 'use strict' -const configure = require('../lib/configure') const SubscriptionTracker = require('./subscription-tracker') -module.exports = configure(({ ky }) => { +module.exports = api => { const subsTracker = SubscriptionTracker.singleton() // eslint-disable-next-line require-await return async (topic, handler) => subsTracker.unsubscribe(topic, handler) -}) +} diff --git a/src/refs/index.js b/src/refs/index.js index 05a636feb..06ddbb599 100644 --- a/src/refs/index.js +++ b/src/refs/index.js @@ -1,61 +1,31 @@ 'use strict' -const configure = require('../lib/configure') const { Buffer } = require('buffer') const CID = require('cids') -const ndjson = require('iterable-ndjson') -const toIterable = require('stream-to-it/source') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = config => { - const refs = (configure(({ ky }) => { - return async function * refs (args, options) { - options = options || {} - - const searchParams = new URLSearchParams() - - if (options.format !== undefined) { - searchParams.set('format', options.format) - } - - if (options.edges !== undefined) { - searchParams.set('edges', options.edges) - } - - if (options.unique !== undefined) { - searchParams.set('unique', options.unique) - } - - if (options.recursive !== undefined) { - searchParams.set('recursive', options.recursive) - } - - if (options.maxDepth !== undefined) { - searchParams.set('max-depth', options.maxDepth) - } - - if (!Array.isArray(args)) { - args = [args] - } - - for (const arg of args) { - searchParams.append('arg', `${Buffer.isBuffer(arg) ? new CID(arg) : arg}`) - } +module.exports = configure((api, options) => { + const refs = (args, options = {}) => { + const searchParams = new URLSearchParams(options) - const res = await ky.post('refs', { - timeout: options.timeout, - signal: options.signal, - headers: options.headers, - searchParams - }) + if (!Array.isArray(args)) { + args = [args] + } - for await (const file of ndjson(toIterable(res.body))) { - yield toCamel(file) - } + for (const arg of args) { + searchParams.append('arg', `${Buffer.isBuffer(arg) ? new CID(arg) : arg}`) } - }))(config) - refs.local = require('./local')(config) + return api.ndjson('refs', { + method: 'POST', + timeout: options.timeout, + signal: options.signal, + searchParams, + transform: toCamel + }) + } + refs.local = require('./local')(options) return refs -} +}) diff --git a/src/refs/local.js b/src/refs/local.js index 98e0fce40..1ddfbadfc 100644 --- a/src/refs/local.js +++ b/src/refs/local.js @@ -1,22 +1,15 @@ 'use strict' -const configure = require('../lib/configure') -const ndjson = require('iterable-ndjson') -const toIterable = require('stream-to-it/source') const toCamel = require('../lib/object-to-camel') +const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async function * refsLocal (options) { - options = options || {} - - const res = await ky.post('refs/local', { +module.exports = configure(api => { + return function refsLocal (options = {}) { + return api.ndjson('refs/local', { + method: 'POST', timeout: options.timeout, signal: options.signal, - headers: options.headers + transform: toCamel }) - - for await (const file of ndjson(toIterable(res.body))) { - yield toCamel(file) - } } }) diff --git a/src/repo/gc.js b/src/repo/gc.js index fc60a46bc..230daa6fc 100644 --- a/src/repo/gc.js +++ b/src/repo/gc.js @@ -1,29 +1,21 @@ 'use strict' const CID = require('cids') -const ndjson = require('iterable-ndjson') const configure = require('../lib/configure') -const toIterable = require('stream-to-it/source') -module.exports = configure(({ ky }) => { - return async function * gc (peerId, options) { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - if (options.streamErrors) searchParams.set('stream-errors', options.streamErrors) - - const res = await ky.post('repo/gc', { +module.exports = configure(api => { + return function gc (options = {}) { + return api.ndjson('repo/gc', { + method: 'POST', 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 + searchParams: options, + transform: (res) => { + return { + err: res.Error ? new Error(res.Error) : null, + cid: (res.Key || {})['/'] ? new CID(res.Key['/']) : null + } } - } + }) } }) diff --git a/src/repo/stat.js b/src/repo/stat.js index 17895e353..ed297cd75 100644 --- a/src/repo/stat.js +++ b/src/repo/stat.js @@ -1,28 +1,22 @@ 'use strict' -const Big = require('bignumber.js') +const { BigNumber } = require('bignumber.js') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async options => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - if (options.sizeOnly) searchParams.set('size-only', options.sizeOnly) - - const res = await ky.post('repo/stat', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await (await api.post('repo/stat', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + })).json() return { - numObjects: new Big(res.NumObjects), - repoSize: new Big(res.RepoSize), + numObjects: new BigNumber(res.NumObjects), + repoSize: new BigNumber(res.RepoSize), repoPath: res.RepoPath, version: res.Version, - storageMax: new Big(res.StorageMax) + storageMax: new BigNumber(res.StorageMax) } } }) diff --git a/src/repo/version.js b/src/repo/version.js index 1bfc708e0..1ca2502c8 100644 --- a/src/repo/version.js +++ b/src/repo/version.js @@ -2,19 +2,13 @@ const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async options => { - options = options || {} - - const searchParams = new URLSearchParams(options.searchParams) - if (options.sizeOnly) searchParams.set('size-only', options.sizeOnly) - - const res = await ky.post('repo/version', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await (await api.post('repo/version', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + })).json() return res.Version } diff --git a/src/resolve.js b/src/resolve.js index 33c44b6e6..25bbf96e3 100644 --- a/src/resolve.js +++ b/src/resolve.js @@ -2,24 +2,15 @@ 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', { +module.exports = configure(api => { + return async (path, options = {}) => { + options.arg = path + const rsp = await api.post('resolve', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() - - return res.Path + searchParams: options + }) + const data = await rsp.json() + return data.Path } }) diff --git a/src/stats/bw.js b/src/stats/bw.js index 12bc6d44a..9c6d081ee 100644 --- a/src/stats/bw.js +++ b/src/stats/bw.js @@ -1,34 +1,21 @@ 'use strict' -const ndjson = require('iterable-ndjson') -const Big = require('bignumber.js') +const { BigNumber } = require('bignumber.js') const configure = require('../lib/configure') -const toIterable = require('stream-to-it/source') -module.exports = configure(({ ky }) => { - return async function * bw (options) { - options = options || {} - - 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) - - const res = await ky.post('stats/bw', { +module.exports = configure(api => { + return function bw (options = {}) { + return api.ndjson('stats/bw', { + method: 'POST', timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams + searchParams: options, + transform: (stats) => ({ + totalIn: new BigNumber(stats.TotalIn), + totalOut: new BigNumber(stats.TotalOut), + rateIn: new BigNumber(stats.RateIn), + rateOut: new BigNumber(stats.RateOut) + }) }) - - 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/stop.js b/src/stop.js index 7cae46880..540961cf7 100644 --- a/src/stop.js +++ b/src/stop.js @@ -2,15 +2,12 @@ const configure = require('./lib/configure') -module.exports = configure(({ ky }) => { - return options => { - options = options || {} - - return ky.post('shutdown', { +module.exports = configure(api => { + return async (options = {}) => { + return (await api.post('shutdown', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams: options.searchParams - }).text() + searchParams: options + })).text() } }) diff --git a/src/swarm/addrs.js b/src/swarm/addrs.js index c4b6576f6..f22fede1e 100644 --- a/src/swarm/addrs.js +++ b/src/swarm/addrs.js @@ -3,16 +3,13 @@ const multiaddr = require('multiaddr') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async options => { - options = options || {} - - const res = await ky.post('swarm/addrs', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await (await api.post('swarm/addrs', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams: options.searchParams - }).json() + })).json() return Object.keys(res.Addrs).map(id => ({ id, diff --git a/src/swarm/connect.js b/src/swarm/connect.js index f47ae6974..ae1f7361d 100644 --- a/src/swarm/connect.js +++ b/src/swarm/connect.js @@ -2,20 +2,18 @@ const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (addrs, options) => { +module.exports = configure(api => { + return async (addrs, options = {}) => { addrs = Array.isArray(addrs) ? addrs : [addrs] - options = options || {} - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) addrs.forEach(addr => searchParams.append('arg', addr)) - const res = await ky.post('swarm/connect', { + const res = await (await api.post('swarm/connect', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + })).json() return res.Strings || [] } diff --git a/src/swarm/disconnect.js b/src/swarm/disconnect.js index e83ca0dd4..2c6e81b50 100644 --- a/src/swarm/disconnect.js +++ b/src/swarm/disconnect.js @@ -2,20 +2,18 @@ const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async (addrs, options) => { +module.exports = configure(api => { + return async (addrs, options = {}) => { addrs = Array.isArray(addrs) ? addrs : [addrs] - options = options || {} - const searchParams = new URLSearchParams(options.searchParams) + const searchParams = new URLSearchParams(options) addrs.forEach(addr => searchParams.append('arg', `${addr}`)) - const res = await ky.post('swarm/disconnect', { + const res = await (await api.post('swarm/disconnect', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams - }).json() + })).json() return res.Strings || [] } diff --git a/src/swarm/localAddrs.js b/src/swarm/localAddrs.js index 41c32db2d..fee69cbf4 100644 --- a/src/swarm/localAddrs.js +++ b/src/swarm/localAddrs.js @@ -3,19 +3,13 @@ const multiaddr = require('multiaddr') const configure = require('../lib/configure') -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', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await (await api.post('swarm/addrs/local', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + })).json() return (res.Strings || []).map(a => multiaddr(a)) } diff --git a/src/swarm/peers.js b/src/swarm/peers.js index 8388af49f..7a815b9a8 100644 --- a/src/swarm/peers.js +++ b/src/swarm/peers.js @@ -3,22 +3,13 @@ const multiaddr = require('multiaddr') const configure = require('../lib/configure') -module.exports = configure(({ ky }) => { - return async options => { - options = options || {} - - 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) - - const res = await ky.post('swarm/peers', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await (await api.post('swarm/peers', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams - }).json() + searchParams: options + })).json() return (res.Peers || []).map(peer => { const info = {} diff --git a/src/update.js b/src/update.js index 91bea6f7f..224b0dba0 100644 --- a/src/update.js +++ b/src/update.js @@ -2,15 +2,12 @@ const configure = require('./lib/configure') -module.exports = configure(({ ky }) => { - return options => { - options = options || {} - - return ky.post('update', { +module.exports = configure(api => { + return async (options = {}) => { + return (await api.post('update', { timeout: options.timeout, signal: options.signal, - headers: options.headers, - searchParams: options.searchParams - }).text() + searchParams: options + })).text() } }) diff --git a/src/version.js b/src/version.js index 8faee147a..c75a9ca8d 100644 --- a/src/version.js +++ b/src/version.js @@ -1,18 +1,15 @@ 'use strict' -const configure = require('./lib/configure') const toCamel = require('./lib/object-to-camel') +const configure = require('./lib/configure') -module.exports = configure(({ ky }) => { - return async options => { - options = options || {} - - const res = await ky.post('version', { +module.exports = configure(api => { + return async (options = {}) => { + const res = await (await api.post('version', { timeout: options.timeout, signal: options.signal, - headers: options.headers, searchParams: options.searchParams - }).json() + })).json() return toCamel(res) } diff --git a/test/constructor.spec.js b/test/constructor.spec.js index acffb11e7..e0d188d0a 100644 --- a/test/constructor.spec.js +++ b/test/constructor.spec.js @@ -5,6 +5,8 @@ const multiaddr = require('multiaddr') const { expect } = require('interface-ipfs-core/src/utils/mocha') const f = require('./utils/factory')() const ipfsClient = require('../src/index.js') +const globalThis = require('ipfs-utils/src/globalthis') +const { isBrowser } = require('ipfs-utils/src/env') describe('ipfs-http-client constructor tests', () => { describe('parameter permuations', () => { @@ -82,13 +84,7 @@ describe('ipfs-http-client constructor tests', () => { const port = '9999' const apiPath = '/future/api/v1/' 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() + expectConfig(ipfs, { host, port, apiPath }) }) }) @@ -118,8 +114,18 @@ 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.protocol).to.equal(protocol || 'http') - expect(conf['api-path']).to.equal(apiPath || '/api/v0') + if (protocol) { + protocol = protocol + ':' + } + if (isBrowser) { + expect(conf.host).to.be.oneOf([host, globalThis.location.hostname, '']) + expect(conf.port).to.be.oneOf([port, globalThis.location.port, '80']) + expect(conf.protocol).to.equal(protocol || 'http:') + expect(conf.pathname).to.equal(apiPath || '/api/v0') + } else { + expect(conf.host).to.be.oneOf([host, 'localhost', '']) + expect(conf.port).to.be.oneOf([port, '5001', '80']) + expect(conf.protocol).to.equal(protocol || 'http:') + expect(conf.pathname).to.equal(apiPath || '/api/v0') + } } diff --git a/test/dag.spec.js b/test/dag.spec.js index fec5229f6..1343961f8 100644 --- a/test/dag.spec.js +++ b/test/dag.spec.js @@ -3,6 +3,7 @@ 'use strict' +const { Buffer } = require('buffer') const { expect } = require('interface-ipfs-core/src/utils/mocha') const { DAGNode } = require('ipld-dag-pb') const CID = require('cids') diff --git a/test/endpoint-config.spec.js b/test/endpoint-config.spec.js index a44de3e1c..f1719d895 100644 --- a/test/endpoint-config.spec.js +++ b/test/endpoint-config.spec.js @@ -11,8 +11,8 @@ describe('.getEndpointConfig', () => { const endpoint = ipfs.getEndpointConfig() expect(endpoint.host).to.equal('127.0.0.1') - expect(endpoint.protocol).to.equal('https') - expect(endpoint['api-path']).to.equal('/ipfs/api') + expect(endpoint.protocol).to.equal('https:') + expect(endpoint.pathname).to.equal('/ipfs/api/') expect(endpoint.port).to.equal('5501') }) }) diff --git a/test/files-mfs.spec.js b/test/files-mfs.spec.js index 4d7e0ea83..87b5f2116 100644 --- a/test/files-mfs.spec.js +++ b/test/files-mfs.spec.js @@ -7,7 +7,7 @@ const loadFixture = require('aegir/fixtures') const mh = require('multihashes') const all = require('it-all') const pipe = require('it-pipe') -const { TimeoutError } = require('ky-universal') +const API = require('../src/lib/core') const f = require('./utils/factory')() @@ -89,7 +89,7 @@ describe('.files (the MFS API part)', function () { // 'ipfs.object.get()' should timeout because content wasn't actually added return expect(ipfs.object.get(files[0].cid, { timeout: 2000 })) - .to.be.rejectedWith(TimeoutError) + .to.be.rejectedWith(API.TimeoutError) }) it('.add with options', async () => { diff --git a/test/fixtures/test-folder/add b/test/fixtures/test-folder/add index ce7fb7cc8..6c64533e0 100644 --- a/test/fixtures/test-folder/add +++ b/test/fixtures/test-folder/add @@ -1,5 +1,6 @@ 'use strict' +const { Buffer } = require('buffer') const ipfs = require('../src')('localhost', 5001) const f1 = 'Hello' diff --git a/test/get.spec.js b/test/get.spec.js index 5c64e3bf2..a8371033f 100644 --- a/test/get.spec.js +++ b/test/get.spec.js @@ -5,6 +5,7 @@ const { expect } = require('interface-ipfs-core/src/utils/mocha') const loadFixture = require('aegir/fixtures') +const { Buffer } = require('buffer') const all = require('it-all') const concat = require('it-concat') diff --git a/test/interface.spec.js b/test/interface.spec.js index 53492cac7..e3e4df903 100644 --- a/test/interface.spec.js +++ b/test/interface.spec.js @@ -348,7 +348,38 @@ describe('interface-ipfs-core tests', () => { ] }) - tests.object(commonFactory) + tests.object(commonFactory, { + skip: [ + { + name: 'should get data by base58 encoded multihash string', + reason: 'FIXME go-ipfs throws invalid encoding: base58' + }, + { + name: 'should get object by base58 encoded multihash', + reason: 'FIXME go-ipfs throws invalid encoding: base58' + }, + { + name: 'should get object by base58 encoded multihash', + reason: 'FIXME go-ipfs throws invalid encoding: base58' + }, + { + name: 'should get object by base58 encoded multihash string', + reason: 'FIXME go-ipfs throws invalid encoding: base58' + }, + { + name: 'should get links by base58 encoded multihash', + reason: 'FIXME go-ipfs throws invalid encoding: base58' + }, + { + name: 'should get links by base58 encoded multihash string', + reason: 'FIXME go-ipfs throws invalid encoding: base58' + }, + { + name: 'should put a Protobuf encoded Buffer', + reason: 'FIXME go-ipfs throws invalid encoding: protobuf' + } + ] + }) tests.pin(commonFactory) diff --git a/test/lib.configure.spec.js b/test/lib.configure.spec.js deleted file mode 100644 index 550165035..000000000 --- a/test/lib.configure.spec.js +++ /dev/null @@ -1,80 +0,0 @@ -/* eslint-env mocha, browser */ -'use strict' - -const { expect } = require('interface-ipfs-core/src/utils/mocha') -const Multiaddr = require('multiaddr') -const { isBrowser, isWebWorker } = require('ipfs-utils/src/env') -const configure = require('../src/lib/configure') - -describe('lib/configure', () => { - it('should accept no config', () => { - configure(config => { - if (isBrowser || isWebWorker) { - expect(config.apiAddr).to.eql(location.origin) - } else { - expect(config.apiAddr).to.eql('http://localhost:5001') - } - })() - }) - - it('should accept string multiaddr', () => { - const input = '/ip4/127.0.0.1/tcp/5001' - configure(config => { - expect(config.apiAddr).to.eql('http://127.0.0.1:5001') - })(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/tcp/5001') - configure(config => { - expect(config.apiAddr).to.eql('http://127.0.0.1:5001') - })(input) - }) - - it('should accept object with protocol, host and port', () => { - const input = { protocol: 'https', host: 'ipfs.io', port: 138 } - configure(config => { - expect(config.apiAddr).to.eql('https://ipfs.io:138') - })(input) - }) - - it('should accept object with protocol only', () => { - const input = { protocol: 'https' } - configure(config => { - if (isBrowser || isWebWorker) { - expect(config.apiAddr).to.eql(`https://${location.host}`) - } else { - expect(config.apiAddr).to.eql('https://localhost:5001') - } - })(input) - }) - - it('should accept object with host only', () => { - const input = { host: 'ipfs.io' } - configure(config => { - if (isBrowser || isWebWorker) { - expect(config.apiAddr).to.eql(`http://ipfs.io:${location.port}`) - } else { - expect(config.apiAddr).to.eql('http://ipfs.io:5001') - } - })(input) - }) - - it('should accept object with port only', () => { - const input = { port: 138 } - configure(config => { - if (isBrowser || isWebWorker) { - expect(config.apiAddr).to.eql(`http://${location.hostname}:138`) - } else { - expect(config.apiAddr).to.eql('http://localhost:138') - } - })(input) - }) -}) diff --git a/test/lib.error-handler.spec.js b/test/lib.error-handler.spec.js index c39e3040d..9804ccdd4 100644 --- a/test/lib.error-handler.spec.js +++ b/test/lib.error-handler.spec.js @@ -2,14 +2,14 @@ 'use strict' const { expect } = require('interface-ipfs-core/src/utils/mocha') -const { HTTPError } = require('ky-universal') const throwsAsync = require('./utils/throws-async') -const errorHandler = require('../src/lib/error-handler') +const { errorHandler, HTTPError } = require('../src/lib/core') describe('lib/error-handler', () => { it('should parse json error response', async () => { const res = { ok: false, + statusText: 'test', headers: { get: () => 'application/json' }, json: () => Promise.resolve({ Message: 'boom', @@ -19,7 +19,7 @@ describe('lib/error-handler', () => { status: 500 } - const err = await throwsAsync(errorHandler(null, null, res)) + const err = await throwsAsync(errorHandler(res)) expect(err instanceof HTTPError).to.be.true() expect(err.message).to.eql('boom') @@ -34,7 +34,7 @@ describe('lib/error-handler', () => { status: 500 } - const err = await throwsAsync(errorHandler(null, null, res)) + const err = await throwsAsync(errorHandler(res)) expect(err instanceof HTTPError).to.be.true() }) @@ -46,7 +46,7 @@ describe('lib/error-handler', () => { status: 500 } - const err = await throwsAsync(errorHandler(null, null, res)) + const err = await throwsAsync(errorHandler(res)) expect(err instanceof HTTPError).to.be.true() }) }) diff --git a/test/log.spec.js b/test/log.spec.js index cfa18582c..b408f7551 100644 --- a/test/log.spec.js +++ b/test/log.spec.js @@ -4,6 +4,7 @@ const { expect } = require('interface-ipfs-core/src/utils/mocha') const all = require('it-all') +const { Buffer } = require('buffer') const f = require('./utils/factory')() describe('.log', function () { diff --git a/test/request-api.spec.js b/test/request-api.spec.js index 1767b5914..3330ce432 100644 --- a/test/request-api.spec.js +++ b/test/request-api.spec.js @@ -3,6 +3,7 @@ const { expect } = require('interface-ipfs-core/src/utils/mocha') const { isNode } = require('ipfs-utils/src/env') +const { Buffer } = require('buffer') const ipfsClient = require('../src/index.js') describe('\'deal with HTTP weirdness\' tests', () => {