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

fix: add support for resolving links by name #78

Merged
merged 4 commits into from
Jul 20, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ lib-cov

# Coverage directory used by tools like istanbul
coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
Expand Down
34 changes: 29 additions & 5 deletions src/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,14 @@ exports.resolve = (binaryBlob, path, callback) => {
// for the resolver
node.links.forEach((l, i) => {
const link = l.toJSON()
values[i] = {
// TODO by enabling something to resolve through link name, we are
// applying a transformation (a view) to the data, confirm if this
// is exactly what we want
values[i] = values[link.name] = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think values[link.name] is needed here. The case is handled below.

Please also remove the "TODO".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was already in the code base although I don't think it was working correctly:

// TODO by enabling something to resolve through link name, we are
// applying a transformation (a view) to the data, confirm if this
// is exactly what we want
values[link.name] = link.multihash

It allows you to reference links by name via Links e.g. /ipfs/QmHash/Links/myNamedLink

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. So this is kind of the IPFS vs. IPLD like traversal.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't know if it's really necessary to be able to /ipfs/QmHash/Links/myNamedLink as well as /ipfs/QmHash/myNamedLink but the former was already there and we're adding the latter.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/ipfs/QmHash/Links/myNamedLink is what I call IPLD-like traversal. It will then be use if you use the /ipld prefix.

hash: link.multihash,
name: link.name,
size: link.size
}
// TODO by enabling something to resolve through link name, we are
// applying a transformation (a view) to the data, confirm if this
// is exactly what we want
values[link.name] = link.multihash
})

let value = values[split[1]]
Expand All @@ -74,6 +73,31 @@ exports.resolve = (binaryBlob, path, callback) => {
} else if (split[0] === 'Data') {
cb(null, { value: node.data, remainderPath: '' })
} else {
const values = {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add a comment saying that this is the case of a named link? It took me a while to figure that out.


// populate both index number and name to enable both cases
// for the resolver
node.links.forEach((l, i) => {
const link = l.toJSON()
// TODO by enabling something to resolve through link name, we are
// applying a transformation (a view) to the data, confirm if this
// is exactly what we want
values[i] = values[link.name] = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assignment to values[i] is not needed here and I find it rather confusing.

Please remote the comments/change them to make the saying the right thing.

hash: link.multihash,
name: link.name,
size: link.size
}
})

const value = values[split[0]]

if (value) {
return cb(null, {
value: { '/': value.hash },
remainderPath: split.slice(1).join('/')
})
}

cb(new Error('path not available'))
}
}
Expand Down
9 changes: 9 additions & 0 deletions test/resolver.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,15 @@ describe('IPLD Format resolver (local)', () => {
})
})

it('links by name', (done) => {
resolver.resolve(linksNodeBlob, 'named link', (err, result) => {
expect(err).to.not.exist()
expect(result.value['/']).to.eql(links[1].multihash)
expect(result.remainderPath).to.eql('')
done()
})
})

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add tests for:

  • named link and a remainder path
  • error case for non-existent named link

it('yield remainderPath if impossible to resolve through (a)', (done) => {
resolver.resolve(linksNodeBlob, 'Links/1/Hash/Data', (err, result) => {
expect(err).to.not.exist()
Expand Down