ipfs-http-client
Version:
A client library for the IPFS HTTP API
68 lines (55 loc) • 1.62 kB
JavaScript
const { CID } = require('multiformats/cid')
const errCode = require('err-code')
/**
* @typedef {import('ipfs-core-types/src/utils').AbortOptions} AbortOptions
*/
/**
* Retrieves IPLD Nodes along the `path` that is rooted at `cid`.
*
* @param {CID} cid - the CID where the resolving starts
* @param {string} path - the path that should be resolved
* @param {import('ipfs-core-utils/src/multicodecs')} codecs
* @param {(cid: CID, options?: AbortOptions) => Promise<Uint8Array>} getBlock
* @param {AbortOptions} [options]
*/
const resolve = async function * (cid, path, codecs, getBlock, options) {
/**
* @param {CID} cid
*/
const load = async (cid) => {
const codec = await codecs.getCodec(cid.code)
const block = await getBlock(cid, options)
return codec.decode(block)
}
const parts = path.split('/').filter(Boolean)
let value = await load(cid)
let lastCid = cid
if (!parts.length) {
yield {
value,
remainderPath: ''
}
}
// End iteration if there isn't a CID to follow any more
while (parts.length) {
const key = parts.shift()
if (!key) {
throw errCode(new Error(`Could not resolve path "${path}"`), 'ERR_INVALID_PATH')
}
if (Object.prototype.hasOwnProperty.call(value, key)) {
value = value[key]
yield {
value,
remainderPath: parts.join('/')
}
} else {
throw errCode(new Error(`no link named "${key}" under ${lastCid}`), 'ERR_NO_LINK')
}
if (value instanceof CID) {
lastCid = value
value = await load(value)
}
}
}
module.exports = resolve