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

Commit

Permalink
fix: add support for resolving to the middle of an IPLD block
Browse files Browse the repository at this point in the history
  • Loading branch information
Stebalien committed Feb 6, 2019
1 parent 47e2b9e commit ac2e7e0
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 16 deletions.
29 changes: 13 additions & 16 deletions src/core/components/resolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,15 @@ module.exports = (self) => {

const path = split.slice(3).join('/')

resolve(cid, path, (err, cid) => {
resolve(cid, path, (err, cid, remainder) => {
if (err) return cb(err)
if (!cid) return cb(new Error('found non-link at given path'))
cb(null, `/ipfs/${cidToString(cid, { base: opts.cidBase })}`)
cb(null, `/ipfs/${cidToString(cid, { base: opts.cidBase })}${remainder ? '/' + remainder : ''}`)
})
})

// Resolve the given CID + path to a CID.
function resolve (cid, path, callback) {
let value

let value, remainder
doUntil(
(cb) => {
self.block.get(cid, (err, block) => {
Expand All @@ -59,28 +57,27 @@ module.exports = (self) => {
r.resolver.resolve(block.data, path, (err, result) => {
if (err) return cb(err)
value = result.value
path = result.remainderPath
remainder = result.remainderPath
cb()
})
})
},
() => {
const endReached = !path || path === '/'

if (endReached) {
return true
}

if (value) {
if (value && value['/']) {
// If we've hit a CID, replace the current CID.
cid = new CID(value['/'])
path = remainder
} else {
// We've hit a value. Return the current CID and the remaining path.
return true
}

return false
// Continue resolving unless the path is empty.
return !path || path === '/'
},
(err) => {
if (err) return callback(err)
if (value && value['/']) return callback(null, new CID(value['/']))
callback()
callback(null, cid, path)
}
)
}
Expand Down
57 changes: 57 additions & 0 deletions test/core/resolve.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* eslint max-nested-callbacks: ["error", 8] */
/* eslint-env mocha */
'use strict'

const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)

const IPFSFactory = require('ipfsd-ctl')
const IPFS = require('../../src/core')

describe('resolve', () => {
let ipfsd, ipfs

before(function (done) {
this.timeout(20 * 1000)

const factory = IPFSFactory.create({ type: 'proc' })

factory.spawn({
exec: IPFS,
initOptions: { bits: 512 },
config: { Bootstrap: [] }
}, (err, _ipfsd) => {
expect(err).to.not.exist()
ipfsd = _ipfsd
ipfs = _ipfsd.api
done()
})
})

after((done) => {
if (ipfsd) {
ipfsd.stop(done)
} else {
done()
}
})

it('should resolve an IPFS path non-link', (done) => {
const content = { path: { to: { file: 'foobar' } } }
const options = { format: 'dag-cbor', hashAlg: 'sha2-256' }

ipfs.dag.put(content, options, (err, cid) => {
expect(err).to.not.exist()

// FIXME: This should be /ipld/... but that's not supported yet.
const path = `/ipfs/${cid.toBaseEncodedString()}/path/to/file`
ipfs.resolve(path, (err, resolved) => {
expect(err).to.not.exist()
expect(resolved).to.equal(path)
done()
})
})
})
})

0 comments on commit ac2e7e0

Please sign in to comment.