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

Commit ac2e7e0

Browse files
committed
fix: add support for resolving to the middle of an IPLD block
see: ipfs-inactive/interface-js-ipfs-core#385
1 parent 47e2b9e commit ac2e7e0

File tree

2 files changed

+70
-16
lines changed

2 files changed

+70
-16
lines changed

src/core/components/resolve.js

+13-16
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,15 @@ module.exports = (self) => {
3434

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

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

4443
// Resolve the given CID + path to a CID.
4544
function resolve (cid, path, callback) {
46-
let value
47-
45+
let value, remainder
4846
doUntil(
4947
(cb) => {
5048
self.block.get(cid, (err, block) => {
@@ -59,28 +57,27 @@ module.exports = (self) => {
5957
r.resolver.resolve(block.data, path, (err, result) => {
6058
if (err) return cb(err)
6159
value = result.value
62-
path = result.remainderPath
60+
remainder = result.remainderPath
6361
cb()
6462
})
6563
})
6664
},
6765
() => {
68-
const endReached = !path || path === '/'
69-
70-
if (endReached) {
71-
return true
72-
}
73-
74-
if (value) {
66+
if (value && value['/']) {
67+
// If we've hit a CID, replace the current CID.
7568
cid = new CID(value['/'])
69+
path = remainder
70+
} else {
71+
// We've hit a value. Return the current CID and the remaining path.
72+
return true
7673
}
7774

78-
return false
75+
// Continue resolving unless the path is empty.
76+
return !path || path === '/'
7977
},
8078
(err) => {
8179
if (err) return callback(err)
82-
if (value && value['/']) return callback(null, new CID(value['/']))
83-
callback()
80+
callback(null, cid, path)
8481
}
8582
)
8683
}

test/core/resolve.spec.js

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* eslint max-nested-callbacks: ["error", 8] */
2+
/* eslint-env mocha */
3+
'use strict'
4+
5+
const chai = require('chai')
6+
const dirtyChai = require('dirty-chai')
7+
const expect = chai.expect
8+
chai.use(dirtyChai)
9+
10+
const IPFSFactory = require('ipfsd-ctl')
11+
const IPFS = require('../../src/core')
12+
13+
describe('resolve', () => {
14+
let ipfsd, ipfs
15+
16+
before(function (done) {
17+
this.timeout(20 * 1000)
18+
19+
const factory = IPFSFactory.create({ type: 'proc' })
20+
21+
factory.spawn({
22+
exec: IPFS,
23+
initOptions: { bits: 512 },
24+
config: { Bootstrap: [] }
25+
}, (err, _ipfsd) => {
26+
expect(err).to.not.exist()
27+
ipfsd = _ipfsd
28+
ipfs = _ipfsd.api
29+
done()
30+
})
31+
})
32+
33+
after((done) => {
34+
if (ipfsd) {
35+
ipfsd.stop(done)
36+
} else {
37+
done()
38+
}
39+
})
40+
41+
it('should resolve an IPFS path non-link', (done) => {
42+
const content = { path: { to: { file: 'foobar' } } }
43+
const options = { format: 'dag-cbor', hashAlg: 'sha2-256' }
44+
45+
ipfs.dag.put(content, options, (err, cid) => {
46+
expect(err).to.not.exist()
47+
48+
// FIXME: This should be /ipld/... but that's not supported yet.
49+
const path = `/ipfs/${cid.toBaseEncodedString()}/path/to/file`
50+
ipfs.resolve(path, (err, resolved) => {
51+
expect(err).to.not.exist()
52+
expect(resolved).to.equal(path)
53+
done()
54+
})
55+
})
56+
})
57+
})

0 commit comments

Comments
 (0)