Skip to content
This repository was archived by the owner on Mar 10, 2020. It is now read-only.

use object tests from interface-ipfs-core #267

Merged
merged 1 commit into from
May 13, 2016
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
"jsnext:main": "src/index.js",
"dependencies": {
"babel-runtime": "^6.6.1",
"bs58": "^3.0.0",
"detect-node": "^2.0.3",
"flatmap": "0.0.3",
"glob": "^7.0.3",
"ipfs-merkle-dag": "^0.5.1",
"multiaddr": "^1.3.0",
"multipart-stream": "^2.0.1",
"ndjson": "^1.4.3",
"promisify-es6": "^1.0.1",
"qs": "^6.1.0",
"wreck": "^7.0.2"
},
Expand All @@ -23,9 +26,10 @@
"url": "https://github.com/ipfs/js-ipfs-api"
},
"devDependencies": {
"aegir": "^3.0.2",
"chai": "^3.5.0",
"aegir": "^3.0.1",
"gulp": "^3.9.1",
"interface-ipfs-core": "^0.1.3",
"ipfsd-ctl": "^0.13.0",
"pre-commit": "^1.1.2",
"raw-loader": "^0.5.1",
Expand Down Expand Up @@ -93,4 +97,4 @@
}
}
}
}
}
279 changes: 255 additions & 24 deletions src/api/object.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,264 @@
'use strict'

const argCommand = require('../cmd-helpers').argCommand
const DAGNode = require('ipfs-merkle-dag').DAGNode
const DAGLink = require('ipfs-merkle-dag').DAGLink
const promisify = require('promisify-es6')
const bs58 = require('bs58')
const bl = require('bl')

module.exports = (send) => {
return {
get: argCommand(send, 'object/get'),
put (file, encoding, cb) {
if (typeof encoding === 'function') {
return cb(null, new Error("Must specify an object encoding ('json' or 'protobuf')"))
}
return send('object/put', encoding, null, file, cb)
},
data: argCommand(send, 'object/data'),
links: argCommand(send, 'object/links'),
stat: argCommand(send, 'object/stat'),
new: argCommand(send, 'object/new'),
const api = {
get: promisify((multihash, options, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
}
if (!options) {
options = {}
}
multihash = cleanMultihash(multihash, options)

send('object/get', multihash, null, null, (err, result) => {
if (err) {
return callback(err)
}

const node = new DAGNode(result.Data, result.Links.map(
(l) => {
return new DAGLink(l.Name, l.Size, new Buffer(bs58.decode(l.Hash)))
}))

callback(null, node)
})
}),
put: promisify((obj, options, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
}
if (!options) {
options = {}
}

let tmpObj = {
Data: null,
Links: []
}

if (Buffer.isBuffer(obj)) {
if (!options.enc) {
tmpObj = { Data: obj.toString(), Links: [] }
}
} else if (obj.multihash) {
tmpObj = {
Data: obj.data.toString(),
Links: obj.links.map((l) => { return l.toJSON() })
}
} else if (typeof obj === 'object') {
tmpObj.Data = obj.Data.toString()
} else {
return callback(new Error('obj not recognized'))
}

let buf
if (Buffer.isBuffer(obj) && options.enc) {
buf = obj
} else {
buf = new Buffer(JSON.stringify(tmpObj))
}
const enc = options.enc || 'json'

send('object/put', enc, null, buf, (err, result) => {
if (err) {
return callback(err)
}

if (Buffer.isBuffer(obj)) {
if (!options.enc) {
obj = { Data: obj, Links: [] }
} else {
obj = JSON.parse(obj.toString())
}
}
let node
if (obj.multihash) {
node = obj
} else {
node = new DAGNode(obj.Data, obj.Links)
}

if (node.toJSON().Hash !== result.Hash) {
return callback(new Error('Stored object was different from constructed object'))
}

callback(null, node)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In order to support the variety of ways ipfs.object.put can be called, I had to break the elegant promise injection that was there before. @dignifiedquire wanna share some wisdom on how we can add promises again, in the most elegant way possible?

Copy link
Contributor

Choose a reason for hiding this comment

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

it's probably best to just wrap the function using sth like this: https://github.com/manuel-di-iorio/promisify-es6

})
}),
data: promisify((multihash, options, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
}
if (!options) {
options = {}
}
multihash = cleanMultihash(multihash, options)

send('object/data', multihash, null, null, (err, result) => {
if (err) {
return callback(err)
}

result.pipe(bl(callback))
})
}),
links: promisify((multihash, options, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
}
if (!options) {
options = {}
}
multihash = cleanMultihash(multihash, options)

send('object/links', multihash, null, null, (err, result) => {
if (err) {
return callback(err)
}

let links = []

if (result.Links) {
links = result.Links.map((l) => {
return new DAGLink(l.Name, l.Size, new Buffer(bs58.decode(l.Hash)))
})
}
callback(null, links)
})
}),
stat: promisify((multihash, options, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
}
if (!options) {
options = {}
}
multihash = cleanMultihash(multihash, options)

send('object/stat', multihash, null, null, callback)
}),
new: promisify((callback) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

what about layouts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried all the other layouts through the CLI and only unixfs-dir works. It seems one of those deprecated features that no one ever used to even notice. I updated the spec accordingly.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, I made it fully work in js-ipfs :/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would you like to propose that we shim that feature in, although go-ipfs not supporting? All is possible with code 🎤 :D

send('object/new', null, null, null, (err, result) => {
if (err) {
return callback(err)
}
const node = new DAGNode()

if (node.toJSON().Hash !== result.Hash) {
return callback(new Error('Stored object was different from constructed object'))
}

callback(null, node)
})
}),
patch: {
rmLink: (root, link, cb) => {
return send('object/patch/rm-link', [root, link], null, null, cb)
},
setData: (root, data, cb) => {
return send('object/patch/set-data', [root], null, data, cb)
},
appendData: (root, data, cb) => {
return send('object/patch/append-data', [root], null, data, cb)
},
addLink: (root, name, ref, cb) => {
return send('object/patch/add-link', [root, name, ref], null, null, cb)
addLink: promisify((multihash, dLink, options, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
}
if (!options) {
options = {}
}
multihash = cleanMultihash(multihash, options)

send('object/patch/add-link', [multihash, dLink.name, bs58.encode(dLink.hash).toString()], null, null, (err, result) => {
if (err) {
return callback(err)
}
api.get(result.Hash, { enc: 'base58' }, callback)
})
}),
rmLink: promisify((multihash, dLink, options, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
}
if (!options) {
options = {}
}
multihash = cleanMultihash(multihash, options)

send('object/patch/rm-link', [multihash, dLink.name], null, null, (err, result) => {
if (err) {
return callback(err)
}
api.get(result.Hash, { enc: 'base58' }, callback)
})
}),
setData: promisify((multihash, data, options, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
}
if (!options) {
options = {}
}
multihash = cleanMultihash(multihash, options)

send('object/patch/set-data', [multihash], null, data, (err, result) => {
if (err) {
return callback(err)
}
api.get(result.Hash, { enc: 'base58' }, callback)
})
}),
appendData: promisify((multihash, data, options, callback) => {
if (typeof options === 'function') {
callback = options
options = {}
}
if (!options) {
options = {}
}
multihash = cleanMultihash(multihash, options)

send('object/patch/append-data', [multihash], null, data, (err, result) => {
if (err) {
return callback(err)
}
api.get(result.Hash, { enc: 'base58' }, callback)
})
})
}
}
return api
}

function cleanMultihash (multihash, options) {
if (Buffer.isBuffer(multihash)) {
if (options.enc) {
switch (options.enc) {
Copy link
Contributor

Choose a reason for hiding this comment

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

why are you using a switch statement for a single case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

same as above

case 'base58': {
multihash = multihash.toString()
break
}
default: throw new Error('invalid multihash')
}
} else {
multihash = bs58.encode(multihash).toString()
}
} else if (typeof multihash === 'string') {
if (options.enc) {
// For the future, when we support more than one enc
// switch (options.enc) {
// case 'base58': // It is good
// }
} else {
throw new Error('not valid multihash')
}
}
return multihash
}
Loading