From 4073fb488e14edb04dcf03352cb7876221d24534 Mon Sep 17 00:00:00 2001 From: Hugo Dias Date: Sun, 7 Jun 2020 20:08:55 +0100 Subject: [PATCH 1/3] feat: add config.getAll This PR adds `ipfs.config.getAll(options?: Object)` and makes `key` in `ipfs.config.get(key: string, options?: object)` required. --- docs/core-api/CONFIG.md | 39 +++++++++++++++++-- .../interface-ipfs-core/src/config/get.js | 33 ++++++++++++++-- packages/ipfs-http-client/src/config/get.js | 10 ++--- .../ipfs-http-client/src/config/getAll.js | 20 ++++++++++ packages/ipfs-http-client/src/config/index.js | 1 + packages/ipfs/src/cli/commands/config/show.js | 2 +- packages/ipfs/src/core/components/config.js | 6 +-- 7 files changed, 94 insertions(+), 17 deletions(-) create mode 100644 packages/ipfs-http-client/src/config/getAll.js diff --git a/docs/core-api/CONFIG.md b/docs/core-api/CONFIG.md index bed36f0e40..fa909cf68c 100644 --- a/docs/core-api/CONFIG.md +++ b/docs/core-api/CONFIG.md @@ -1,10 +1,14 @@ # Config API -- [`ipfs.config.get([key,] [options])`](#ipfsconfiggetkey-options) +- [`ipfs.config.get(key, [options])`](#ipfsconfiggetkey-options) - [Parameters](#parameters) - [Options](#options) - [Returns](#returns) - [Example](#example) +- [`ipfs.config.getAll([options])`](#ipfsconfiggetkey-options) + - [Options](#options) + - [Returns](#returns) + - [Example](#example) - [`ipfs.config.set(key, value, [options])`](#ipfsconfigsetkey-value-options) - [Parameters](#parameters-1) - [Options](#options-1) @@ -26,7 +30,7 @@ - [Returns](#returns-4) - [Example](#example-4) -## `ipfs.config.get([key,] [options])` +## `ipfs.config.get(key, [options])` > Returns the currently being used config. If the daemon is off, it returns the stored config. @@ -34,7 +38,7 @@ | Name | Type | Description | | ---- | ---- | ----------- | -| key | `String` | The key of the value that should be fetched from the config file. If no key is passed, then the whole config will be returned. | +| key | `String` | The key of the value that should be fetched from the config file. | ### Options @@ -60,6 +64,35 @@ console.log(config) A great source of [examples][] can be found in the tests for this API. +## `ipfs.config.getAll([options])` + +> Returns the full config been used. If the daemon is off, it returns the stored config. + +### Options + +An optional object which may have the following keys: + +| Name | Type | Default | Description | +| ---- | ---- | ------- | ----------- | +| timeout | `Number` | `undefined` | A timeout in ms | +| signal | [AbortSignal][] | `undefined` | Can be used to cancel any long running requests started as a result of this call | + +### Returns + +| Type | Description | +| -------- | -------- | +| `Promise` | An object containing the configuration of the IPFS node | + +### Example + +```JavaScript +const config = await ipfs.config.getAll() +console.log(config) +``` + +A great source of [examples][] can be found in the tests for this API. + + ## `ipfs.config.set(key, value, [options])` > Adds or replaces a config value. diff --git a/packages/interface-ipfs-core/src/config/get.js b/packages/interface-ipfs-core/src/config/get.js index 6aac0c84d3..5071e6f93c 100644 --- a/packages/interface-ipfs-core/src/config/get.js +++ b/packages/interface-ipfs-core/src/config/get.js @@ -27,10 +27,8 @@ module.exports = (common, options) => { })) }) - it('should retrieve the whole config', async () => { - const config = await ipfs.config.get() - - expect(config).to.be.an('object') + it('should fail with error', async () => { + await expect(ipfs.config.get()).to.eventually.rejectedWith('key argument is required') }) it('should retrieve a value through a key', async () => { @@ -51,4 +49,31 @@ module.exports = (common, options) => { return expect(ipfs.config.get('Bananas')).to.eventually.be.rejected() }) }) + + describe('.config.getAll', function () { + this.timeout(30 * 1000) + let ipfs + + before(async () => { ipfs = (await common.spawn()).api }) + + after(() => common.clean()) + + it('should respect timeout option when getting config values', () => { + return testTimeout(() => ipfs.config.getAll({ + timeout: 1 + })) + }) + + it('should retrieve the whole config', async () => { + const config = await ipfs.config.getAll() + + expect(config).to.be.an('object') + }) + + it('should retrieve the whole config with options', async () => { + const config = await ipfs.config.getAll({ signal: undefined }) + + expect(config).to.be.an('object') + }) + }) } diff --git a/packages/ipfs-http-client/src/config/get.js b/packages/ipfs-http-client/src/config/get.js index 3ce848b81e..3cc0e7e3cd 100644 --- a/packages/ipfs-http-client/src/config/get.js +++ b/packages/ipfs-http-client/src/config/get.js @@ -5,13 +5,11 @@ const toUrlSearchParams = require('../lib/to-url-search-params') module.exports = configure(api => { return async (key, options = {}) => { - if (key && typeof key === 'object') { - options = key - key = null + if (!key) { + throw new Error('key argument is required') } - const url = key ? 'config' : 'config/show' - const res = await api.post(url, { + const res = await api.post('config', { timeout: options.timeout, signal: options.signal, searchParams: toUrlSearchParams({ @@ -22,6 +20,6 @@ module.exports = configure(api => { }) const data = await res.json() - return key ? data.Value : data + return data.Value } }) diff --git a/packages/ipfs-http-client/src/config/getAll.js b/packages/ipfs-http-client/src/config/getAll.js new file mode 100644 index 0000000000..0c60c5d8c4 --- /dev/null +++ b/packages/ipfs-http-client/src/config/getAll.js @@ -0,0 +1,20 @@ +'use strict' + +const configure = require('../lib/configure') +const toUrlSearchParams = require('../lib/to-url-search-params') + +module.exports = configure(api => { + return async (options = {}) => { + const res = await api.post('config/show', { + timeout: options.timeout, + signal: options.signal, + searchParams: toUrlSearchParams({ + ...options + }), + headers: options.headers + }) + const data = await res.json() + + return data + } +}) diff --git a/packages/ipfs-http-client/src/config/index.js b/packages/ipfs-http-client/src/config/index.js index cb56190a2d..d177cda308 100644 --- a/packages/ipfs-http-client/src/config/index.js +++ b/packages/ipfs-http-client/src/config/index.js @@ -1,6 +1,7 @@ 'use strict' module.exports = config => ({ + getAll: require('./getAll')(config), get: require('./get')(config), set: require('./set')(config), replace: require('./replace')(config), diff --git a/packages/ipfs/src/cli/commands/config/show.js b/packages/ipfs/src/cli/commands/config/show.js index cd85c8c787..7a4b3835cc 100644 --- a/packages/ipfs/src/cli/commands/config/show.js +++ b/packages/ipfs/src/cli/commands/config/show.js @@ -18,7 +18,7 @@ module.exports = { }, async handler ({ ctx: { ipfs, print }, timeout }) { - const config = await ipfs.config.get({ + const config = await ipfs.config.getAll({ timeout }) print(JSON.stringify(config, null, 4)) diff --git a/packages/ipfs/src/core/components/config.js b/packages/ipfs/src/core/components/config.js index 9dd491ab7b..3a4746a0ac 100644 --- a/packages/ipfs/src/core/components/config.js +++ b/packages/ipfs/src/core/components/config.js @@ -6,10 +6,10 @@ const log = require('debug')('ipfs:core:config') module.exports = ({ repo }) => { return { + getAll: withTimeoutOption(repo.config.getAll), get: withTimeoutOption((key, options) => { - if (!options && key && typeof key === 'object') { - options = key - key = undefined + if (!key) { + return Promise.reject(new Error('key argument is required')) } return repo.config.get(key, options) From c5973cd8e0af7dd3edb5a2df99e06b375420f1fd Mon Sep 17 00:00:00 2001 From: Hugo Dias Date: Wed, 10 Jun 2020 15:49:12 +0100 Subject: [PATCH 2/3] fix: can relevant tests to getAll --- packages/interface-ipfs-core/src/config/profiles/apply.js | 8 ++++---- packages/interface-ipfs-core/src/config/replace.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/interface-ipfs-core/src/config/profiles/apply.js b/packages/interface-ipfs-core/src/config/profiles/apply.js index 0f35683c02..d0980cd4d9 100644 --- a/packages/interface-ipfs-core/src/config/profiles/apply.js +++ b/packages/interface-ipfs-core/src/config/profiles/apply.js @@ -33,12 +33,12 @@ module.exports = (common, options) => { const diff = await ipfs.config.profiles.apply('lowpower') expect(diff.original.Swarm.ConnMgr.LowWater).to.not.equal(diff.updated.Swarm.ConnMgr.LowWater) - const newConfig = await ipfs.config.get() + const newConfig = await ipfs.config.getAll() expect(newConfig.Swarm.ConnMgr.LowWater).to.equal(diff.updated.Swarm.ConnMgr.LowWater) }) it('should strip private key from diff output', async () => { - const originalConfig = await ipfs.config.get() + const originalConfig = await ipfs.config.getAll() const diff = await ipfs.config.profiles.apply('default-networking', { dryRun: true }) // should have stripped private key from diff output @@ -48,11 +48,11 @@ module.exports = (common, options) => { }) it('should not apply a config profile in dry-run mode', async () => { - const originalConfig = await ipfs.config.get() + const originalConfig = await ipfs.config.getAll() await ipfs.config.profiles.apply('server', { dryRun: true }) - const updatedConfig = await ipfs.config.get() + const updatedConfig = await ipfs.config.getAll() expect(updatedConfig).to.deep.equal(originalConfig) }) diff --git a/packages/interface-ipfs-core/src/config/replace.js b/packages/interface-ipfs-core/src/config/replace.js index 0d9360427f..d532e64019 100644 --- a/packages/interface-ipfs-core/src/config/replace.js +++ b/packages/interface-ipfs-core/src/config/replace.js @@ -36,14 +36,14 @@ module.exports = (common, options) => { it('should replace the whole config', async () => { await ipfs.config.replace(config) - const _config = await ipfs.config.get() + const _config = await ipfs.config.getAll() expect(_config).to.deep.equal(config) }) it('should replace to empty config', async () => { await ipfs.config.replace({}) - const _config = await ipfs.config.get() + const _config = await ipfs.config.getAll() expect(_config).to.deep.equal({}) }) }) From 740515fb1f240d8402a97b3613266dc41ff3bf5a Mon Sep 17 00:00:00 2001 From: Hugo Dias Date: Wed, 10 Jun 2020 17:54:25 +0100 Subject: [PATCH 3/3] chore: add more getAll --- .../ipfs/src/core/components/bootstrap/add.js | 2 +- .../ipfs/src/core/components/bootstrap/rm.js | 2 +- packages/ipfs/src/core/components/init.js | 2 +- packages/ipfs/src/core/components/start.js | 2 +- .../ipfs/src/http/api/resources/config.js | 6 ++--- packages/ipfs/src/http/index.js | 2 +- packages/ipfs/test/cli/config.js | 5 ++-- packages/ipfs/test/core/create-node.spec.js | 8 +++---- packages/ipfs/test/core/init.spec.js | 10 ++++---- packages/ipfs/test/http-api/inject/config.js | 23 ++++++++++--------- 10 files changed, 32 insertions(+), 30 deletions(-) diff --git a/packages/ipfs/src/core/components/bootstrap/add.js b/packages/ipfs/src/core/components/bootstrap/add.js index 77b6ab37a6..855c5b3698 100644 --- a/packages/ipfs/src/core/components/bootstrap/add.js +++ b/packages/ipfs/src/core/components/bootstrap/add.js @@ -12,7 +12,7 @@ module.exports = ({ repo }) => { throw new Error(`${multiaddr} is not a valid Multiaddr`) } - const config = await repo.config.get() + const config = await repo.config.getAll() if (options.default) { config.Bootstrap = defaultConfig().Bootstrap } else if (multiaddr && config.Bootstrap.indexOf(multiaddr) === -1) { diff --git a/packages/ipfs/src/core/components/bootstrap/rm.js b/packages/ipfs/src/core/components/bootstrap/rm.js index cb3e4bf76c..c8a9b80fe0 100644 --- a/packages/ipfs/src/core/components/bootstrap/rm.js +++ b/packages/ipfs/src/core/components/bootstrap/rm.js @@ -12,7 +12,7 @@ module.exports = ({ repo }) => { } let res = [] - const config = await repo.config.get() + const config = await repo.config.getAll() if (options.all) { res = config.Bootstrap || [] diff --git a/packages/ipfs/src/core/components/init.js b/packages/ipfs/src/core/components/init.js index af48ea4e5f..7a0213eaea 100644 --- a/packages/ipfs/src/core/components/init.js +++ b/packages/ipfs/src/core/components/init.js @@ -227,7 +227,7 @@ async function initNewRepo (repo, { privateKey, emptyRepo, bits, profiles, confi } async function initExistingRepo (repo, { config: newConfig, profiles, pass }) { - let config = await repo.config.get() + let config = await repo.config.getAll() if (newConfig || profiles) { if (profiles) { diff --git a/packages/ipfs/src/core/components/start.js b/packages/ipfs/src/core/components/start.js index 2b5639f5c3..d0e1248347 100644 --- a/packages/ipfs/src/core/components/start.js +++ b/packages/ipfs/src/core/components/start.js @@ -34,7 +34,7 @@ module.exports = ({ await repo.open() } - const config = await repo.config.get() + const config = await repo.config.getAll() const addrs = [] if (config.Addresses && config.Addresses.Swarm) { diff --git a/packages/ipfs/src/http/api/resources/config.js b/packages/ipfs/src/http/api/resources/config.js index 1228264be9..bc54d47bd6 100644 --- a/packages/ipfs/src/http/api/resources/config.js +++ b/packages/ipfs/src/http/api/resources/config.js @@ -99,7 +99,7 @@ exports.getOrSet = { let originalConfig try { - originalConfig = await ipfs.config.get(undefined, { + originalConfig = await ipfs.config.getAll({ signal, timeout }) @@ -172,7 +172,7 @@ exports.get = { let config try { - config = await ipfs.config.get(undefined, { + config = await ipfs.config.getAll({ signal, timeout }) @@ -215,7 +215,7 @@ exports.show = { let config try { - config = await ipfs.config.get(undefined, { + config = await ipfs.config.getAll({ signal, timeout }) diff --git a/packages/ipfs/src/http/index.js b/packages/ipfs/src/http/index.js index 5495d2a353..9cc8c43422 100644 --- a/packages/ipfs/src/http/index.js +++ b/packages/ipfs/src/http/index.js @@ -54,7 +54,7 @@ class HttpApi { const ipfs = this._ipfs - const config = await ipfs.config.get() + const config = await ipfs.config.getAll() config.Addresses = config.Addresses || {} const apiAddrs = config.Addresses.API diff --git a/packages/ipfs/test/cli/config.js b/packages/ipfs/test/cli/config.js index bdef1d08bb..cc9dd9d258 100644 --- a/packages/ipfs/test/cli/config.js +++ b/packages/ipfs/test/cli/config.js @@ -14,6 +14,7 @@ describe('config', () => { ipfs = { config: { set: sinon.stub(), + getAll: sinon.stub(), get: sinon.stub(), replace: sinon.stub(), profiles: { @@ -87,7 +88,7 @@ describe('config', () => { describe('show', function () { it('returns the full config', async () => { - ipfs.config.get.withArgs({ + ipfs.config.getAll.withArgs({ timeout: undefined }).returns({ foo: 'bar' }) const out = await cli('config show', { ipfs }) @@ -95,7 +96,7 @@ describe('config', () => { }) it('returns the full config with a timeout', async () => { - ipfs.config.get.withArgs({ + ipfs.config.getAll.withArgs({ timeout: 1000 }).returns({ foo: 'bar' }) const out = await cli('config show --timeout=1s', { ipfs }) diff --git a/packages/ipfs/test/core/create-node.spec.js b/packages/ipfs/test/core/create-node.spec.js index 7a742120e9..f1ff80da56 100644 --- a/packages/ipfs/test/core/create-node.spec.js +++ b/packages/ipfs/test/core/create-node.spec.js @@ -34,7 +34,7 @@ describe('create node', function () { preload: { enabled: false } }) - const config = await node.config.get() + const config = await node.config.getAll() expect(config.Identity).to.exist() await node.stop() }) @@ -53,7 +53,7 @@ describe('create node', function () { preload: { enabled: false } }) - const config = await node.config.get() + const config = await node.config.getAll() expect(config.Identity).to.exist() await node.stop() }) @@ -104,7 +104,7 @@ describe('create node', function () { preload: { enabled: false } }) - const config = await node.config.get() + const config = await node.config.getAll() expect(config.Identity).to.exist() expect(config.Identity.PrivKey.length).is.below(1024) await node.stop() @@ -152,7 +152,7 @@ describe('create node', function () { preload: { enabled: false } }) - const config = await node.config.get() + const config = await node.config.getAll() expect(config.Addresses.Swarm).to.eql(['/ip4/127.0.0.1/tcp/9977']) expect(config.Bootstrap).to.eql([]) await node.stop() diff --git a/packages/ipfs/test/core/init.spec.js b/packages/ipfs/test/core/init.spec.js index 60ed8c3e4f..222e4f0067 100644 --- a/packages/ipfs/test/core/init.spec.js +++ b/packages/ipfs/test/core/init.spec.js @@ -38,7 +38,7 @@ describe('init', function () { const res = await repo.exists() expect(res).to.equal(true) - const config = await repo.config.get() + const config = await repo.config.getAll() expect(config.Identity).to.exist() expect(config.Keychain).to.exist() @@ -49,14 +49,14 @@ describe('init', function () { await ipfs.init({ bits: 1024, pass: nanoid() }) - const config = await repo.config.get() + const config = await repo.config.getAll() expect(config.Identity.PrivKey.length).is.above(256) }) it('should allow a pregenerated key to be used', async () => { await ipfs.init({ privateKey }) - const config = await repo.config.get() + const config = await repo.config.getAll() expect(config.Identity.PeerID).is.equal('QmRsooYQasV5f5r834NSpdUtmejdQcpxXkK6qsozZWEihC') }) @@ -79,14 +79,14 @@ describe('init', function () { it('should apply one profile', async () => { await ipfs.init({ bits: 512, profiles: ['test'] }) - const config = await repo.config.get() + const config = await repo.config.getAll() expect(config.Bootstrap).to.be.empty() }) it('should apply multiple profiles', async () => { await ipfs.init({ bits: 512, profiles: ['test', 'local-discovery'] }) - const config = await repo.config.get() + const config = await repo.config.getAll() expect(config.Bootstrap).to.be.empty() expect(config.Discovery.MDNS.Enabled).to.be.true() }) diff --git a/packages/ipfs/test/http-api/inject/config.js b/packages/ipfs/test/http-api/inject/config.js index 90c9abc645..62b0d5be6e 100644 --- a/packages/ipfs/test/http-api/inject/config.js +++ b/packages/ipfs/test/http-api/inject/config.js @@ -23,6 +23,7 @@ describe('/config', () => { beforeEach(() => { ipfs = { config: { + getAll: sinon.stub(), get: sinon.stub(), replace: sinon.stub(), profiles: { @@ -58,7 +59,7 @@ describe('/config', () => { }) it('returns value for request with valid arg', async () => { - ipfs.config.get.withArgs(undefined, defaultOptions).returns({ + ipfs.config.getAll.withArgs(defaultOptions).returns({ API: { HTTPHeaders: 'value' } @@ -75,7 +76,7 @@ describe('/config', () => { }) it('returns value for request as subcommand', async () => { - ipfs.config.get.withArgs(undefined, defaultOptions).returns({ + ipfs.config.getAll.withArgs(defaultOptions).returns({ API: { HTTPHeaders: 'value' } @@ -92,7 +93,7 @@ describe('/config', () => { }) it('updates value for request with both args', async () => { - ipfs.config.get.withArgs(undefined, defaultOptions).returns({ + ipfs.config.getAll.withArgs(defaultOptions).returns({ Datastore: { Path: 'not-kitten' } @@ -114,7 +115,7 @@ describe('/config', () => { }) it('returns 400 value for request with both args and JSON flag with invalid JSON argument', async () => { - ipfs.config.get.withArgs(undefined, defaultOptions).returns({ + ipfs.config.getAll.withArgs(defaultOptions).returns({ Datastore: { Path: 'not-kitten' } @@ -132,7 +133,7 @@ describe('/config', () => { }) it('updates value for request with both args and JSON flag with valid JSON argument', async () => { - ipfs.config.get.withArgs(undefined, defaultOptions).returns({ + ipfs.config.getAll.withArgs(defaultOptions).returns({ Datastore: { Path: 'not-kitten' } @@ -156,7 +157,7 @@ describe('/config', () => { }) it('updates null json value', async () => { - ipfs.config.get.withArgs(undefined, defaultOptions).returns({ + ipfs.config.getAll.withArgs(defaultOptions).returns({ Datastore: { Path: 'not-kitten' } @@ -178,7 +179,7 @@ describe('/config', () => { }) it('updates value for request with both args and bool flag and true argument', async () => { - ipfs.config.get.withArgs(undefined, defaultOptions).returns({ + ipfs.config.getAll.withArgs(defaultOptions).returns({ Datastore: { Path: 'not-kitten' } @@ -200,7 +201,7 @@ describe('/config', () => { }) it('updates value for request with both args and bool flag and false argument', async () => { - ipfs.config.get.withArgs(undefined, defaultOptions).returns({ + ipfs.config.getAll.withArgs(defaultOptions).returns({ Datastore: { Path: 'not-kitten' } @@ -224,7 +225,7 @@ describe('/config', () => { it('accepts a timeout', async () => { const key = 'Datastore.Path' const value = 'value' - ipfs.config.get.withArgs(undefined, { + ipfs.config.getAll.withArgs({ ...defaultOptions, timeout: 1000 }).returns({ @@ -262,7 +263,7 @@ describe('/config', () => { } } - ipfs.config.get.withArgs(undefined, defaultOptions).returns(config) + ipfs.config.getAll.withArgs(defaultOptions).returns(config) const res = await http({ method: 'POST', @@ -280,7 +281,7 @@ describe('/config', () => { } } - ipfs.config.get.withArgs(undefined, { + ipfs.config.getAll.withArgs({ ...defaultOptions, timeout: 1000 }).returns(config)