From d1e99e784184c6b9fabf03b423782656ef51e070 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Wed, 6 Mar 2019 20:23:44 +0000 Subject: [PATCH] refactor: export types and utilities statically (#951) Allows users to access these additional types and utilities without having to create an instance of the client first. resolves #902 BREAKING CHANGE: `ipfs.util.isIPFS` has moved to a static export and should be accessed via `const { isIPFS } = require('ipfs-http-client')`. The modules available under `ipfs.types.*` have also become static exports. `ipfs.util.crypto` has been removed as it is not a dependency of `ipfs-http-client` so reduces the bundle size. If you need to use libp2p crypto primitives then please see the [js-libp2p-crypto](https://github.com/libp2p/js-libp2p-crypto) project for info on how to use it in your project. Finally `ipfs.util.getEndpointConfig` is now a direct instance method, `ipfs.getEndpointConfig` License: MIT Signed-off-by: Alan Shaw --- README.md | 47 ++++++++------------ examples/bundle-browserify/index.js | 4 +- examples/bundle-webpack/src/App.js | 6 +-- src/{util => }/get-endpoint-config.js | 0 src/index.js | 9 +++- src/utils/load-commands.js | 29 ++++-------- test/constructor.spec.js | 4 +- test/endpoint-config.spec.js | 46 +++++++++++++++++++ test/exports.spec.js | 29 ++++++++++++ test/interface.spec.js | 4 -- test/util.spec.js | 64 --------------------------- 11 files changed, 117 insertions(+), 125 deletions(-) rename src/{util => }/get-endpoint-config.js (100%) create mode 100644 test/endpoint-config.spec.js create mode 100644 test/exports.spec.js delete mode 100644 test/util.spec.js diff --git a/README.md b/README.md index f8bb44c808..f4982baa8d 100644 --- a/README.md +++ b/README.md @@ -348,41 +348,32 @@ This means: - See https://github.com/ipfs/js-ipfs for details on pubsub in js-ipfs -#### Domain data types +#### Instance utils -A set of data types are exposed directly from the IPFS instance under `ipfs.types`. That way you're not required to import/require the following. +- `ipfs.getEndpointConfig()` -- [`ipfs.types.Buffer`](https://www.npmjs.com/package/buffer) -- [`ipfs.types.PeerId`](https://github.com/libp2p/js-peer-id) -- [`ipfs.types.PeerInfo`](https://github.com/libp2p/js-peer-info) -- [`ipfs.types.multiaddr`](https://github.com/multiformats/js-multiaddr) -- [`ipfs.types.multibase`](https://github.com/multiformats/multibase) -- [`ipfs.types.multihash`](https://github.com/multiformats/js-multihash) -- [`ipfs.types.CID`](https://github.com/ipld/js-cid) +Call this on your client instance to return an object containing the `host`, `port`, `protocol` and `api-path`. -#### Extra (util) functions +#### Static types and utils -Adding to the methods defined by [`interface-ipfs-core`](https://github.com/ipfs/interface-ipfs-core), `js-ipfs-http-client` exposes a set of extra utility methods. These utility functions are scoped behind the `ipfs.util`. +Aside from the default export, `ipfs-http-client` exports various types and utilities that are included in the bundle: -Complete documentation for these methods is coming with: https://github.com/ipfs/js-ipfs-http-client/pull/305 +- [`isIPFS`](https://www.npmjs.com/package/is-ipfs) +- [`Buffer`](https://www.npmjs.com/package/buffer) +- [`PeerId`](https://www.npmjs.com/package/peer-id) +- [`PeerInfo`](https://www.npmjs.com/package/peer-info) +- [`multiaddr`](https://www.npmjs.com/package/multiaddr) +- [`multibase`](https://www.npmjs.com/package/multibase) +- [`multihash`](https://www.npmjs.com/package/multihash) +- [`CID`](https://www.npmjs.com/package/cids) -##### Get endpoint configuration (host and port) +These can be accessed like this, for example: -> `ipfs.util.getEndpointConfig()` - -This returns an object containing the `host`, `port` and `protocol` - -##### Get libp2p crypto primitives - -> `ipfs.util.crypto` - -This contains an object with the crypto primitives - -##### Get is-ipfs utilities - -> `ipfs.util.isIPFS` - -This contains an object with the is-ipfs utilities to help identifying IPFS resources +```js +const { CID } = require('ipfs-http-client') +// ...or from an es-module: +import { CID } from 'ipfs-http-client' +``` ## Development diff --git a/examples/bundle-browserify/index.js b/examples/bundle-browserify/index.js index 1be85b9d9c..b0bc9f15e7 100644 --- a/examples/bundle-browserify/index.js +++ b/examples/bundle-browserify/index.js @@ -6,7 +6,7 @@ var ipfs = IPFS() function store () { var toStore = document.getElementById('source').value - ipfs.files.add(Buffer.from(toStore), function (err, res) { + ipfs.add(Buffer.from(toStore), function (err, res) { if (err || !res) { return console.error('ipfs add error', err, res) } @@ -21,7 +21,7 @@ function store () { } function display (hash) { - ipfs.files.cat(hash, function (err, res) { + ipfs.cat(hash, function (err, res) { if (err || !res) { return console.error('ipfs cat error', err, res) } diff --git a/examples/bundle-webpack/src/App.js b/examples/bundle-webpack/src/App.js index 155c6897e3..06bf819918 100644 --- a/examples/bundle-webpack/src/App.js +++ b/examples/bundle-webpack/src/App.js @@ -28,15 +28,15 @@ class App extends React.Component { ipfs.add([Buffer.from(stringToUse)], (err, res) => { if (err) throw err const hash = res[0].hash - this.setState({added_file_hash: hash}) + this.setState({ added_file_hash: hash }) ipfs.cat(hash, (err, data) => { if (err) throw err - this.setState({added_file_contents: data.toString()}) + this.setState({ added_file_contents: data.toString() }) }) }) } render () { - return
+ return

Everything is working!

Your ID is {this.state.id}

Your IPFS version is {this.state.version}

diff --git a/src/util/get-endpoint-config.js b/src/get-endpoint-config.js similarity index 100% rename from src/util/get-endpoint-config.js rename to src/get-endpoint-config.js diff --git a/src/index.js b/src/index.js index 5be787427b..2423091c2c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,13 @@ 'use strict' /* global self */ +const isIPFS = require('is-ipfs') +const CID = require('cids') const multiaddr = require('multiaddr') +const multibase = require('multibase') +const multihash = require('multihashes') +const PeerId = require('peer-id') +const PeerInfo = require('peer-info') const loadCommands = require('./utils/load-commands') const getConfig = require('./utils/default-config') const sendRequest = require('./utils/send-request') @@ -39,7 +45,6 @@ function ipfsClient (hostOrMultiaddr, port, opts) { const requestAPI = sendRequest(config) const cmds = loadCommands(requestAPI, config) cmds.send = requestAPI - cmds.Buffer = Buffer // Added buffer in types (this should be removed once a breaking change is release) return cmds } @@ -54,3 +59,5 @@ function toHostAndPort (multiaddr) { } module.exports = ipfsClient + +Object.assign(module.exports, { isIPFS, Buffer, CID, multiaddr, multibase, multihash, PeerId, PeerInfo }) diff --git a/src/utils/load-commands.js b/src/utils/load-commands.js index 4d203defc6..030aef5abe 100644 --- a/src/utils/load-commands.js +++ b/src/utils/load-commands.js @@ -1,7 +1,7 @@ 'use strict' function requireCommands () { - const cmds = { + return { // Files Regular (not MFS) add: require('../files-regular/add'), addReadableStream: require('../files-regular/add-readable-stream'), @@ -19,6 +19,9 @@ function requireCommands () { lsReadableStream: require('../files-regular/ls-readable-stream'), lsPullStream: require('../files-regular/ls-pull-stream'), + // Files MFS (Mutable Filesystem) + files: require('../files-mfs'), + // Block block: require('../block'), bitswap: require('../bitswap'), @@ -50,30 +53,14 @@ function requireCommands () { refs: require('../refs'), repo: require('../repo'), stop: require('../stop'), + shutdown: require('../stop'), stats: require('../stats'), update: require('../update'), version: require('../version'), - types: require('../types'), - resolve: require('../resolve') - } - - // shutdown is an alias for stop - cmds.shutdown = cmds.stop - - // Files MFS (Mutable Filesystem) - cmds.files = (send) => { - return require('../files-mfs')(send) + resolve: require('../resolve'), + // ipfs-http-client instance + getEndpointConfig: (send, config) => require('../get-endpoint-config')(config) } - - cmds.util = (send, config) => { - return { - getEndpointConfig: require('../util/get-endpoint-config')(config), - crypto: require('libp2p-crypto'), - isIPFS: require('is-ipfs') - } - } - - return cmds } function loadCommands (send, config) { diff --git a/test/constructor.spec.js b/test/constructor.spec.js index ab3ad26a25..68e1339c82 100644 --- a/test/constructor.spec.js +++ b/test/constructor.spec.js @@ -1,4 +1,4 @@ -/* eslint-env mocha */ +/* eslint-env mocha, browser */ 'use strict' const multiaddr = require('multiaddr') @@ -114,7 +114,7 @@ function clientWorks (client, done) { } function expectConfig (ipfs, { host, port, protocol, apiPath }) { - const conf = ipfs.util.getEndpointConfig() + const conf = ipfs.getEndpointConfig() expect(conf.host).to.equal(host || 'localhost') expect(conf.port).to.equal(port || '5001') expect(conf.protocol).to.equal(protocol || 'http') diff --git a/test/endpoint-config.spec.js b/test/endpoint-config.spec.js new file mode 100644 index 0000000000..8ff6532c7b --- /dev/null +++ b/test/endpoint-config.spec.js @@ -0,0 +1,46 @@ +/* eslint-env mocha */ +/* eslint max-nested-callbacks: ["error", 8] */ +'use strict' + +const chai = require('chai') +const dirtyChai = require('dirty-chai') +const expect = chai.expect +chai.use(dirtyChai) +const isNode = require('detect-node') + +const ipfsClient = require('../src') +const f = require('./utils/factory') + +describe('.getEndpointConfig', () => { + if (!isNode) { return } + + let ipfsd + let ipfs + + before(function (done) { + this.timeout(20 * 1000) // slow CI + + f.spawn({ initOptions: { bits: 1024, profile: 'test' } }, (err, _ipfsd) => { + expect(err).to.not.exist() + ipfsd = _ipfsd + ipfs = ipfsClient(_ipfsd.apiAddr) + done() + }) + }) + + after(function (done) { + this.timeout(10 * 1000) + if (!ipfsd) return done() + ipfsd.stop(done) + }) + + it('should return the endpoint configuration', function () { + const endpoint = ipfs.getEndpointConfig() + + expect(endpoint.host).to.equal('127.0.0.1') + expect(endpoint.protocol).to.equal('http') + expect(endpoint['api-path']).to.equal('/api/v0/') + // changes per test run so we just assert it exists. + expect(endpoint).to.have.property('port') + }) +}) diff --git a/test/exports.spec.js b/test/exports.spec.js new file mode 100644 index 0000000000..f1f813f696 --- /dev/null +++ b/test/exports.spec.js @@ -0,0 +1,29 @@ +/* eslint-env mocha, browser */ +'use strict' + +const isIPFS = require('is-ipfs') +const CID = require('cids') +const multiaddr = require('multiaddr') +const multibase = require('multibase') +const multihash = require('multihashes') +const PeerId = require('peer-id') +const PeerInfo = require('peer-info') +const chai = require('chai') +const dirtyChai = require('dirty-chai') +const expect = chai.expect +chai.use(dirtyChai) + +const IpfsHttpClient = require('../') + +describe('exports', () => { + it('should export the expected types and utilities', () => { + expect(IpfsHttpClient.isIPFS).to.equal(isIPFS) + expect(IpfsHttpClient.Buffer).to.equal(Buffer) + expect(IpfsHttpClient.CID).to.equal(CID) + expect(IpfsHttpClient.multiaddr).to.equal(multiaddr) + expect(IpfsHttpClient.multibase).to.equal(multibase) + expect(IpfsHttpClient.multihash).to.equal(multihash) + expect(IpfsHttpClient.PeerId).to.equal(PeerId) + expect(IpfsHttpClient.PeerInfo).to.equal(PeerInfo) + }) +}) diff --git a/test/interface.spec.js b/test/interface.spec.js index 5d87a2b918..3d7cb79709 100644 --- a/test/interface.spec.js +++ b/test/interface.spec.js @@ -282,8 +282,4 @@ describe('interface-ipfs-core tests', () => { } } })) - - tests.types(defaultCommonFactory) - - tests.util(defaultCommonFactory, { skip: { reason: 'FIXME currently failing' } }) }) diff --git a/test/util.spec.js b/test/util.spec.js deleted file mode 100644 index 9915c29400..0000000000 --- a/test/util.spec.js +++ /dev/null @@ -1,64 +0,0 @@ -/* eslint-env mocha */ -/* eslint max-nested-callbacks: ["error", 8] */ -'use strict' - -const chai = require('chai') -const dirtyChai = require('dirty-chai') -const expect = chai.expect -chai.use(dirtyChai) -const isNode = require('detect-node') - -const ipfsClient = require('../src') -const f = require('./utils/factory') - -describe('.util', () => { - if (!isNode) { return } - - let ipfsd - let ipfs - - before(function (done) { - this.timeout(20 * 1000) // slow CI - - f.spawn({ initOptions: { bits: 1024, profile: 'test' } }, (err, _ipfsd) => { - expect(err).to.not.exist() - ipfsd = _ipfsd - ipfs = ipfsClient(_ipfsd.apiAddr) - done() - }) - }) - - after(function (done) { - this.timeout(10 * 1000) - if (!ipfsd) return done() - ipfsd.stop(done) - }) - - describe('.getEndpointConfig', () => { - it('should return the endpoint configuration', function () { - const endpoint = ipfs.util.getEndpointConfig() - - expect(endpoint.host).to.equal('127.0.0.1') - expect(endpoint.protocol).to.equal('http') - expect(endpoint['api-path']).to.equal('/api/v0/') - // changes per test run so we just assert it exists. - expect(endpoint).to.have.property('port') - }) - }) - - describe('.crypto', () => { - it('should contain the crypto primitives object', function () { - const cripto = ipfs.util.crypto - - expect(cripto).to.exist() - }) - }) - - describe('.isIPFS', () => { - it('should contain the isIPFS utilities object', function () { - const isIPFS = ipfs.util.isIPFS - - expect(isIPFS).to.exist() - }) - }) -})