diff --git a/.aegir.js b/.aegir.js index 31235b7c..8d0b07ca 100644 --- a/.aegir.js +++ b/.aegir.js @@ -1,8 +1,25 @@ 'use strict' const createServer = require('./src').createServer +const { findBin } = require('./src/utils') -const server = createServer() // using defaults +const server = createServer(null, { + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + }, + ipfsHttpModule: { + path: require.resolve('ipfs-http-client'), + ref: require('ipfs-http-client') + } +}, { + go: { + ipfsBin: findBin('go', true) + }, + js: { + ipfsBin: findBin('js', true) + } +}) // using defaults module.exports = { bundlesize: { maxSize: '35kB' }, karma: { diff --git a/src/endpoint/routes.js b/src/endpoint/routes.js index 8cbb650a..57e5d5b1 100644 --- a/src/endpoint/routes.js +++ b/src/endpoint/routes.js @@ -20,7 +20,7 @@ const badRequest = err => { } else { msg = err.message } - debug(msg) + debug(err) throw boom.badRequest(msg) } diff --git a/src/factory.js b/src/factory.js index 561a9656..4ab990a2 100644 --- a/src/factory.js +++ b/src/factory.js @@ -1,7 +1,7 @@ 'use strict' const merge = require('merge-options').bind({ ignoreUndefined: true }) const kyOriginal = require('ky-universal').default -const { tmpDir, findBin } = require('./utils') +const { tmpDir } = require('./utils') const { isNode } = require('ipfs-utils/src/env') const ControllerDaemon = require('./ipfsd-daemon') const ControllerRemote = require('./ipfsd-client') @@ -77,27 +77,11 @@ class Factory { const opts = { json: { ...options, - ipfsModule: undefined, - ipfsHttpModule: undefined, // avoid recursive spawning remote: false } } - if (options.ipfsModule && options.ipfsModule.path) { - opts.json.ipfsModule = { - path: options.ipfsModule.path - // n.b. no ref property - do not send code refs over http - } - } - - if (options.ipfsHttpModule && options.ipfsHttpModule.path) { - opts.json.ipfsHttpModule = { - path: options.ipfsHttpModule.path - // n.b. no ref property - do not send code refs over http - } - } - const res = await ky.post( `${options.endpoint}/spawn`, opts @@ -121,36 +105,6 @@ class Factory { options ) - // conditionally include ipfs based on which type of daemon we will spawn when none has been specified - if ((opts.type === 'js' || opts.type === 'proc') && !opts.ipfsModule) { - opts.ipfsModule = {} - } - - if (opts.ipfsModule) { - if (!opts.ipfsModule.path) { - opts.ipfsModule.path = require.resolve('ipfs') - } - - if (!opts.ipfsModule.ref) { - opts.ipfsModule.ref = require('ipfs') - } - } - - // only include the http api client if it has not been specified as an option - // for example if we are testing the http api client itself we should not try - // to require 'ipfs-http-client' - if (!opts.ipfsHttpModule) { - opts.ipfsHttpModule = { - path: require.resolve('ipfs-http-client'), - ref: require('ipfs-http-client') - } - } - - // find ipfs binary if not specified - if (opts.type !== 'proc' && !opts.ipfsBin) { - opts.ipfsBin = findBin(opts.type, true) - } - // IPFS options defaults const ipfsOptions = merge( { diff --git a/src/index.js b/src/index.js index 0103a7b4..41aea8fc 100644 --- a/src/index.js +++ b/src/index.js @@ -32,13 +32,18 @@ const createController = (options) => { * * @param {(Object|number)} options - Configuration options or just the port. * @param {number} options.port - Port to start the server on. + * @param {ControllerOptions} factoryOptions + * @param {ControllerOptionsOverrides} factoryOverrides * @returns {Server} */ -const createServer = (options) => { +const createServer = (options, factoryOptions = {}, factoryOverrides = {}) => { if (typeof options === 'number') { options = { port: options } } - return new Server(options, createFactory) + + return new Server(options, () => { + return createFactory(factoryOptions, factoryOverrides) + }) } module.exports = { diff --git a/src/ipfsd-client.js b/src/ipfsd-client.js index 4c27cf65..86729661 100644 --- a/src/ipfsd-client.js +++ b/src/ipfsd-client.js @@ -34,8 +34,9 @@ class Client { this.disposable = remoteState.disposable this.clean = remoteState.clean this.api = null - this.apiAddr = this._setApi(remoteState.apiAddr) - this.gatewayAddr = this._setGateway(remoteState.gatewayAddr) + + this._setApi(remoteState.apiAddr) + this._setGateway(remoteState.gatewayAddr) } /** diff --git a/test/browser.utils.js b/test/browser.utils.js index 6e72ac86..e3c211bc 100644 --- a/test/browser.utils.js +++ b/test/browser.utils.js @@ -36,7 +36,11 @@ describe('utils browser version', function () { test: true, type: 'proc', disposable: false, - ipfsOptions: { repo: 'ipfs_test_remove' } + ipfsOptions: { repo: 'ipfs_test_remove' }, + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + } }) await ctl.init() await ctl.start() @@ -51,7 +55,16 @@ describe('utils browser version', function () { describe('repoExists', () => { it('should resolve true when repo exists', async () => { const f = createFactory({ test: true }) - const node = await f.spawn({ type: 'proc', ipfsOptions: { repo: 'ipfs_test' } }) + const node = await f.spawn({ + type: 'proc', + ipfsOptions: { + repo: 'ipfs_test' + }, + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + } + }) expect(await repoExists('ipfs_test')).to.be.true() await node.stop() }) diff --git a/test/controller.spec.js b/test/controller.spec.js index 42f52690..3dfa6a0d 100644 --- a/test/controller.spec.js +++ b/test/controller.spec.js @@ -6,23 +6,84 @@ const merge = require('merge-options') const dirtyChai = require('dirty-chai') const chaiPromise = require('chai-as-promised') const { createFactory, createController } = require('../src') -const { repoExists } = require('../src/utils') +const { repoExists, findBin } = require('../src/utils') const { isBrowser, isWebWorker } = require('ipfs-utils/src/env') const expect = chai.expect chai.use(dirtyChai) chai.use(chaiPromise) -const types = [ - { type: 'js', test: true, ipfsOptions: { init: false, start: false } }, - { type: 'go', test: true, ipfsOptions: { init: false, start: false } }, - { type: 'proc', test: true, ipfsOptions: { init: false, start: false } }, - { type: 'js', remote: true, test: true, ipfsOptions: { init: false, start: false } }, - { type: 'go', remote: true, test: true, ipfsOptions: { init: false, start: false } } -] +const defaultOpts = { + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + }, + ipfsHttpModule: { + path: require.resolve('ipfs-http-client'), + ref: require('ipfs-http-client') + }, + ipfsBin: findBin('js', true) +} + +const types = [{ + ...defaultOpts, + type: 'js', + test: true, + ipfsOptions: { + init: false, + start: false + } +}, { + ...defaultOpts, + ipfsBin: findBin('go', true), + type: 'go', + test: true, + ipfsOptions: { + init: false, + start: false + } +}, { + ...defaultOpts, + type: 'proc', + test: true, + ipfsOptions: { + init: false, + start: false + } +}, { + ...defaultOpts, + type: 'js', + remote: true, + test: true, + ipfsOptions: { + init: false, + start: false + } +}, { + ...defaultOpts, + ipfsBin: findBin('go', true), + type: 'go', + remote: true, + test: true, + ipfsOptions: { + init: false, + start: false + } +}] describe('Controller API', () => { - const factory = createFactory({ test: true }) + const factory = createFactory({ + test: true, + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + }, + ipfsHttpModule: { + path: require.resolve('ipfs-http-client'), + ref: require('ipfs-http-client') + }, + ipfsBin: findBin('js', true) + }) before(() => factory.spawn({ type: 'js' })) @@ -48,7 +109,11 @@ describe('Controller API', () => { describe('should work with a initialized repo', () => { for (const opts of types) { it(`type: ${opts.type} remote: ${Boolean(opts.remote)}`, async () => { - const ctl = await createController(merge(opts, { ipfsOptions: { repo: factory.controllers[0].path } })) + const ctl = await createController(merge(opts, { + ipfsOptions: { + repo: factory.controllers[0].path + } + })) await ctl.init() expect(ctl.initialized).to.be.true() @@ -130,8 +195,11 @@ describe('Controller API', () => { return this.skip() // browser in proc can't attach to running node } const ctl = await createController(merge( - opts, - { ipfsOptions: { repo: factory.controllers[0].path } } + opts, { + ipfsOptions: { + repo: factory.controllers[0].path + } + } )) await ctl.init() @@ -184,10 +252,7 @@ describe('Controller API', () => { const f = createFactory() const ctl = await f.spawn(merge(opts, { disposable: false, - test: true, - ipfsOptions: { - repo: await f.tmpDir() - } + test: true })) await ctl.init() diff --git a/test/create.spec.js b/test/create.spec.js index 95b16953..fa5b7803 100644 --- a/test/create.spec.js +++ b/test/create.spec.js @@ -8,13 +8,26 @@ const { createFactory, createController, createServer } = require('../src') const Client = require('../src/ipfsd-client') const Daemon = require('../src/ipfsd-daemon') const Proc = require('../src/ipfsd-in-proc') +const { findBin } = require('../src/utils') const expect = chai.expect chai.use(dirtyChai) describe('`createController` should return the correct class', () => { it('for type `js` ', async () => { - const f = await createController({ type: 'js', disposable: false }) + const f = await createController({ + type: 'js', + disposable: false, + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + }, + ipfsHttpModule: { + path: require.resolve('ipfs-http-client'), + ref: require('ipfs-http-client') + }, + ipfsBin: findBin('js', true) + }) if (!isNode) { expect(f).to.be.instanceOf(Client) @@ -23,7 +36,15 @@ describe('`createController` should return the correct class', () => { } }) it('for type `go` ', async () => { - const f = await createController({ type: 'go', disposable: false }) + const f = await createController({ + type: 'go', + disposable: false, + ipfsHttpModule: { + path: require.resolve('ipfs-http-client'), + ref: require('ipfs-http-client') + }, + ipfsBin: findBin('go', true) + }) if (!isNode) { expect(f).to.be.instanceOf(Client) @@ -38,19 +59,61 @@ describe('`createController` should return the correct class', () => { }) it('for remote', async () => { - const f = await createController({ remote: true, disposable: false }) + const f = await createController({ + remote: true, + disposable: false, + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + }, + ipfsHttpModule: { + path: require.resolve('ipfs-http-client'), + ref: require('ipfs-http-client') + }, + ipfsBin: findBin('js', true) + }) expect(f).to.be.instanceOf(Client) }) }) -const types = [ - { type: 'js', test: true }, - { type: 'go', test: true }, - { type: 'proc', test: true }, - { type: 'js', test: true, remote: true }, - { type: 'go', test: true, remote: true } -] +const defaultOps = { + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + }, + ipfsHttpModule: { + path: require.resolve('ipfs-http-client'), + ref: require('ipfs-http-client') + }, + ipfsBin: findBin('js', true) +} + +const types = [{ + ...defaultOps, + type: 'js', + test: true +}, { + ...defaultOps, + ipfsBin: findBin('go', true), + type: 'go', + test: true +}, { + ...defaultOps, + type: 'proc', + test: true +}, { + ...defaultOps, + type: 'js', + test: true, + remote: true +}, { + ...defaultOps, + ipfsBin: findBin('go', true), + type: 'go', + test: true, + remote: true +}] describe('`createController` should return daemon with peerId when started', () => { for (const opts of types) { @@ -105,7 +168,9 @@ describe('`createController({test: true})` should return daemon with correct con describe('`createFactory({test: true})` should return daemon with test profile', () => { for (const opts of types) { it(`type: ${opts.type} remote: ${Boolean(opts.remote)}`, async () => { - const factory = createFactory({ test: true }) + const factory = createFactory({ + test: true + }) const node = await factory.spawn(opts) expect(await node.api.config.get('Bootstrap')).to.be.empty() await factory.clean() diff --git a/test/factory.spec.js b/test/factory.spec.js index 61c6c58e..7d0ccdc8 100644 --- a/test/factory.spec.js +++ b/test/factory.spec.js @@ -5,17 +5,48 @@ const chai = require('chai') const dirtyChai = require('dirty-chai') const { isNode } = require('ipfs-utils/src/env') const { createFactory } = require('../src') +const { findBin } = require('../src/utils') const expect = chai.expect chai.use(dirtyChai) -const types = [ - { type: 'js', test: true }, - { type: 'go', test: true }, - { type: 'proc', test: true }, - { type: 'js', remote: true, test: true }, - { type: 'go', remote: true, test: true } -] +const defaultOps = { + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + }, + ipfsHttpModule: { + path: require.resolve('ipfs-http-client'), + ref: require('ipfs-http-client') + }, + ipfsBin: findBin('js', true) +} + +const types = [{ + ...defaultOps, + type: 'js', + test: true +}, { + ...defaultOps, + ipfsBin: findBin('go', true), + type: 'go', + test: true +}, { + ...defaultOps, + type: 'proc', + test: true +}, { + ...defaultOps, + type: 'js', + remote: true, + test: true +}, { + ...defaultOps, + ipfsBin: findBin('go', true), + type: 'go', + remote: true, + test: true +}] describe('`Factory tmpDir()` should return correct temporary dir', () => { for (const opts of types) { @@ -58,7 +89,19 @@ describe('`Factory spawn()` ', () => { for (const opts of types) { it(`type: ${opts.type} remote: ${Boolean(opts.remote)}`, async () => { const factory = await createFactory({ test: true }) - const ctl = await factory.spawn({ type: opts.type, remote: opts.remote }) + const ctl = await factory.spawn({ + type: opts.type, + remote: opts.remote, + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + }, + ipfsHttpModule: { + path: require.resolve('ipfs-http-client'), + ref: require('ipfs-http-client') + }, + ipfsBin: findBin('js', true) + }) expect(ctl).to.exist() expect(ctl.opts.test).to.be.true() await ctl.stop() diff --git a/test/node.routes.js b/test/node.routes.js index 00874d94..5026d59d 100644 --- a/test/node.routes.js +++ b/test/node.routes.js @@ -16,7 +16,19 @@ describe('routes', () => { before(() => { server = new Hapi.Server({ port: 43134 }) - routes(server, createFactory) + routes(server, () => { + return createFactory({ + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + }, + ipfsHttpModule: { + path: require.resolve('ipfs-http-client'), + ref: require('ipfs-http-client') + }, + ipfsBin: require.resolve('ipfs/src/cli/bin.js') + }) + }) }) after(async () => { diff --git a/test/node.utils.js b/test/node.utils.js index 6b7e6e96..312d66bc 100644 --- a/test/node.utils.js +++ b/test/node.utils.js @@ -44,7 +44,18 @@ describe('utils node version', function () { expect(checkForRunningApi()).to.be.null() }) it('should return path to api with running node', async () => { - const node = await createController({ test: true }) + const node = await createController({ + test: true, + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + }, + ipfsHttpModule: { + path: require.resolve('ipfs-http-client'), + ref: require('ipfs-http-client') + }, + ipfsBin: require.resolve('ipfs/src/cli/bin.js') + }) expect(checkForRunningApi(node.path)).to.be.contain('/ip4/127.0.0.1/tcp/') await node.stop() }) @@ -57,7 +68,18 @@ describe('utils node version', function () { }) it('removeRepo should work', async () => { - const f = createFactory({ test: true }) + const f = createFactory({ + test: true, + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + }, + ipfsHttpModule: { + path: require.resolve('ipfs-http-client'), + ref: require('ipfs-http-client') + }, + ipfsBin: require.resolve('ipfs/src/cli/bin.js') + }) const dir = await f.tmpDir() const node = await f.spawn({ type: 'proc', @@ -73,7 +95,19 @@ describe('utils node version', function () { describe('repoExists', () => { it('should resolve true when repo exists', async () => { - const node = await createController({ type: 'proc', test: true }) + const node = await createController({ + type: 'proc', + test: true, + ipfsModule: { + path: require.resolve('ipfs'), + ref: require('ipfs') + }, + ipfsHttpModule: { + path: require.resolve('ipfs-http-client'), + ref: require('ipfs-http-client') + }, + ipfsBin: require.resolve('ipfs/src/cli/bin.js') + }) expect(await repoExists(node.path)).to.be.true() await node.stop() })