diff --git a/API/dag/README.md b/API/dag/README.md index ae5e3be006..03fdd7d640 100644 --- a/API/dag/README.md +++ b/API/dag/README.md @@ -1,6 +1,8 @@ dag API ======= +> The dag API comes to replace the `object API`, it support the creation and manipulation of dag-pb object, as well as other IPLD formats (i.e dag-cbor, ethereum-block, git, etc) + #### `dag.put` > Store an IPLD format node @@ -9,13 +11,10 @@ dag API ##### `JavaScript` - ipfs.dag.put(dagNode, formatMulticodec, hashAlg, callback) -`dagNode` - a DAG node that follows one of the supported IPLD formats. - -`formatMulticodec` - The IPLD format multicodec. - -`hashAlg` - The hash algorithm to be used over the serialized dagNode. - -`callback` must follow `function (err) {}` signature, where `err` is an error if the operation was not successful. +- `dagNode` - a DAG node that follows one of the supported IPLD formats. +- `formatMulticodec` - The IPLD format multicodec. +- `hashAlg` - The hash algorithm to be used over the serialized dagNode. +- `callback` must follow `function (err) {}` signature, where `err` is an error if the operation was not successful. If no `callback` is passed, a [promise][] is returned. @@ -25,10 +24,39 @@ If no `callback` is passed, a [promise][] is returned. ##### `Go` **WIP** -##### `JavaScript` - ipfs.object.get(cid, callback) +##### `JavaScript` - ipfs.dag.get(cid, callback) -`cid` is a [CID][https://github.com/ipfs/js-cid] instance. +- `cid` is a [CID][https://github.com/ipfs/js-cid] instance. `callback` must follow `function (err, dagNode) {}` signature, where `err` is an error if the operation was not successful and `dagNode` is the IPLD format DAG node retrieved. If no `callback` is passed, a [promise][] is returned. + +#### `dag.resolve` + +> Resolves an IPLD path + +##### `Go` **WIP** + +##### `JavaScript` - ipfs.dag.resolve(cid, path, callback) + +- `cid` is a [CID][https://github.com/ipfs/js-cid] instance. +- `path` is a String that represents a valid path to be resolved + +`callback` must follow `function (err, value) {}` signature, where `err` is an error if the operation was not successful and `value` is the value it was retrieved. + +If no `callback` is passed, a [promise][] is returned. + +#### `dag.remove` + +> Deletes an IPLD node + +##### `Go` **WIP** + +##### `JavaScript` - ipfs.dag.rm(cid, callback) + +- `cid` is a [CID][https://github.com/ipfs/js-cid] instance. + +`callback` must follow `function (err) {}` signature, where `err` is an error if the operation was not successful. + +If no `callback` is passed, a [promise][] is returned. diff --git a/src/dag.js b/src/dag.js new file mode 100644 index 0000000000..3a25a2d6bf --- /dev/null +++ b/src/dag.js @@ -0,0 +1,181 @@ +/* eslint-env mocha */ +/* eslint max-nested-callbacks: ["error", 8] */ + +'use strict' + +const expect = require('chai').expect +const dagPB = require('ipld-dag-pb') +const DAGNode = dagPB.DAGNode +const dagCBOR = require('ipld-dag-pb') +// const series = require('async/series') + +module.exports = (common) => { + describe.only('.dag', () => { + let ipfs + + before(function (done) { + // CI is slow + this.timeout(20 * 1000) + + common.setup((err, factory) => { + expect(err).to.not.exist + factory.spawnNode((err, node) => { + expect(err).to.not.exist + ipfs = node + done() + }) + }) + }) + + after((done) => { + common.teardown(done) + }) + + describe('callback API', () => { + let pbNode + let cborNode + + before((done) => { + const someData = new Buffer('some data') + + pbNode = DAGNode.create(someData, (err, node) => { + expect(err).to.not.exist + pbNode = node + done() + }) + + cborNode = { + data: someData + } + }) + + describe('.put', () => { + it('dag-pb with default hash func (sha2-256)', (done) => { + ipfs.dag.put(pbNode, 'dag-pb', 'sha2-256', done) + }) + + it.skip('dag-pb with custom hash func (sha3-512)', (done) => { + ipfs.dag.put(pbNode, 'dag-pb', 'sha3-512', done) + }) + + it.skip('dag-pb node with wrong multicodec', (done) => { + // This works because dag-cbor will just treat pbNode as a + // regular object + ipfs.dag.put(pbNode, 'dag-cbor', 'sha3-512', (err) => { + expect(err).to.exist + done() + }) + }) + + it('dag-cbor with default hash func (sha2-256)', (done) => { + ipfs.dag.put(cborNode, 'dag-cbor', 'sha2-256', done) + }) + + it.skip('dag-cbor with custom hash func (sha3-512)', (done) => { + ipfs.dag.put(cborNode, 'dag-cbor', 'sha3-512', done) + }) + + it('dag-cbor node with wrong multicodec', (done) => { + ipfs.dag.put(cborNode, 'dag-pb', 'sha3-512', (err) => { + expect(err).to.exist + done() + }) + }) + }) + + describe('.get', () => { + let pbNode + let cborNode + + before((done) => { + const someData = new Buffer('some other data') + + pbNode = DAGNode.create(someData, (err, node) => { + expect(err).to.not.exist + pbNode = node + done() + }) + + cborNode = { + data: someData + } + }) + + it('dag-pb node', (done) => { + ipfs.dag.put(pbNode, 'dag-pb', 'sha2-256', (err) => { + expect(err).to.not.exist + dagPB.util.cid(pbNode, (err, cid) => { + expect(err).to.not.exist + ipfs.dag.get(cid, (err, node) => { + expect(err).to.not.exist + expect(pbNode.toJSON()).to.eql(node.toJSON()) + done() + }) + }) + }) + }) + + it('dag-cbor node', (done) => { + ipfs.dag.put(cborNode, 'dag-cbor', 'sha2-256', (err) => { + expect(err).to.not.exist + dagCBOR.util.cid(cborNode, (err, cid) => { + expect(err).to.not.exist + ipfs.dag.get(cid, (err, node) => { + expect(err).to.not.exist + expect(cborNode).to.eql(node) + done() + }) + }) + }) + }) + }) + + describe('.resolve', () => { + it.skip('dag-pb local scope', (done) => {}) + it.skip('dag-pb one level', (done) => {}) + it.skip('dag-pb two levels', (done) => {}) + it.skip('dag-cbor local scope', (done) => {}) + it.skip('dag-cbor one level', (done) => {}) + it.skip('dag-cbor two levels', (done) => {}) + it.skip('from dag-pb to dag-cbor', (done) => {}) + it.skip('from dag-cbor to dag-pb', (done) => {}) + }) + + describe('.rm', () => { + let pbNode + + before((done) => { + const someData = new Buffer('some other data') + + pbNode = DAGNode.create(someData, (err, node) => { + expect(err).to.not.exist + pbNode = node + done() + }) + }) + + it('dag-pb node', (done) => { + ipfs.dag.put(pbNode, 'dag-pb', 'sha2-256', (err) => { + expect(err).to.not.exist + dagPB.util.cid(pbNode, (err, cid) => { + expect(err).to.not.exist + ipfs.dag.get(cid, (err, node) => { + expect(err).to.not.exist + ipfs.dag.rm(cid, done) + // TODO When we get timeouts in js-ipfs, try to fetch again + // and observe it timesout without the node + }) + }) + }) + }) + }) + }) + + describe('promise API', () => { + describe('.put', () => {}) + describe('.get', () => {}) + describe('.resolve', () => {}) + describe('.rm', () => {}) + }) + }) +} diff --git a/src/index.js b/src/index.js index 33865f9b6c..b69d0b6993 100644 --- a/src/index.js +++ b/src/index.js @@ -8,3 +8,4 @@ exports.generic = require('./generic') exports.swarm = require('./swarm') exports.block = require('./block') exports.dht = require('./dht') +exports.dag = require('./dag')