Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

Commit c73bd2f

Browse files
author
Alan Shaw
authored
fix: allow null/undefined options (#1581)
Options should be optional! Our API should be flexible enough to allow passing null or undefined in place of an options object. This PR fixes cases where we assume an options object has been passed. fixes: #1574
1 parent 88c735a commit c73bd2f

15 files changed

+211
-9
lines changed

src/core/components/block.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ module.exports = function block (self) {
3939
options = {}
4040
}
4141

42+
options = options || {}
43+
4244
if (Array.isArray(block)) {
4345
return callback(new Error('Array is not supported'))
4446
}
@@ -93,6 +95,8 @@ module.exports = function block (self) {
9395
options = {}
9496
}
9597

98+
options = options || {}
99+
96100
try {
97101
cid = cleanCid(cid)
98102
} catch (err) {

src/core/components/dag.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@ module.exports = function dag (self) {
1414
if (typeof options === 'function') {
1515
callback = options
1616
options = {}
17-
} else if (options && options.cid && (options.format || options.hashAlg)) {
17+
}
18+
19+
options = options || {}
20+
21+
if (options.cid && (options.format || options.hashAlg)) {
1822
return callback(new Error('Can\'t put dag node. Please provide either `cid` OR `format` and `hashAlg` options.'))
19-
} else if (options && ((options.format && !options.hashAlg) || (!options.format && options.hashAlg))) {
23+
} else if (((options.format && !options.hashAlg) || (!options.format && options.hashAlg))) {
2024
return callback(new Error('Can\'t put dag node. Please provide `format` AND `hashAlg` options.'))
2125
}
22-
options = options || {}
2326

2427
const optionDefaults = {
2528
format: 'dag-cbor',

src/core/components/dht.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ module.exports = (self) => {
2828
options = {}
2929
}
3030

31+
options = options || {}
32+
3133
self._libp2pNode.dht.get(key, options.timeout, callback)
3234
}),
3335

@@ -134,6 +136,8 @@ module.exports = (self) => {
134136
options = {}
135137
}
136138

139+
options = options || {}
140+
137141
// ensure blocks are actually local
138142
every(keys, (key, cb) => {
139143
self._repo.blocks.has(key, cb)

src/core/components/dns.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ module.exports = () => {
1515
opts = {}
1616
}
1717

18+
opts = opts || {}
19+
1820
dns(domain, opts, callback)
1921
})
2022
}

src/core/components/files.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,14 +256,14 @@ module.exports = function files (self) {
256256

257257
return {
258258
add: (() => {
259-
const add = promisify((data, options = {}, callback) => {
259+
const add = promisify((data, options, callback) => {
260260
if (typeof options === 'function') {
261261
callback = options
262262
options = {}
263-
} else if (!callback || typeof callback !== 'function') {
264-
callback = noop
265263
}
266264

265+
options = options || {}
266+
267267
const ok = Buffer.isBuffer(data) ||
268268
isStream.readable(data) ||
269269
Array.isArray(data) ||

src/core/components/key.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const promisify = require('promisify-es6')
77
module.exports = function key (self) {
88
return {
99
gen: promisify((name, opts, callback) => {
10+
opts = opts || {}
1011
self._keychain.createKey(name, opts.type, opts.size, callback)
1112
}),
1213

src/core/components/object.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ module.exports = function object (self) {
7070
options = {}
7171
}
7272

73+
options = options || {}
74+
7375
waterfall([
7476
(cb) => {
7577
self.object.get(multihash, options, cb)
@@ -151,6 +153,8 @@ module.exports = function object (self) {
151153
options = {}
152154
}
153155

156+
options = options || {}
157+
154158
const encoding = options.enc
155159
let node
156160

@@ -217,6 +221,8 @@ module.exports = function object (self) {
217221
options = {}
218222
}
219223

224+
options = options || {}
225+
220226
let mh, cid
221227

222228
try {

src/core/components/stats.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ module.exports = function stats (self) {
8181
opts = {}
8282
}
8383

84+
opts = opts || {}
85+
8486
bandwidthStats(self, opts)
8587
.then((stats) => callback(null, stats))
8688
.catch((err) => callback(err))

src/core/components/swarm.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ module.exports = function swarm (self) {
1313
opts = {}
1414
}
1515

16+
opts = opts || {}
17+
1618
if (!self.isOnline()) {
1719
return callback(new Error(OFFLINE_ERROR))
1820
}

src/core/components/version.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module.exports = function version (self) {
1313

1414
self.repo.version((err, repoVersion) => {
1515
if (err) {
16-
callback(err)
16+
return callback(err)
1717
}
1818

1919
callback(null, {

test/core/block.spec.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const chai = require('chai')
66
const dirtyChai = require('dirty-chai')
77
const expect = chai.expect
88
chai.use(dirtyChai)
9+
const hat = require('hat')
910

1011
const IPFSFactory = require('ipfsd-ctl')
1112
const IPFS = require('../../src/core')
@@ -47,6 +48,15 @@ describe('block', () => {
4748
})
4849
})
4950

51+
describe('put', () => {
52+
it('should not error when passed null options', (done) => {
53+
ipfs.block.put(Buffer.from(hat()), null, (err) => {
54+
expect(err).to.not.exist()
55+
done()
56+
})
57+
})
58+
})
59+
5060
describe('rm', () => {
5161
it('should callback with error for invalid CID input', (done) => {
5262
ipfs.block.rm('INVALID CID', (err) => {
@@ -65,5 +75,16 @@ describe('block', () => {
6575
done()
6676
})
6777
})
78+
79+
it('should not error when passed null options', (done) => {
80+
ipfs.block.put(Buffer.from(hat()), (err, block) => {
81+
expect(err).to.not.exist()
82+
83+
ipfs.block.stat(block.cid, null, (err) => {
84+
expect(err).to.not.exist()
85+
done()
86+
})
87+
})
88+
})
6889
})
6990
})

test/core/files.spec.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const chai = require('chai')
66
const dirtyChai = require('dirty-chai')
77
const expect = chai.expect
88
chai.use(dirtyChai)
9-
9+
const hat = require('hat')
1010
const pull = require('pull-stream')
1111
const IPFSFactory = require('ipfsd-ctl')
1212
const IPFS = require('../../src/core')
@@ -75,4 +75,13 @@ describe('files', () => {
7575
)
7676
})
7777
})
78+
79+
describe('add', () => {
80+
it('should not error when passed null options', (done) => {
81+
ipfs.files.add(Buffer.from(hat()), null, (err) => {
82+
expect(err).to.not.exist()
83+
done()
84+
})
85+
})
86+
})
7887
})

test/core/object.spec.js

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ const chai = require('chai')
66
const dirtyChai = require('dirty-chai')
77
const expect = chai.expect
88
chai.use(dirtyChai)
9-
9+
const hat = require('hat')
1010
const IPFSFactory = require('ipfsd-ctl')
11+
const auto = require('async/auto')
1112
const IPFS = require('../../src/core')
1213

1314
describe('object', () => {
@@ -45,6 +46,17 @@ describe('object', () => {
4546
done()
4647
})
4748
})
49+
50+
it('should not error when passed null options', (done) => {
51+
ipfs.object.put(Buffer.from(hat()), (err, dagNode) => {
52+
expect(err).to.not.exist()
53+
54+
ipfs.object.get(dagNode.multihash, null, (err) => {
55+
expect(err).to.not.exist()
56+
done()
57+
})
58+
})
59+
})
4860
})
4961

5062
describe('put', () => {
@@ -55,5 +67,84 @@ describe('object', () => {
5567
done()
5668
})
5769
})
70+
71+
it('should not error when passed null options', (done) => {
72+
ipfs.object.put(Buffer.from(hat()), null, (err) => {
73+
expect(err).to.not.exist()
74+
done()
75+
})
76+
})
77+
})
78+
79+
describe('patch.addLink', () => {
80+
it('should not error when passed null options', (done) => {
81+
auto({
82+
a: (cb) => ipfs.object.put(Buffer.from(hat()), cb),
83+
b: (cb) => ipfs.object.put(Buffer.from(hat()), cb)
84+
}, (err, nodes) => {
85+
expect(err).to.not.exist()
86+
87+
const link = {
88+
name: nodes.b.name,
89+
multihash: nodes.b.multihash,
90+
size: nodes.b.size
91+
}
92+
93+
ipfs.object.patch.addLink(nodes.a.multihash, link, null, (err) => {
94+
expect(err).to.not.exist()
95+
done()
96+
})
97+
})
98+
})
99+
})
100+
101+
describe('patch.rmLink', () => {
102+
it('should not error when passed null options', (done) => {
103+
auto({
104+
nodeA: (cb) => ipfs.object.put(Buffer.from(hat()), cb),
105+
nodeB: (cb) => ipfs.object.put(Buffer.from(hat()), cb),
106+
nodeAWithLink: ['nodeA', 'nodeB', (res, cb) => {
107+
ipfs.object.patch.addLink(res.nodeA.multihash, {
108+
name: res.nodeB.name,
109+
multihash: res.nodeB.multihash,
110+
size: res.nodeB.size
111+
}, cb)
112+
}]
113+
}, (err, res) => {
114+
expect(err).to.not.exist()
115+
116+
const link = res.nodeAWithLink.links[0]
117+
ipfs.object.patch.rmLink(res.nodeAWithLink.multihash, link, null, (err) => {
118+
expect(err).to.not.exist()
119+
done()
120+
})
121+
})
122+
})
123+
})
124+
125+
describe('patch.appendData', () => {
126+
it('should not error when passed null options', (done) => {
127+
ipfs.object.put(Buffer.from(hat()), null, (err, dagNode) => {
128+
expect(err).to.not.exist()
129+
130+
ipfs.object.patch.appendData(dagNode.multihash, Buffer.from(hat()), null, (err) => {
131+
expect(err).to.not.exist()
132+
done()
133+
})
134+
})
135+
})
136+
})
137+
138+
describe('patch.setData', () => {
139+
it('should not error when passed null options', (done) => {
140+
ipfs.object.put(Buffer.from(hat()), null, (err, dagNode) => {
141+
expect(err).to.not.exist()
142+
143+
ipfs.object.patch.setData(dagNode.multihash, Buffer.from(hat()), null, (err) => {
144+
expect(err).to.not.exist()
145+
done()
146+
})
147+
})
148+
})
58149
})
59150
})

test/core/stats.spec.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,13 @@ describe('stats', () => {
5050
)
5151
})
5252
})
53+
54+
describe('bw', () => {
55+
it('should not error when passed null options', (done) => {
56+
ipfs.stats.bw(null, (err) => {
57+
expect(err).to.not.exist()
58+
done()
59+
})
60+
})
61+
})
5362
})

test/core/swarm.spec.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/* eslint max-nested-callbacks: ["error", 8] */
2+
/* eslint-env mocha */
3+
'use strict'
4+
5+
const chai = require('chai')
6+
const dirtyChai = require('dirty-chai')
7+
const expect = chai.expect
8+
chai.use(dirtyChai)
9+
10+
const IPFSFactory = require('ipfsd-ctl')
11+
const IPFS = require('../../src/core')
12+
13+
describe('swarm', () => {
14+
let ipfsd, ipfs
15+
16+
before(function (done) {
17+
this.timeout(20 * 1000)
18+
19+
const factory = IPFSFactory.create({ type: 'proc' })
20+
21+
factory.spawn({
22+
exec: IPFS,
23+
initOptions: { bits: 512 }
24+
}, (err, _ipfsd) => {
25+
expect(err).to.not.exist()
26+
ipfsd = _ipfsd
27+
ipfs = _ipfsd.api
28+
done()
29+
})
30+
})
31+
32+
after((done) => {
33+
if (ipfsd) {
34+
ipfsd.stop(done)
35+
} else {
36+
done()
37+
}
38+
})
39+
40+
describe('peers', () => {
41+
it('should not error when passed null options', (done) => {
42+
ipfs.swarm.peers(null, (err) => {
43+
expect(err).to.not.exist()
44+
done()
45+
})
46+
})
47+
})
48+
})

0 commit comments

Comments
 (0)