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

Commit a55fa54

Browse files
committed
Merge pull request #288 from ipfs/files-add-interface
Files add interface
2 parents 689f262 + b61b3cd commit a55fa54

10 files changed

+194
-192
lines changed

package.json

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
"main": "lib/index.js",
66
"jsnext:main": "src/index.js",
77
"dependencies": {
8-
"bl": "^1.1.2",
8+
"async": "^2.0.0-rc.5",
99
"babel-runtime": "^6.6.1",
10+
"bl": "^1.1.2",
1011
"bs58": "^3.0.0",
1112
"detect-node": "^2.0.3",
1213
"flatmap": "0.0.3",
1314
"glob": "^7.0.3",
1415
"ipfs-merkle-dag": "^0.6.0",
16+
"isstream": "^0.1.2",
1517
"multiaddr": "^2.0.0",
1618
"multipart-stream": "^2.0.1",
1719
"ndjson": "^1.4.3",
@@ -30,7 +32,7 @@
3032
"aegir": "^3.2.0",
3133
"chai": "^3.5.0",
3234
"gulp": "^3.9.1",
33-
"interface-ipfs-core": "^0.1.4",
35+
"interface-ipfs-core": "^0.2.0",
3436
"ipfsd-ctl": "^0.14.0",
3537
"pre-commit": "^1.1.2",
3638
"stream-equal": "^0.1.8",
@@ -90,4 +92,4 @@
9092
"url": "https://github.com/ipfs/js-ipfs-api/issues"
9193
},
9294
"homepage": "https://github.com/ipfs/js-ipfs-api"
93-
}
95+
}

src/add-to-dagnode-transform.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict'
2+
3+
const async = require('async')
4+
const getDagNode = require('./get-dagnode')
5+
6+
// transform { Hash: '...' } objects into { path: 'string', node: DAGNode }
7+
module.exports = function (err, res, send, done) {
8+
if (err) {
9+
return done(err)
10+
}
11+
async.map(res, function map (entry, next) {
12+
getDagNode(send, entry.Hash, function (err, node) {
13+
if (err) {
14+
return next(err)
15+
}
16+
var obj = {
17+
path: entry.Name,
18+
node: node
19+
}
20+
next(null, obj)
21+
})
22+
}, function (err, res) {
23+
done(err, res)
24+
})
25+
}

src/api/add-files.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict'
2+
3+
const addToDagNodesTransform = require('../add-to-dagnode-transform')
4+
5+
module.exports = (send) => {
6+
return function add (path, opts, cb) {
7+
if (typeof (opts) === 'function' && cb === undefined) {
8+
cb = opts
9+
opts = {}
10+
}
11+
12+
if (typeof (path) !== 'string') {
13+
return cb(new Error('"path" must be a string'))
14+
}
15+
16+
var sendWithTransform = send.withTransform(addToDagNodesTransform)
17+
18+
return sendWithTransform('add', null, opts, path, cb)
19+
}
20+
}

src/api/add-url.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict'
2+
3+
const Wreck = require('wreck')
4+
const addToDagNodesTransform = require('../add-to-dagnode-transform')
5+
6+
module.exports = (send) => {
7+
return function add (url, opts, cb) {
8+
if (typeof (opts) === 'function' && cb === undefined) {
9+
cb = opts
10+
opts = {}
11+
}
12+
13+
if (typeof url !== 'string' || !url.startsWith('http')) {
14+
return cb(new Error('"url" param must be an http(s) url'))
15+
}
16+
17+
var sendWithTransform = send.withTransform(addToDagNodesTransform)
18+
19+
Wreck.request('GET', url, null, (err, res) => {
20+
if (err) return cb(err)
21+
22+
sendWithTransform('add', null, opts, res, cb)
23+
})
24+
}
25+
}

src/api/add.js

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22

3-
const Wreck = require('wreck')
3+
const isStream = require('isstream')
4+
const addToDagNodesTransform = require('../add-to-dagnode-transform')
45

56
module.exports = (send) => {
67
return function add (files, opts, cb) {
@@ -9,14 +10,16 @@ module.exports = (send) => {
910
opts = {}
1011
}
1112

12-
if (typeof files === 'string' && files.startsWith('http')) {
13-
return Wreck.request('GET', files, null, (err, res) => {
14-
if (err) return cb(err)
13+
const good = Buffer.isBuffer(files) ||
14+
isStream.isReadable(files) ||
15+
Array.isArray(files)
1516

16-
send('add', null, opts, res, cb)
17-
})
17+
if (!good) {
18+
return cb(new Error('"files" must be a buffer, readable stream, or array of objects'))
1819
}
1920

20-
return send('add', null, opts, files, cb)
21+
var sendWithTransform = send.withTransform(addToDagNodesTransform)
22+
23+
return sendWithTransform('add', null, opts, files, cb)
2124
}
2225
}

src/get-dagnode.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use strict'
2+
3+
const DAGNode = require('ipfs-merkle-dag').DAGNode
4+
const bl = require('bl')
5+
const async = require('async')
6+
7+
module.exports = function (send, hash, cb) {
8+
// Retrieve the object and its data in parallel, then produce a DAGNode
9+
// instance using this information.
10+
async.parallel([
11+
function get (done) {
12+
send('object/get', hash, null, null, done)
13+
},
14+
15+
function data (done) {
16+
// WORKAROUND: request the object's data separately, since raw bits in JSON
17+
// are interpreted as UTF-8 and corrupt the data.
18+
// See https://github.com/ipfs/go-ipfs/issues/1582 for more details.
19+
send('object/data', hash, null, null, done)
20+
}],
21+
22+
function done (err, res) {
23+
if (err) {
24+
return cb(err)
25+
}
26+
27+
var object = res[0]
28+
var stream = res[1]
29+
30+
stream.pipe(bl(function (err, data) {
31+
if (err) {
32+
return cb(err)
33+
}
34+
35+
cb(err, new DAGNode(data, object.Links))
36+
}))
37+
})
38+
}

src/load-commands.js

+19-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
'use strict'
22

33
function requireCommands () {
4-
return {
5-
add: require('./api/add'),
4+
var cmds = {
65
bitswap: require('./api/bitswap'),
76
block: require('./api/block'),
87
cat: require('./api/cat'),
@@ -11,7 +10,6 @@ function requireCommands () {
1110
dht: require('./api/dht'),
1211
diag: require('./api/diag'),
1312
id: require('./api/id'),
14-
files: require('./api/files'),
1513
log: require('./api/log'),
1614
ls: require('./api/ls'),
1715
mount: require('./api/mount'),
@@ -24,6 +22,24 @@ function requireCommands () {
2422
update: require('./api/update'),
2523
version: require('./api/version')
2624
}
25+
26+
// TODO: crowding the 'files' namespace temporarily for interface-ipfs-core
27+
// compatibility, until 'files vs mfs' naming decision is resolved.
28+
cmds.files = function (send) {
29+
const files = require('./api/files')(send)
30+
files.add = require('./api/add')(send)
31+
return files
32+
}
33+
34+
cmds.util = function (send) {
35+
const util = {
36+
addFiles: require('./api/add-files')(send),
37+
addUrl: require('./api/add-url')(send)
38+
}
39+
return util
40+
}
41+
42+
return cmds
2743
}
2844

2945
function loadCommands (send) {

src/request-api.js

+38-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ function requestAPI (config, path, args, qs, files, buffer, cb) {
110110
// -- Interface
111111

112112
exports = module.exports = function getRequestAPI (config) {
113-
return function (path, args, qs, files, buffer, cb) {
113+
var send = function (path, args, qs, files, buffer, cb) {
114114
if (typeof buffer === 'function') {
115115
cb = buffer
116116
buffer = false
@@ -127,4 +127,41 @@ exports = module.exports = function getRequestAPI (config) {
127127

128128
return requestAPI(config, path, args, qs, files, buffer, cb)
129129
}
130+
131+
// Wraps the 'send' function such that an asynchronous transform may be
132+
// applied to its result before passing it on to either its callback or
133+
// promise.
134+
send.withTransform = function (transform) {
135+
return function (path, args, qs, files, buffer, cb) {
136+
if (typeof buffer === 'function') {
137+
cb = buffer
138+
buffer = false
139+
}
140+
141+
var p = send(path, args, qs, files, buffer, wrap(cb))
142+
143+
if (p instanceof Promise) {
144+
return p.then((res) => {
145+
return new Promise(function (resolve, reject) {
146+
transform(null, res, send, function (err, res) {
147+
if (err) reject(err)
148+
else resolve(res)
149+
})
150+
})
151+
})
152+
} else {
153+
return p
154+
}
155+
156+
function wrap (done) {
157+
if (done) {
158+
return function (err, res) {
159+
transform(err, res, send, done)
160+
}
161+
}
162+
}
163+
}
164+
}
165+
166+
return send
130167
}

0 commit comments

Comments
 (0)