Skip to content
This repository has been archived by the owner on Mar 10, 2020. It is now read-only.

Commit

Permalink
refactor: object API write methods return CIDs
Browse files Browse the repository at this point in the history
Since `ipld-dag-pb` removed `multihash` and `cid` properties, the Object API became less useful, returning the data you provided it when you call methods that write DAG nodes. This meant the user had to calculate the CID manually.

This PR updates the Object API so that write methods return CID instances instead of DAG nodes.

See discussion here for more context: #388 (review)

License: MIT
Signed-off-by: Alan Shaw <alan.shaw@protocol.ai>
  • Loading branch information
alanshaw committed Nov 27, 2018
1 parent 5d09dd2 commit bf2c763
Show file tree
Hide file tree
Showing 13 changed files with 281 additions and 433 deletions.
70 changes: 35 additions & 35 deletions SPEC/OBJECT.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,22 @@
##### `Go` **WIP**

##### `JavaScript` - ipfs.object.new([template][, callback])
##### `JavaScript` - ipfs.object.new([template], [callback])

`template` if defined, must be a string `unixfs-dir` and if that is passed, the created node will be an empty unixfs style directory.

`callback` must follow `function (err, node) {}` signature, where `err` is an error if the operation was not successful and `node` is a MerkleDAG node of the type [DAGNode][]
`callback` must follow `function (err, cid) {}` signature, where `err` is an error if the operation was not successful and `cid` is an instance of [CID][].

If no `callback` is passed, a [promise][] is returned.

**Example:**

```JavaScript
ipfs.object.new('unixfs-dir', (err, node) => {
ipfs.object.new('unixfs-dir', (err, cid) => {
if (err) {
throw err
}
console.log(node.toJSON().multihash)
console.log(cid.toString())
// Logs:
// QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn
})
Expand All @@ -46,7 +46,7 @@ A great source of [examples][] can be found in the tests for this API.
##### `Go` **WIP**

##### `JavaScript` - ipfs.object.put(obj, [options, callback])
##### `JavaScript` - ipfs.object.put(obj, [options], [callback])

`obj` is the MerkleDAG Node to be stored. Can of type:

Expand All @@ -58,7 +58,7 @@ A great source of [examples][] can be found in the tests for this API.

- `enc`, the encoding of the Buffer (json, yml, etc), if passed a Buffer.

`callback` must follow `function (err, node) {}` signature, where `err` is an error if the operation was not successful and `node` is a MerkleDAG node of the type [DAGNode][]
`callback` must follow `function (err, cid) {}` signature, where `err` is an error if the operation was not successful and `cid` is an instance of [CID][].

If no `callback` is passed, a [promise][] is returned.

Expand All @@ -70,11 +70,11 @@ const obj = {
Links: []
}

ipfs.object.put(obj, (err, node) => {
ipfs.object.put(obj, (err, cid) => {
if (err) {
throw err
}
console.log(node.toJSON().multihash)
console.log(cid.toString())
// Logs:
// QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK
})
Expand All @@ -88,7 +88,7 @@ A great source of [examples][] can be found in the tests for this API.
##### `Go` **WIP**

##### `JavaScript` - ipfs.object.get(multihash, [options, callback])
##### `JavaScript` - ipfs.object.get(multihash, [options], [callback])

`multihash` is a [multihash][] which can be passed as:

Expand All @@ -112,9 +112,9 @@ ipfs.object.get(multihash, (err, node) => {
if (err) {
throw err
}
console.log(node.toJSON().multihash)
console.log(node.data)
// Logs:
// QmPb5f92FxKPYdT3QNBd1GKiL4tZUXUrzF4Hkpdr3Gf1gK
// some data
})
```

Expand All @@ -126,7 +126,7 @@ A great source of [examples][] can be found in the tests for this API.
##### `Go` **WIP**

##### `JavaScript` - ipfs.object.data(multihash, [options, callback])
##### `JavaScript` - ipfs.object.data(multihash, [options], [callback])
`multihash` is a [multihash][] which can be passed as:

- Buffer, the raw Buffer of the multihash (or of and encoded version)
Expand Down Expand Up @@ -163,7 +163,7 @@ A great source of [examples][] can be found in the tests for this API.
##### `Go` **WIP**

##### `JavaScript` - ipfs.object.links(multihash, [options, callback])
##### `JavaScript` - ipfs.object.links(multihash, [options], [callback])

`multihash` is a [multihash][] which can be passed as:

Expand Down Expand Up @@ -201,7 +201,7 @@ A great source of [examples][] can be found in the tests for this API.
##### `Go` **WIP**

##### `JavaScript` - ipfs.object.stat(multihash, [options, callback])
##### `JavaScript` - ipfs.object.stat(multihash, [options], [callback])

`multihash` is a [multihash][] which can be passed as:

Expand Down Expand Up @@ -261,7 +261,7 @@ A great source of [examples][] can be found in the tests for this API.
###### `Go` **WIP**

###### `JavaScript` - ipfs.object.patch.addLink(multihash, link, [options, callback])
###### `JavaScript` - ipfs.object.patch.addLink(multihash, link, [options], [callback])

`multihash` is a [multihash][] which can be passed as:

Expand Down Expand Up @@ -290,7 +290,7 @@ const link = new DAGLink(name, size, multihash)

- `enc`, the encoding of multihash (base58, base64, etc), if any.

`callback` must follow `function (err, node) {}` signature, where `err` is an error if the operation was not successful and `node` is a MerkleDAG node of the type [DAGNode][] that resulted by the operation of adding a Link.
`callback` must follow `function (err, cid) {}` signature, where `err` is an error if the operation was not successful and `cid` is an instance of [CID][] - the CID of the new DAG node that was created due to the operation.

If no `callback` is passed, a [promise][] is returned.

Expand All @@ -301,11 +301,11 @@ ipfs.object.patch.addLink(node, {
name: 'some-link'
size: 10
multihash: 'QmPTkMuuL6PD8L2SwTwbcs1NPg14U8mRzerB1ZrrBrkSDD'
}, (err, newNode) => {
}, (err, cid) => {
if (err) {
throw err
}
// newNode is node with the added link
// cid is CID of the DAG node created by adding a link
})
```

Expand All @@ -317,34 +317,34 @@ A great source of [examples][] can be found in the tests for this API.
###### `Go` **WIP**

###### `JavaScript` - ipfs.object.patch.rmLink(multihash, link, [options, callback])
###### `JavaScript` - ipfs.object.patch.rmLink(multihash, link, [options], [callback])

`multihash` is a [multihash][] which can be passed as:

- Buffer, the raw Buffer of the multihash (or of and encoded version)
- String, the toString version of the multihash (or of an encoded version)

`link` is the link to be removed on the node that is identified by the `multihash`, can be passed as:

- `DAGLink`
- Object containing name property

```js
const link = {
name: 'Qmef7ScwzJUCg1zUSrCmPAz45m8uP5jU7SLgt2EffjBmbL'
};
```
```js
const link = new DAGLink(name, size, multihash)
```

or
- Object containing a `name` property

```js
const link = new DAGLink(name, size, multihash)
```js
const link = {
name: 'Qmef7ScwzJUCg1zUSrCmPAz45m8uP5jU7SLgt2EffjBmbL'
};
```

`options` is a optional argument of type object, that can contain the following properties:

- `enc`, the encoding of multihash (base58, base64, etc), if any.

`callback` must follow `function (err, node) {}` signature, where `err` is an error if the operation was not successful and `node` is a MerkleDAG node of the type [DAGNode][] that resulted by the operation of adding a Link.
`callback` must follow `function (err, cid) {}` signature, where `err` is an error if the operation was not successful and `cid` is an instance of [CID][] - the CID of the new DAG node that was created due to the operation.

If no `callback` is passed, a [promise][] is returned.

Expand All @@ -361,7 +361,7 @@ A great source of [examples][] can be found in the tests for this API.

###### `Go` **WIP**

###### `JavaScript` - ipfs.object.patch.appendData(multihash, data, [options, callback])
###### `JavaScript` - ipfs.object.patch.appendData(multihash, data, [options], [callback])

`multihash` is a [multihash][] which can be passed as:

Expand All @@ -374,7 +374,7 @@ A great source of [examples][] can be found in the tests for this API.

- `enc`, the encoding of multihash (base58, base64, etc), if any.

`callback` must follow `function (err, node) {}` signature, where `err` is an error if the operation was not successful and `node` is a MerkleDAG node of the type [DAGNode][] that resulted by the operation of adding a Link.
`callback` must follow `function (err, cid) {}` signature, where `err` is an error if the operation was not successful and `cid` is an instance of [CID][] - the CID of the new DAG node that was created due to the operation.

If no `callback` is passed, a [promise][] is returned.

Expand All @@ -396,7 +396,7 @@ A great source of [examples][] can be found in the tests for this API.

###### `Go` **WIP**

###### `JavaScript` - ipfs.object.patch.setData(multihash, data, [options, callback])
###### `JavaScript` - ipfs.object.patch.setData(multihash, data, [options], [callback])

`multihash` is a [multihash][] which can be passed as:

Expand All @@ -409,23 +409,23 @@ A great source of [examples][] can be found in the tests for this API.

- `enc`, the encoding of multihash (base58, base64, etc), if any.

`callback` must follow `function (err, node) {}` signature, where `err` is an error if the operation was not successful and `node` is a MerkleDAG node of the type [DAGNode][] that resulted by the operation of adding a Link.
`callback` must follow `function (err, cid) {}` signature, where `err` is an error if the operation was not successful and `cid` is an instance of [CID][] - the CID of the new DAG node that was created due to the operation.

If no `callback` is passed, a [promise][] is returned.

**Example:**

```JavaScript
ipfs.object.patch.setData(multihash, new Buffer('more data'), (err, node) => {
ipfs.object.patch.setData(multihash, new Buffer('more data'), (err, cid) => {
if (err) {
throw err
}
})

```

A great source of [examples][] can be found in the tests for this API.

[CID]: https://github.com/multiformats/js-cid
[DAGNode]: https://github.com/ipld/js-ipld-dag-pb
[multihash]: http://github.com/multiformats/multihash
[promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
Expand Down
4 changes: 1 addition & 3 deletions SPEC/TYPES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,4 @@ A set of data types are exposed directly from the IPFS instance under `ipfs.type
- [`ipfs.types.multiaddr`](https://github.com/multiformats/js-multiaddr)
- [`ipfs.types.multibase`](https://github.com/multiformats/multibase)
- [`ipfs.types.multihash`](https://github.com/multiformats/js-multihash)
- [`ipfs.types.CID`](https://github.com/ipld/js-cid)
- [`ipfs.types.dagPB`](https://github.com/ipld/js-ipld-dag-pb)
- [`ipfs.types.dagCBOR`](https://github.com/ipld/js-ipld-dag-cbor)
- [`ipfs.types.CID`](https://github.com/multiformats/js-cid)
74 changes: 29 additions & 45 deletions js/src/object/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
const bs58 = require('bs58')
const hat = require('hat')
const { getDescribe, getIt, expect } = require('../utils/mocha')
const {
calculateCid
} = require('../utils/dag-pb')

module.exports = (createCommon, options) => {
const describe = getDescribe(options)
Expand Down Expand Up @@ -42,23 +39,19 @@ module.exports = (createCommon, options) => {
Links: []
}

ipfs.object.put(testObj, (err, node) => {
ipfs.object.put(testObj, (err, nodeCid) => {
expect(err).to.not.exist()

calculateCid(node, (err, nodeCid) => {
ipfs.object.data(nodeCid, (err, data) => {
expect(err).to.not.exist()

ipfs.object.data(nodeCid, (err, data) => {
expect(err).to.not.exist()

// because js-ipfs-api can't infer
// if the returned Data is Buffer or String
if (typeof data === 'string') {
data = Buffer.from(data)
}
expect(node.data).to.eql(data)
done()
})
// because js-ipfs-api can't infer
// if the returned Data is Buffer or String
if (typeof data === 'string') {
data = Buffer.from(data)
}
expect(testObj.Data).to.eql(data)
done()
})
})
})
Expand All @@ -69,16 +62,15 @@ module.exports = (createCommon, options) => {
Links: []
}

const node = await ipfs.object.put(testObj)
const nodeCid = await calculateCid(node)
const nodeCid = await ipfs.object.put(testObj)
let data = await ipfs.object.data(nodeCid)

// because js-ipfs-api can't infer
// if the returned Data is Buffer or String
if (typeof data === 'string') {
data = Buffer.from(data)
}
expect(node.data).to.deep.equal(data)
expect(testObj.Data).to.deep.equal(data)
})

it('should get data by base58 encoded multihash', (done) => {
Expand All @@ -87,23 +79,19 @@ module.exports = (createCommon, options) => {
Links: []
}

ipfs.object.put(testObj, (err, node) => {
ipfs.object.put(testObj, (err, nodeCid) => {
expect(err).to.not.exist()

calculateCid(node, (err, nodeCid) => {
ipfs.object.data(bs58.encode(nodeCid.buffer), { enc: 'base58' }, (err, data) => {
expect(err).to.not.exist()

ipfs.object.data(bs58.encode(nodeCid.buffer), { enc: 'base58' }, (err, data) => {
expect(err).to.not.exist()

// because js-ipfs-api can't infer
// if the returned Data is Buffer or String
if (typeof data === 'string') {
data = Buffer.from(data)
}
expect(node.data).to.eql(data)
done()
})
// because js-ipfs-api can't infer
// if the returned Data is Buffer or String
if (typeof data === 'string') {
data = Buffer.from(data)
}
expect(testObj.Data).to.eql(data)
done()
})
})
})
Expand All @@ -114,23 +102,19 @@ module.exports = (createCommon, options) => {
Links: []
}

ipfs.object.put(testObj, (err, node) => {
ipfs.object.put(testObj, (err, nodeCid) => {
expect(err).to.not.exist()

calculateCid(node, (err, nodeCid) => {
ipfs.object.data(bs58.encode(nodeCid.buffer).toString(), { enc: 'base58' }, (err, data) => {
expect(err).to.not.exist()

ipfs.object.data(bs58.encode(nodeCid.buffer).toString(), { enc: 'base58' }, (err, data) => {
expect(err).to.not.exist()

// because js-ipfs-api can't infer if the
// returned Data is Buffer or String
if (typeof data === 'string') {
data = Buffer.from(data)
}
expect(node.data).to.eql(data)
done()
})
// because js-ipfs-api can't infer if the
// returned Data is Buffer or String
if (typeof data === 'string') {
data = Buffer.from(data)
}
expect(testObj.Data).to.eql(data)
done()
})
})
})
Expand Down
Loading

0 comments on commit bf2c763

Please sign in to comment.