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

fix: ipfs get with raw blocks #3683

Merged
merged 6 commits into from
May 11, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
10 changes: 7 additions & 3 deletions packages/ipfs-cli/src/commands/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,20 @@ module.exports = {
throw new Error(`File prefix invalid, would write to files outside of ${output}, pass --force to override`)
}

if (file.type === 'file') {
if (file.type === 'file' || file.type === 'raw' ) {
await fs.promises.mkdir(path.join(output, path.dirname(file.path)), { recursive: true })
await pipe(
file.content,
map(chunk => chunk.slice()), // BufferList to Buffer
toIterable.sink(fs.createWriteStream(fullFilePath))
)
} else {
// this is a dir

} else if (file.type === 'dir') {
await fs.promises.mkdir(fullFilePath, { recursive: true })

} else {
// file.type === object | identity not supported yet
throw new Error(`Unknown node type ${file.type}`)
}
}
}
Expand Down
22 changes: 22 additions & 0 deletions packages/ipfs-cli/test/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,28 @@ describe('get', () => {
await clean(outPath)
})

it('should get file from a raw block', async () => {
const cid = new CID('bafkreifzjut3te2nhyekklss27nh3k72ysco7y32koao5eei66wof36n5e')
ipfs.get.withArgs(cid.toString(), defaultOptions).returns([{
type: 'raw',
path: 'bafkreifzjut3te2nhyekklss27nh3k72ysco7y32koao5eei66wof36n5e',
content: function * () {
yield buf
}
}])

const outPath = path.join(process.cwd(), cid.toString())
await clean(outPath)

const out = await cli(`get ${cid}`, { ipfs })
expect(out)
.to.equal(`Saving file(s) ${cid}\n`)

expect(fs.readFileSync(outPath)).to.deep.equal(buf)

await clean(outPath)
})

it('get file with output option', async () => {
ipfs.get.withArgs(cid.toString(), defaultOptions).returns([{
type: 'file',
Expand Down
28 changes: 16 additions & 12 deletions packages/ipfs-core/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,28 +103,32 @@ const mapFile = (file, options = {}) => {
name: file.name,
depth: file.path.split('/').length,
size: 0,
type: 'file'
type: file.type
Copy link
Member

@achingbrain achingbrain May 10, 2021

Choose a reason for hiding this comment

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

Types are broken - output has a type of IPFSEntry - IPFSEntry.type can only be 'dir' or 'file'. file.type has more possible values than that so the typecheck fails.

Copy link
Member Author

Choose a reason for hiding this comment

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

Just to check, should the value of output.type be file when file.type === 'raw' ?

Copy link
Member Author

Choose a reason for hiding this comment

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

ok so i guess I need to push the "can't deal with objects or identity" check down into mapFiles.

Copy link
Member

Choose a reason for hiding this comment

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

objects or identity

AFAIK these parts of UnixFS aren't used by anything.

should the value of output.type be file when file.type === 'raw'

Yes, unless go-ipfs does something different 🙂

}

if (file.type === 'file' || file.type === 'directory') {
// @ts-ignore - TS type can't be changed from File to Directory
output.type = file.type === 'directory' ? 'dir' : 'file'

if (file.type === 'file') {
output.size = file.unixfs.fileSize()
// @ts-ignore - TS type can't be changed from File to Directory
if (file.type === 'directory') {
output.type = 'dir'
}

if (options.includeContent) {
// @ts-expect-error - content is readonly
output.content = file.content()
}
}
if (file.type === 'file') {
output.size = file.unixfs.fileSize()
}

if (file.type === 'file' || file.type === 'directory') {
output.mode = file.unixfs.mode

if (file.unixfs.mtime !== undefined) {
output.mtime = file.unixfs.mtime
}
}

if (options.includeContent) {
if (file.type === 'file' || file.type === 'raw') {
// @ts-expect-error - content is readonly
output.content = file.content()
}
}

return output
}
Expand Down