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

Commit 6421678

Browse files
committed
Merge pull request #99 from ipfs/feature/object-patch
Add object patch endpoints and cli commands
2 parents da0bb36 + a3f73e6 commit 6421678

File tree

12 files changed

+1074
-27
lines changed

12 files changed

+1074
-27
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
"bs58": "^3.0.0",
8181
"debug": "^2.2.0",
8282
"hapi": "^12.0.0",
83-
"ipfs-api": "^2.13.1",
83+
"ipfs-api": "github:ipfs/js-ipfs-api#1fd9749",
8484
"ipfs-blocks": "^0.1.0",
8585
"ipfs-data-importing": "^0.3.3",
8686
"ipfs-merkle-dag": "^0.2.1",
+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
'use strict'
2+
3+
const Command = require('ronin').Command
4+
const utils = require('../../../utils')
5+
const bs58 = require('bs58')
6+
const debug = require('debug')
7+
const log = debug('cli:object')
8+
const mDAG = require('ipfs-merkle-dag')
9+
const DAGLink = mDAG.DAGLink
10+
log.error = debug('cli:object:error')
11+
12+
module.exports = Command.extend({
13+
desc: 'Add a link to a given object',
14+
15+
options: {},
16+
17+
run: (root, name, ref) => {
18+
if (!root) {
19+
throw new Error("Argument 'root' is required")
20+
}
21+
if (!name) {
22+
throw new Error("Argument 'name' is required")
23+
}
24+
if (!ref) {
25+
throw new Error("Argument 'ref' is required")
26+
}
27+
28+
utils.getIPFS((err, ipfs) => {
29+
if (err) {
30+
throw err
31+
}
32+
33+
if (utils.isDaemonOn()) {
34+
return ipfs.object.patch.addLink(root, name, ref, (err, obj) => {
35+
if (err) {
36+
log.error(err)
37+
throw err
38+
}
39+
40+
console.log(obj.Hash)
41+
})
42+
}
43+
44+
// when running locally we first need to get the ref object,
45+
// so we can create the link with the correct size
46+
const refMh = new Buffer(bs58.decode(ref))
47+
ipfs.object.get(refMh, (err, linkedObj) => {
48+
if (err) {
49+
log.error(err)
50+
throw err
51+
}
52+
53+
const rootMh = new Buffer(bs58.decode(root))
54+
const link = new DAGLink(name, linkedObj.size(), linkedObj.multihash())
55+
ipfs.object.patch.addLink(rootMh, link, (err, obj) => {
56+
if (err) {
57+
log.error(err)
58+
throw err
59+
}
60+
61+
console.log(bs58.encode(obj.multihash()).toString())
62+
})
63+
})
64+
})
65+
}
66+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
'use strict'
2+
3+
const Command = require('ronin').Command
4+
const utils = require('../../../utils')
5+
const bs58 = require('bs58')
6+
const bl = require('bl')
7+
const fs = require('fs')
8+
const debug = require('debug')
9+
const log = debug('cli:object')
10+
log.error = debug('cli:object:error')
11+
12+
function appendData (keyStr, data) {
13+
utils.getIPFS((err, ipfs) => {
14+
if (err) {
15+
throw err
16+
}
17+
18+
const key = utils.isDaemonOn() ? keyStr : new Buffer(bs58.decode(keyStr))
19+
20+
ipfs.object.patch.appendData(key, data, (err, obj) => {
21+
if (err) {
22+
log.error(err)
23+
throw err
24+
}
25+
26+
if (typeof obj.multihash === 'function') {
27+
console.log(bs58.encode(obj.multihash()).toString())
28+
return
29+
}
30+
31+
console.log(obj.Hash)
32+
})
33+
})
34+
}
35+
36+
module.exports = Command.extend({
37+
desc: 'Append data to the data segment of a dag node',
38+
39+
options: {},
40+
41+
run: (key, filePath) => {
42+
if (!key) {
43+
throw new Error("Argument 'root' is required")
44+
}
45+
46+
if (filePath) {
47+
return appendData(key, fs.readFileSync(filePath))
48+
}
49+
50+
process.stdin.pipe(bl((err, input) => {
51+
if (err) {
52+
log.error(err)
53+
throw err
54+
}
55+
56+
appendData(key, input)
57+
}))
58+
}
59+
})
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
'use strict'
2+
3+
const Command = require('ronin').Command
4+
const utils = require('../../../utils')
5+
const bs58 = require('bs58')
6+
const debug = require('debug')
7+
const log = debug('cli:object')
8+
log.error = debug('cli:object:error')
9+
10+
module.exports = Command.extend({
11+
desc: 'Remove a link from an object',
12+
13+
options: {},
14+
15+
run: (root, link) => {
16+
if (!root) {
17+
throw new Error("Argument 'root' is required")
18+
}
19+
if (!link) {
20+
throw new Error("Argument 'link' is required")
21+
}
22+
23+
utils.getIPFS((err, ipfs) => {
24+
if (err) {
25+
throw err
26+
}
27+
28+
if (utils.isDaemonOn()) {
29+
return ipfs.object.patch.rmLink(root, link, (err, obj) => {
30+
if (err) {
31+
log.error(err)
32+
throw err
33+
}
34+
35+
console.log(obj.Hash)
36+
})
37+
}
38+
39+
const mh = new Buffer(bs58.decode(root))
40+
ipfs.object.patch.rmLink(mh, link, (err, obj) => {
41+
if (err) {
42+
log.error(err)
43+
throw err
44+
}
45+
46+
console.log(bs58.encode(obj.multihash()).toString())
47+
})
48+
})
49+
}
50+
})
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
'use strict'
2+
3+
const Command = require('ronin').Command
4+
const utils = require('../../../utils')
5+
const bs58 = require('bs58')
6+
const bl = require('bl')
7+
const fs = require('fs')
8+
const debug = require('debug')
9+
const log = debug('cli:object')
10+
log.error = debug('cli:object:error')
11+
12+
function parseAndAddNode (keyStr, data) {
13+
utils.getIPFS((err, ipfs) => {
14+
if (err) {
15+
throw err
16+
}
17+
18+
const key = utils.isDaemonOn() ? keyStr : new Buffer(bs58.decode(keyStr))
19+
20+
ipfs.object.patch.setData(key, data, (err, obj) => {
21+
if (err) {
22+
log.error(err)
23+
throw err
24+
}
25+
26+
if (typeof obj.multihash === 'function') {
27+
console.log(bs58.encode(obj.multihash()).toString())
28+
return
29+
}
30+
31+
console.log(obj.Hash)
32+
})
33+
})
34+
}
35+
36+
module.exports = Command.extend({
37+
desc: 'Set data field of an ipfs object',
38+
39+
options: {},
40+
41+
run: (key, filePath) => {
42+
if (!key) {
43+
throw new Error("Argument 'root' is required")
44+
}
45+
46+
if (filePath) {
47+
return parseAndAddNode(key, fs.readFileSync(filePath))
48+
}
49+
50+
process.stdin.pipe(bl((err, input) => {
51+
if (err) {
52+
log.error(err)
53+
throw err
54+
}
55+
56+
parseAndAddNode(key, input)
57+
}))
58+
}
59+
})

src/core/index.js

+9-8
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ function IPFS (repo) {
207207
if (err) {
208208
return callback(err)
209209
}
210-
callback(null, obj.multihash())
210+
callback(null, obj)
211211
})
212212
})
213213
},
@@ -219,24 +219,25 @@ function IPFS (repo) {
219219
if (err) {
220220
return callback(err)
221221
}
222-
callback(null, obj.multihash())
222+
callback(null, obj)
223223
})
224224
})
225225
},
226-
rmLink: (multihash, multihashLink, callback) => {
226+
rmLink: (multihash, linkRef, callback) => {
227227
this.object.get(multihash, (err, obj) => {
228228
if (err) { return callback(err) }
229229
obj.links = obj.links.filter((link) => {
230-
if (link.hash.equals(multihashLink)) {
231-
return false
230+
// filter by name when linkRef is a string, or by hash otherwise
231+
if (typeof linkRef === 'string') {
232+
return link.name !== linkRef
232233
}
233-
return true
234+
return !link.hash.equals(linkRef)
234235
})
235236
dagS.add(obj, (err) => {
236237
if (err) {
237238
return callback(err)
238239
}
239-
callback(null, obj.multihash())
240+
callback(null, obj)
240241
})
241242
})
242243
},
@@ -248,7 +249,7 @@ function IPFS (repo) {
248249
if (err) {
249250
return callback(err)
250251
}
251-
callback(null, obj.multihash())
252+
callback(null, obj)
252253
})
253254
})
254255
}

0 commit comments

Comments
 (0)