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

Commit ac5fa8e

Browse files
author
Alan Shaw
authored
refactor: object APIs write methods now return CIDs (#1730)
For the back story on this change, please see: ipfs-inactive/interface-js-ipfs-core#388 (review) BREAKING CHANGE: Object API refactor. Object API methods that write DAG nodes now return a [CID](https://www.npmjs.com/package/cids) instead of a DAG node. Affected methods: * `ipfs.object.new` * `ipfs.object.patch.addLink` * `ipfs.object.patch.appendData` * `ipfs.object.patch.rmLink` * `ipfs.object.patch.setData` * `ipfs.object.put` Example: ```js // Before const dagNode = await ipfs.object.new() ``` ```js // After const cid = await ipfs.object.new() // now returns a CID const dagNode = await ipfs.object.get(cid) // fetch the DAG node that was created ``` IMPORTANT: `DAGNode` instances, which are part of the IPLD dag-pb format have been refactored. These instances no longer have `multihash`, `cid` or `serialized` properties. This effects the following API methods that return these types of objects: * `ipfs.object.get` * `ipfs.dag.get` See ipld/js-ipld-dag-pb#99 for more information. License: MIT Signed-off-by: Alan Shaw <[email protected]>
1 parent 2c44600 commit ac5fa8e

23 files changed

+152
-281
lines changed

Diff for: README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ Commands:
186186

187187
### IPFS Daemon
188188

189-
The IPFS Daemon exposes the API defined [`http-api-spec`](https://github.com/ipfs/http-api-spec). You can use any of the IPFS HTTP-API client libraries with it, such as: [js-ipfs-api](https://github.com/ipfs/js-ipfs-api).
189+
The IPFS Daemon exposes the API defined [`http-api-spec`](https://github.com/ipfs/http-api-spec). You can use any of the IPFS HTTP-API client libraries with it, such as: [js-ipfs-http-client](https://github.com/ipfs/js-ipfs-http-client).
190190

191191
If you want a programmatic way to spawn a IPFS Daemon using JavaScript, check out [ipfsd-ctl module](https://github.com/ipfs/js-ipfsd-ctl)
192192

@@ -884,7 +884,7 @@ Listing of the main packages used in the IPFS ecosystem. There are also three sp
884884
| [`libp2p-crypto`](//github.com/libp2p/js-libp2p-crypto) | [![npm](https://img.shields.io/npm/v/libp2p-crypto.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-crypto/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-crypto.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-crypto) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-crypto/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-crypto/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-crypto/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-crypto) | [Friedel Ziegelmayer](mailto:[email protected]) |
885885
| [`libp2p-keychain`](//github.com/libp2p/js-libp2p-keychain) | [![npm](https://img.shields.io/npm/v/libp2p-keychain.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-keychain/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-keychain.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-keychain) | N/A | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-keychain/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-keychain) | [Vasco Santos](mailto:[email protected]) |
886886
| **Generics/Utils** |
887-
| [`ipfs-api`](//github.com/ipfs/js-ipfs-api) | [![npm](https://img.shields.io/npm/v/ipfs-api.svg?maxAge=86400&style=flat-square)](//github.com/ipfs/js-ipfs-api/releases) | [![Deps](https://david-dm.org/ipfs/js-ipfs-api.svg?style=flat-square)](https://david-dm.org/ipfs/js-ipfs-api) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=ipfs/js-ipfs-api/master)](https://ci.ipfs.team/job/ipfs/job/js-ipfs-api/job/master/) | [![codecov](https://codecov.io/gh/ipfs/js-ipfs-api/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/js-ipfs-api) | [Alan Shaw](mailto:[email protected]) |
887+
| [`ipfs-http-client`](//github.com/ipfs/js-ipfs-http-client) | [![npm](https://img.shields.io/npm/v/ipfs-http-client.svg?maxAge=86400&style=flat-square)](//github.com/ipfs/js-ipfs-http-client/releases) | [![Deps](https://david-dm.org/ipfs/js-ipfs-http-client.svg?style=flat-square)](https://david-dm.org/ipfs/js-ipfs-http-client) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=ipfs/js-ipfs-http-client/master)](https://ci.ipfs.team/job/ipfs/job/js-ipfs-http-client/job/master/) | [![codecov](https://codecov.io/gh/ipfs/js-ipfs-http-client/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/js-ipfs-http-client) | [Alan Shaw](mailto:[email protected]) |
888888
| [`ipfs-multipart`](//github.com/ipfs/ipfs-multipart) | [![npm](https://img.shields.io/npm/v/ipfs-multipart.svg?maxAge=86400&style=flat-square)](//github.com/ipfs/ipfs-multipart/releases) | [![Deps](https://david-dm.org/ipfs/ipfs-multipart.svg?style=flat-square)](https://david-dm.org/ipfs/ipfs-multipart) | N/A | [![codecov](https://codecov.io/gh/ipfs/ipfs-multipart/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/ipfs-multipart) | N/A |
889889
| [`is-ipfs`](//github.com/ipfs/is-ipfs) | [![npm](https://img.shields.io/npm/v/is-ipfs.svg?maxAge=86400&style=flat-square)](//github.com/ipfs/is-ipfs/releases) | [![Deps](https://david-dm.org/ipfs/is-ipfs.svg?style=flat-square)](https://david-dm.org/ipfs/is-ipfs) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=ipfs/is-ipfs/master)](https://ci.ipfs.team/job/ipfs/job/is-ipfs/job/master/) | [![codecov](https://codecov.io/gh/ipfs/is-ipfs/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/is-ipfs) | [Marcin Rataj](mailto:[email protected]) |
890890
| [`multihashing`](//github.com/multiformats/js-multihashing) | [![npm](https://img.shields.io/npm/v/multihashing.svg?maxAge=86400&style=flat-square)](//github.com/multiformats/js-multihashing/releases) | [![Deps](https://david-dm.org/multiformats/js-multihashing.svg?style=flat-square)](https://david-dm.org/multiformats/js-multihashing) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=multiformats/js-multihashing/master)](https://ci.ipfs.team/job/multiformats/job/js-multihashing/job/master/) | [![codecov](https://codecov.io/gh/multiformats/js-multihashing/branch/master/graph/badge.svg)](https://codecov.io/gh/multiformats/js-multihashing) | N/A |

Diff for: img/overview.txt

+17-17
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
2-
offline mode - uses IPFS core directly
3-
┌───────────────────────────────────────────
4-
5-
6-
│ online mode - uses IPFS through http-api
7-
┌────────────┐ │ ┌────────────────────┐ │ ┌─────────┐
8-
│ │ │ ┌ ─ ─ ─ ─ ─ ─ │ │ │
9-
│ CLI │───┴── ipfs-api ├──▶│ HTTP-API │───┴───▶│IPFS Core
10-
│ │ └ ─ ─ ─ ─ ─ ─ │ │
11-
└────────────┘ └────────────────────┘ └─────────┘
12-
13-
├───────────────────────────────────────────────────────────────┘
14-
15-
┌────────────┐
16-
│ Tests │
17-
└────────────┘
1+
2+
offline mode - uses IPFS core directly
3+
┌────────────────────────────────────────────┐
4+
5+
6+
│ online mode - uses IPFS through http-api
7+
┌────────────┐ │ ┌─────────────┐ │ ┌─────────┐
8+
│ │ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │ │ │
9+
│ CLI │───┴── ipfs-http-client ├──▶│ HTTP-API │───┴───▶│IPFS Core│
10+
│ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │ │
11+
└────────────┘ └─────────────┘ └─────────┘
12+
13+
├───────────────────────────────────────────────────────────────┘
14+
15+
┌────────────┐
16+
│ Tests │
17+
└────────────┘

Diff for: package-list.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
["libp2p/js-libp2p-keychain", "libp2p-keychain"],
5151

5252
"Generics/Utils",
53-
["ipfs/js-ipfs-api", "ipfs-api"],
53+
["ipfs/js-ipfs-http-client", "ipfs-http-client"],
5454
["ipfs/ipfs-multipart", "ipfs-multipart"],
5555
["ipfs/is-ipfs", "is-ipfs"],
5656
["multiformats/js-multihashing", "multihashing"],

Diff for: package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@
6969
"execa": "^1.0.0",
7070
"form-data": "^2.3.3",
7171
"hat": "0.0.3",
72-
"interface-ipfs-core": "~0.86.0",
73-
"ipfsd-ctl": "ipfs/js-ipfsd-ctl#update-dag-pb-to-not-have-cid-property",
72+
"interface-ipfs-core": "~0.88.0",
73+
"ipfsd-ctl": "~0.40.1",
7474
"ncp": "^2.0.0",
7575
"qs": "^6.5.2",
7676
"rimraf": "^2.6.2",
@@ -86,7 +86,7 @@
8686
"boom": "^7.2.0",
8787
"bs58": "^4.0.1",
8888
"byteman": "^1.3.5",
89-
"cid-tool": "~0.1.0",
89+
"cid-tool": "~0.2.0",
9090
"cids": "~0.5.5",
9191
"datastore-core": "~0.6.0",
9292
"debug": "^4.1.0",
@@ -102,10 +102,10 @@
102102
"hoek": "^5.0.4",
103103
"human-to-milliseconds": "^1.0.0",
104104
"interface-datastore": "~0.6.0",
105-
"ipfs-api": "ipfs/js-ipfs-api",
106105
"ipfs-bitswap": "~0.21.0",
107106
"ipfs-block": "~0.8.0",
108107
"ipfs-block-service": "~0.15.1",
108+
"ipfs-http-client": "^27.0.0",
109109
"ipfs-http-response": "~0.2.1",
110110
"ipfs-mfs": "~0.5.2",
111111
"ipfs-multipart": "~0.1.0",
@@ -124,7 +124,7 @@
124124
"is-stream": "^1.1.0",
125125
"joi": "^13.4.0",
126126
"joi-browser": "^13.4.0",
127-
"joi-multiaddr": "^2.0.0",
127+
"joi-multiaddr": "^3.0.0",
128128
"libp2p": "~0.24.0",
129129
"libp2p-bootstrap": "~0.9.3",
130130
"libp2p-crypto": "~0.14.1",
@@ -144,7 +144,7 @@
144144
"mkdirp": "~0.5.1",
145145
"multiaddr": "^5.0.0",
146146
"multiaddr-to-uri": "^4.0.0",
147-
"multibase": "~0.5.0",
147+
"multibase": "~0.6.0",
148148
"multihashes": "~0.4.14",
149149
"multihashing-async": "~0.5.1",
150150
"once": "^1.4.0",

Diff for: src/cli/commands/block/rm.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module.exports = {
1313

1414
handler (argv) {
1515
if (utils.isDaemonOn()) {
16-
// TODO implement this once `js-ipfs-api` supports it
16+
// TODO implement this once `js-ipfs-http-client` supports it
1717
throw new Error('rm block with daemon running is not yet implemented')
1818
}
1919

Diff for: src/cli/commands/object/get.js

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
'use strict'
22

33
const print = require('../../utils').print
4-
const {
5-
util: {
6-
cid
7-
}
8-
} = require('ipld-dag-pb')
4+
const dagPB = require('ipld-dag-pb')
95

106
module.exports = {
117
command: 'get <key>',
@@ -29,7 +25,7 @@ module.exports = {
2925
throw err
3026
}
3127

32-
cid(node, (err, result) => {
28+
dagPB.util.cid(node, (err, result) => {
3329
if (err) {
3430
throw err
3531
}

Diff for: src/cli/commands/object/new.js

+2-13
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@ const debug = require('debug')
44
const log = debug('cli:object')
55
log.error = debug('cli:object:error')
66
const print = require('../../utils').print
7-
const {
8-
util: {
9-
cid
10-
}
11-
} = require('ipld-dag-pb')
127

138
module.exports = {
149
command: 'new [<template>]',
@@ -23,18 +18,12 @@ module.exports = {
2318
},
2419

2520
handler (argv) {
26-
argv.ipfs.object.new(argv.template, (err, node) => {
21+
argv.ipfs.object.new(argv.template, (err, cid) => {
2722
if (err) {
2823
throw err
2924
}
3025

31-
cid(node, (err, cid) => {
32-
if (err) {
33-
throw err
34-
}
35-
36-
print(cid.toBaseEncodedString(argv.cidBase))
37-
})
26+
print(cid.toBaseEncodedString(argv.cidBase))
3827
})
3928
}
4029
}

Diff for: src/cli/commands/object/patch/add-link.js

+3-14
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@
33
const dagPB = require('ipld-dag-pb')
44
const DAGLink = dagPB.DAGLink
55
const print = require('../../../utils').print
6-
const {
7-
util: {
8-
cid
9-
}
10-
} = require('ipld-dag-pb')
116

127
module.exports = {
138
command: 'add-link <root> <name> <ref>',
@@ -30,7 +25,7 @@ module.exports = {
3025
throw err
3126
}
3227

33-
cid(nodeA, (err, result) => {
28+
dagPB.util.cid(nodeA, (err, result) => {
3429
if (err) {
3530
throw err
3631
}
@@ -39,18 +34,12 @@ module.exports = {
3934

4035
ipfs.object.patch.addLink(argv.root, link, {
4136
enc: 'base58'
42-
}, (err, nodeB) => {
37+
}, (err, cid) => {
4338
if (err) {
4439
throw err
4540
}
4641

47-
cid(nodeB, (err, result) => {
48-
if (err) {
49-
throw err
50-
}
51-
52-
print(result.toBaseEncodedString(argv.cidBase))
53-
})
42+
print(cid.toBaseEncodedString(argv.cidBase))
5443
})
5544
})
5645
})

Diff for: src/cli/commands/object/patch/append-data.js

+2-13
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,16 @@ const debug = require('debug')
66
const log = debug('cli:object')
77
log.error = debug('cli:object:error')
88
const print = require('../../../utils').print
9-
const {
10-
util: {
11-
cid
12-
}
13-
} = require('ipld-dag-pb')
149

1510
function appendData (key, data, ipfs) {
1611
ipfs.object.patch.appendData(key, data, {
1712
enc: 'base58'
18-
}, (err, node) => {
13+
}, (err, cid) => {
1914
if (err) {
2015
throw err
2116
}
2217

23-
cid(node, (err, cid) => {
24-
if (err) {
25-
throw err
26-
}
27-
28-
print(cid.toBaseEncodedString())
29-
})
18+
print(cid.toBaseEncodedString())
3019
})
3120
}
3221

Diff for: src/cli/commands/object/patch/rm-link.js

+2-13
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@ const debug = require('debug')
44
const log = debug('cli:object')
55
log.error = debug('cli:object:error')
66
const print = require('../../../utils').print
7-
const {
8-
util: {
9-
cid
10-
}
11-
} = require('ipld-dag-pb')
127

138
module.exports = {
149
command: 'rm-link <root> <link>',
@@ -25,18 +20,12 @@ module.exports = {
2520
handler (argv) {
2621
argv.ipfs.object.patch.rmLink(argv.root, { name: argv.link }, {
2722
enc: 'base58'
28-
}, (err, node) => {
23+
}, (err, cid) => {
2924
if (err) {
3025
throw err
3126
}
3227

33-
cid(node, (err, cid) => {
34-
if (err) {
35-
throw err
36-
}
37-
38-
print(cid.toBaseEncodedString(argv.cidBase))
39-
})
28+
print(cid.toBaseEncodedString(argv.cidBase))
4029
})
4130
}
4231
}

Diff for: src/cli/commands/object/patch/set-data.js

+2-13
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,16 @@ const debug = require('debug')
66
const log = debug('cli:object')
77
log.error = debug('cli:object:error')
88
const print = require('../../../utils').print
9-
const {
10-
util: {
11-
cid
12-
}
13-
} = require('ipld-dag-pb')
149

1510
function parseAndAddNode (key, data, ipfs) {
1611
ipfs.object.patch.setData(key, data, {
1712
enc: 'base58'
18-
}, (err, node) => {
13+
}, (err, cid) => {
1914
if (err) {
2015
throw err
2116
}
2217

23-
cid(node, (err, cid) => {
24-
if (err) {
25-
throw err
26-
}
27-
28-
print(cid.toBaseEncodedString())
29-
})
18+
print(cid.toBaseEncodedString())
3019
})
3120
}
3221

Diff for: src/cli/commands/object/put.js

+2-13
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,14 @@
33
const bl = require('bl')
44
const fs = require('fs')
55
const print = require('../../utils').print
6-
const {
7-
util: {
8-
cid
9-
}
10-
} = require('ipld-dag-pb')
116

127
function putNode (buf, enc, ipfs, cidEnc) {
13-
ipfs.object.put(buf, { enc: enc }, (err, node) => {
8+
ipfs.object.put(buf, { enc: enc }, (err, cid) => {
149
if (err) {
1510
throw err
1611
}
1712

18-
cid(node, (err, cid) => {
19-
if (err) {
20-
throw err
21-
}
22-
23-
print(`added ${cid.toBaseEncodedString(cidEnc)}`)
24-
})
13+
print(`added ${cid.toBaseEncodedString(cidEnc)}`)
2514
})
2615
}
2716

Diff for: src/cli/commands/object/stat.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ module.exports = {
1717
throw err
1818
}
1919

20-
delete stats.Hash // only for js-ipfs-api output
20+
delete stats.Hash // only for js-ipfs-http-client output
2121

2222
Object.keys(stats).forEach((key) => {
2323
print(`${key}: ${stats[key]}`)

Diff for: src/cli/utils.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ function getAPICtl (apiAddr) {
3535
apiAddr = multiaddr(fs.readFileSync(apiPath).toString()).toString()
3636
}
3737
// Required inline to reduce startup time
38-
const APIctl = require('ipfs-api')
38+
const APIctl = require('ipfs-http-client')
3939
return APIctl(apiAddr)
4040
}
4141

Diff for: src/core/components/files-regular.js

+16-8
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const waterfall = require('async/waterfall')
1414
const isStream = require('is-stream')
1515
const isSource = require('is-pull-stream').isSource
1616
const Duplex = require('readable-stream').Duplex
17-
const OtherBuffer = require('buffer').Buffer
17+
const isString = require('lodash/isString')
1818
const CID = require('cids')
1919
const toB58String = require('multihashes').toB58String
2020
const errCode = require('err-code')
@@ -292,15 +292,23 @@ module.exports = function (self) {
292292

293293
options = options || {}
294294

295-
const ok = Buffer.isBuffer(data) ||
296-
isStream.readable(data) ||
297-
Array.isArray(data) ||
298-
OtherBuffer.isBuffer(data) ||
299-
typeof data === 'object' ||
300-
isSource(data)
295+
// Buffer, pull stream or Node.js stream
296+
const isBufferOrStream = obj => Buffer.isBuffer(obj) || isStream.readable(obj) || isSource(obj)
297+
// An object like { content?, path? }, where content isBufferOrStream and path isString
298+
const isContentObject = obj => {
299+
if (typeof obj !== 'object') return false
300+
// path is optional if content is present
301+
if (obj.content) return isBufferOrStream(obj.content)
302+
// path must be a non-empty string if no content
303+
return Boolean(obj.path) && isString(obj.path)
304+
}
305+
// An input atom: a buffer, stream or content object
306+
const isInput = obj => isBufferOrStream(obj) || isContentObject(obj)
307+
// All is ok if data isInput or data is an array of isInput
308+
const ok = isInput(data) || (Array.isArray(data) && data.every(isInput))
301309

302310
if (!ok) {
303-
return callback(new Error('first arg must be a buffer, readable stream, pull stream, an object or array of objects'))
311+
return callback(new Error('invalid input: expected buffer, readable stream, pull stream, object or array of objects'))
304312
}
305313

306314
// CID v0 is for multihashes encoded with sha2-256

0 commit comments

Comments
 (0)