Skip to content
This repository was archived by the owner on Aug 11, 2021. It is now read-only.

Commit

Permalink
fix: use binary blobs directly
Browse files Browse the repository at this point in the history
IPLD shouldn't need to know about IPFS. Hence work directly with
the binary data instead of using an IPFS block.

This is part of ipld/interface-ipld-format#21

BREAKING CHANGE: Everyone calling the functions of `resolve` need to
pass in the binary data instead of an IPFS block.

So if your input is an IPFS block, the code changes from

    resolver.resolve(block, path, (err, result) => {…}

to

    resolver.resolve(block.data, path, (err, result) => {…}
  • Loading branch information
vmx committed Feb 12, 2018
1 parent 218f094 commit 50edc45
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 35 deletions.
19 changes: 10 additions & 9 deletions src/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ exports = module.exports
exports.multicodec = 'dag-pb'

/*
* resolve: receives a path and a block and returns the value on path,
* throw if not possible. `block` is an IPFS Block instance (contains data+key)
* resolve: receives a path and a binary blob and returns the value on path,
* throw if not possible. `binaryBlob` is the ProtocolBuffer encoded data.
*/
exports.resolve = (block, path, callback) => {
exports.resolve = (binaryBlob, path, callback) => {
waterfall([
(cb) => util.deserialize(block.data, cb),
(cb) => util.deserialize(binaryBlob, cb),
(node, cb) => {
const split = path.split('/')

Expand Down Expand Up @@ -75,15 +75,15 @@ exports.resolve = (block, path, callback) => {
* tree: returns a flattened array with paths: values of the project. options
* is an object that can carry several options (i.e. nestness)
*/
exports.tree = (block, options, callback) => {
exports.tree = (binaryBlob, options, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
}

options = options || {}

util.deserialize(block.data, (err, node) => {
util.deserialize(binaryBlob, (err, node) => {
if (err) {
return callback(err)
}
Expand All @@ -105,10 +105,11 @@ exports.tree = (block, options, callback) => {
}

/*
* isLink: returns the Link if a given path in a block is a Link, false otherwise
* isLink: returns the Link if a given path in a binary blob is a Link,
* false otherwise
*/
exports.isLink = (block, path, callback) => {
exports.resolve(block, path, (err, result) => {
exports.isLink = (binaryBlob, path, callback) => {
exports.resolve(binaryBlob, path, (err, result) => {
if (err) {
return callback(err)
}
Expand Down
51 changes: 25 additions & 26 deletions test/resolver.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@ const expect = chai.expect
chai.use(dirtyChai)
const parallel = require('async/parallel')
const CID = require('cids')
const Block = require('ipfs-block')
const waterfall = require('async/waterfall')

const dagPB = require('../src')
const DAGNode = dagPB.DAGNode
const resolver = dagPB.resolver

describe('IPLD Format resolver (local)', () => {
let emptyNodeBlock
let linksNodeBlock
let dataLinksNodeBlock
let emptyNodeBlob
let linksNodeBlob
let dataLinksNodeBlob

const links = [{
name: '',
Expand All @@ -33,7 +32,7 @@ describe('IPLD Format resolver (local)', () => {
const create = (data, links, callback) => waterfall([
(cb) => DAGNode.create(data, links, cb),
(n, cb) => {
cb(null, new Block(n.serialized, new CID(n.multihash)))
cb(null, n.serialized)
}
], callback)

Expand All @@ -44,9 +43,9 @@ describe('IPLD Format resolver (local)', () => {
(cb) => create(Buffer.from('aaah the data'), links, cb)
], (err, res) => {
expect(err).to.not.exist()
emptyNodeBlock = res[0]
linksNodeBlock = res[1]
dataLinksNodeBlock = res[2]
emptyNodeBlob = res[0]
linksNodeBlob = res[1]
dataLinksNodeBlob = res[2]
done()
})
})
Expand All @@ -58,7 +57,7 @@ describe('IPLD Format resolver (local)', () => {
describe('empty node', () => {
describe('resolver.resolve', () => {
it('links path', (done) => {
resolver.resolve(emptyNodeBlock, 'Links', (err, result) => {
resolver.resolve(emptyNodeBlob, 'Links', (err, result) => {
expect(err).to.not.exist()
expect(result.value).to.eql([])
expect(result.remainderPath).to.eql('')
Expand All @@ -67,7 +66,7 @@ describe('IPLD Format resolver (local)', () => {
})

it('data path', (done) => {
resolver.resolve(emptyNodeBlock, 'Data', (err, result) => {
resolver.resolve(emptyNodeBlob, 'Data', (err, result) => {
expect(err).to.not.exist()
expect(result.value).to.eql(Buffer.alloc(0))
expect(result.remainderPath).to.eql('')
Expand All @@ -76,15 +75,15 @@ describe('IPLD Format resolver (local)', () => {
})

it('non existent path', (done) => {
resolver.resolve(emptyNodeBlock, 'pathThatDoesNotExist', (err, result) => {
resolver.resolve(emptyNodeBlob, 'pathThatDoesNotExist', (err, result) => {
expect(err).to.exist()
done()
})
})
})

it('resolver.tree', (done) => {
resolver.tree(emptyNodeBlock, (err, paths) => {
resolver.tree(emptyNodeBlob, (err, paths) => {
expect(err).to.not.exist()
expect(paths).to.eql([
'Links',
Expand All @@ -98,7 +97,7 @@ describe('IPLD Format resolver (local)', () => {
describe('links node', () => {
describe('resolver.resolve', () => {
it('links path', (done) => {
resolver.resolve(linksNodeBlock, 'Links', (err, result) => {
resolver.resolve(linksNodeBlob, 'Links', (err, result) => {
expect(err).to.not.exist()
expect(result.value).to.eql(links)
expect(result.remainderPath).to.eql('')
Expand All @@ -107,7 +106,7 @@ describe('IPLD Format resolver (local)', () => {
})

it('links position path Hash', (done) => {
resolver.resolve(linksNodeBlock, 'Links/1/Hash', (err, result) => {
resolver.resolve(linksNodeBlob, 'Links/1/Hash', (err, result) => {
expect(err).to.not.exist()
expect(result.value['/']).to.eql(links[1].multihash)
expect(result.remainderPath).to.eql('')
Expand All @@ -116,7 +115,7 @@ describe('IPLD Format resolver (local)', () => {
})

it('links position path Name', (done) => {
resolver.resolve(linksNodeBlock, 'Links/1/Name', (err, result) => {
resolver.resolve(linksNodeBlob, 'Links/1/Name', (err, result) => {
expect(err).to.not.exist()
expect(result.value['/']).to.eql(links[1].name)
expect(result.remainderPath).to.eql('')
Expand All @@ -125,7 +124,7 @@ describe('IPLD Format resolver (local)', () => {
})

it('links position path Tsize', (done) => {
resolver.resolve(linksNodeBlock, 'Links/1/Tsize', (err, result) => {
resolver.resolve(linksNodeBlob, 'Links/1/Tsize', (err, result) => {
expect(err).to.not.exist()
expect(result.value['/']).to.eql(links[1].size)
expect(result.remainderPath).to.eql('')
Expand All @@ -134,7 +133,7 @@ describe('IPLD Format resolver (local)', () => {
})

it('yield remainderPath if impossible to resolve through (a)', (done) => {
resolver.resolve(linksNodeBlock, 'Links/1/Hash/Data', (err, result) => {
resolver.resolve(linksNodeBlob, 'Links/1/Hash/Data', (err, result) => {
expect(err).to.not.exist()
expect(result.value['/']).to.exist()
expect(result.value['/']).to.equal('QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V')
Expand All @@ -144,7 +143,7 @@ describe('IPLD Format resolver (local)', () => {
})

it('yield remainderPath if impossible to resolve through (b)', (done) => {
resolver.resolve(linksNodeBlock, 'Links/1/Hash/Links/0/Hash/Data', (err, result) => {
resolver.resolve(linksNodeBlob, 'Links/1/Hash/Links/0/Hash/Data', (err, result) => {
expect(err).to.not.exist()
expect(result.value['/'])
.to.equal('QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V')
Expand All @@ -156,7 +155,7 @@ describe('IPLD Format resolver (local)', () => {
})

it('resolver.tree', (done) => {
resolver.tree(linksNodeBlock, (err, paths) => {
resolver.tree(linksNodeBlob, (err, paths) => {
expect(err).to.not.exist()
expect(paths).to.eql([
'Links',
Expand All @@ -176,7 +175,7 @@ describe('IPLD Format resolver (local)', () => {
describe('links and data node', () => {
describe('resolver.resolve', (done) => {
it('links path', (done) => {
resolver.resolve(dataLinksNodeBlock, 'Links', (err, result) => {
resolver.resolve(dataLinksNodeBlob, 'Links', (err, result) => {
expect(err).to.not.exist()
expect(result.value).to.eql(links)
expect(result.remainderPath).to.eql('')
Expand All @@ -185,7 +184,7 @@ describe('IPLD Format resolver (local)', () => {
})

it('data path', (done) => {
resolver.resolve(dataLinksNodeBlock, 'Data', (err, result) => {
resolver.resolve(dataLinksNodeBlob, 'Data', (err, result) => {
expect(err).to.not.exist()
expect(result.value).to.eql(Buffer.from('aaah the data'))
expect(result.remainderPath).to.eql('')
Expand All @@ -194,15 +193,15 @@ describe('IPLD Format resolver (local)', () => {
})

it('non existent path', (done) => {
resolver.resolve(dataLinksNodeBlock, 'pathThatDoesNotExist', (err, result) => {
resolver.resolve(dataLinksNodeBlob, 'pathThatDoesNotExist', (err, result) => {
expect(err).to.exist()
done()
})
})
})

it('resolver.tree', (done) => {
resolver.tree(dataLinksNodeBlock, (err, paths) => {
resolver.tree(dataLinksNodeBlob, (err, paths) => {
expect(err).to.not.exist()
expect(paths).to.eql([
'Links',
Expand All @@ -220,7 +219,7 @@ describe('IPLD Format resolver (local)', () => {
})

it('resolver.isLink for valid CID', (done) => {
resolver.isLink(dataLinksNodeBlock, 'Links/0/Hash', (err, link) => {
resolver.isLink(dataLinksNodeBlob, 'Links/0/Hash', (err, link) => {
expect(err).to.not.exist()
expect(CID.isCID(new CID(link['/']))).to.equal(true)
done()
Expand All @@ -229,11 +228,11 @@ describe('IPLD Format resolver (local)', () => {

it('resolver.isLink for non valid CID', (done) => {
// blank value case
resolver.isLink(dataLinksNodeBlock, 'Links/0/Name', (err, link) => {
resolver.isLink(dataLinksNodeBlob, 'Links/0/Name', (err, link) => {
expect(err).to.not.exist()
expect(link).to.equal(false)
// non-blank value case
resolver.isLink(dataLinksNodeBlock, 'Links/0/Tsize', (err, link) => {
resolver.isLink(dataLinksNodeBlob, 'Links/0/Tsize', (err, link) => {
expect(err).to.not.exist()
expect(link).to.equal(false)
done()
Expand Down

0 comments on commit 50edc45

Please sign in to comment.