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

Commit 0c5e7b8

Browse files
dignifiedquiredaviddias
authored andcommitted
Working and passing
1 parent 19b4d58 commit 0c5e7b8

File tree

7 files changed

+108
-97
lines changed

7 files changed

+108
-97
lines changed

package.json

+4-8
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@
44
"description": "A client library for the IPFS API",
55
"main": "src/index.js",
66
"dependencies": {
7-
"merge-stream": "^1.0.0",
7+
"detect-node": "^2.0.3",
8+
"flatmap": "0.0.3",
9+
"glob": "^6.0.2",
810
"multiaddr": "^1.0.0",
9-
"multipart-stream": "^2.0.0",
11+
"multipart-stream": "github:dignifiedquire/multipart-stream#a1a4e9c4d41d1f78dcf32279affbbb0bfd930c28",
1012
"ndjson": "^1.4.3",
1113
"qs": "^6.0.0",
12-
"require-dir": "^0.3.0",
13-
"vinyl": "^1.1.0",
14-
"vinyl-fs-browser": "^2.1.1-1",
15-
"vinyl-multipart-stream": "^1.2.6",
1614
"wreck": "^7.0.0"
1715
},
1816
"engines": {
@@ -63,8 +61,6 @@
6361
"stream-equal": "^0.1.7",
6462
"stream-http": "^2.1.0",
6563
"uglify-js": "^2.4.24",
66-
"vinyl-buffer": "^1.0.0",
67-
"vinyl-source-stream": "^1.1.0",
6864
"webpack-stream": "^3.1.0"
6965
},
7066
"scripts": {

src/get-files-stream.js

+84-68
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,104 @@
11
'use strict'
22

3-
const File = require('vinyl')
4-
const vinylfs = require('vinyl-fs-browser')
5-
const vmps = require('vinyl-multipart-stream')
6-
const stream = require('stream')
7-
const Merge = require('merge-stream')
3+
const isNode = require('detect-node')
4+
const Multipart = require('multipart-stream')
5+
const flatmap = require('flatmap')
86

9-
exports = module.exports = getFilesStream
7+
function headers (file) {
8+
const name = file.path || ''
9+
const header = {
10+
'Content-Disposition': `file; filename="${name}"`
11+
}
1012

11-
function getFilesStream (files, opts) {
12-
if (!files) return null
13+
if (file.dir) {
14+
header['Content-Type'] = 'application/x-directory'
15+
} else {
16+
header['Content-Type'] = 'application/octet-stream'
17+
}
1318

14-
// merge all inputs into one stream
15-
const adder = new Merge()
19+
return header
20+
}
1621

17-
// single stream for pushing directly
18-
const single = new stream.PassThrough({objectMode: true})
19-
adder.add(single)
22+
function strip (name, base) {
23+
const smallBase = base
24+
.split('/')
25+
.slice(0, -1)
26+
.join('/') + '/'
27+
return name.replace(smallBase, '')
28+
}
2029

21-
for (let i = 0; i < files.length; i++) {
22-
const file = files[i]
30+
function loadPaths (opts, file) {
31+
const path = require('path')
32+
const fs = require('fs')
33+
const glob = require('glob')
2334

24-
if (typeof (file) === 'string') {
25-
const srcOpts = {
26-
buffer: false,
27-
stripBOM: false,
28-
followSymlinks: opts.followSymlinks != null ? opts.followSymlinks : true
29-
}
35+
const followSymlinks = opts.followSymlinks != null ? opts.followSymlinks : true
3036

31-
// add the file or dir itself
32-
adder.add(vinylfs.src(file, srcOpts))
37+
file = path.resolve(file)
38+
const stats = fs.statSync(file)
3339

34-
// if recursive, glob the contents
35-
if (opts.recursive) {
36-
adder.add(vinylfs.src(file + '/**/*', srcOpts))
37-
}
38-
} else {
39-
// try to create a single vinyl file, and push it.
40-
// throws if cannot use the file.
41-
single.push(vinylFile(file))
42-
}
40+
if (stats.isDirectory() && !opts.recursive) {
41+
throw new Error('Can only add directories using --recursive')
4342
}
4443

45-
single.end()
46-
return adder.pipe(vmps.flat())
47-
}
44+
if (stats.isDirectory() && opts.recursive) {
45+
const mg = new glob.sync.GlobSync(`${file}/**/*`, {
46+
follow: followSymlinks
47+
})
4848

49-
// vinylFile tries to cast a file object to a vinyl file.
50-
// it's agressive. If it _cannot_ be converted to a file,
51-
// it returns null.
52-
function vinylFile (file) {
53-
if (file instanceof File) {
54-
return file // it's a vinyl file.
49+
return mg.found.map(name => {
50+
if (mg.cache[name] === 'FILE') {
51+
return {
52+
path: strip(name, file),
53+
dir: false,
54+
content: fs.createReadStream(name)
55+
}
56+
} else {
57+
return {
58+
path: strip(name, file),
59+
dir: true
60+
}
61+
}
62+
})
5563
}
5664

57-
// let's try to make a vinyl file?
58-
const f = {cwd: '/', base: '/', path: ''}
59-
if (file.contents && file.path) {
60-
// set the cwd + base, if there.
61-
f.path = file.path
62-
f.cwd = file.cwd || f.cwd
63-
f.base = file.base || f.base
64-
f.contents = file.contents
65-
} else {
66-
// ok maybe we just have contents?
67-
f.contents = file
65+
return {
66+
path: file,
67+
content: fs.createReadStream(file)
6868
}
69-
70-
// ensure the contents are safe to pass.
71-
// throws if vinyl cannot use the contents
72-
f.contents = vinylContentsSafe(f.contents)
73-
return new File(f)
7469
}
7570

76-
function vinylContentsSafe (c) {
77-
if (Buffer.isBuffer(c)) return c
78-
if (typeof (c) === 'string') return c
79-
if (c instanceof stream.Stream) return c
80-
if (typeof (c.pipe) === 'function') {
81-
// hey, looks like a stream. but vinyl won't detect it.
82-
// pipe it to a PassThrough, and use that
83-
const s = new stream.PassThrough()
84-
return c.pipe(s)
85-
}
71+
function getFilesStream (files, opts) {
72+
if (!files) return null
73+
74+
const mp = new Multipart()
75+
76+
flatmap(files, file => {
77+
if (typeof file === 'string') {
78+
if (!isNode) {
79+
throw new Error('Can not add paths in node')
80+
}
81+
82+
return loadPaths(opts, file)
83+
}
84+
85+
if (file.path && (file.content || file.dir)) {
86+
return file
87+
}
8688

87-
throw new Error('vinyl will not accept: ' + c)
89+
return {
90+
path: '',
91+
dir: false,
92+
content: file
93+
}
94+
}).forEach(file => {
95+
mp.addPart({
96+
headers: headers(file),
97+
body: file.content
98+
})
99+
})
100+
101+
return mp
88102
}
103+
104+
exports = module.exports = getFilesStream

src/load-commands.js

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

3-
const isNode = !global.window
4-
53
function requireCommands () {
6-
if (isNode) return require('require-dir')('./api')
7-
84
return {
95
add: require('./api/add'),
106
block: require('./api/block'),
@@ -14,6 +10,7 @@ function requireCommands () {
1410
dht: require('./api/dht'),
1511
diag: require('./api/diag'),
1612
id: require('./api/id'),
13+
files: require('./api/files'),
1714
log: require('./api/log'),
1815
ls: require('./api/ls'),
1916
mount: require('./api/mount'),

src/request-api.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const Qs = require('qs')
55
const ndjson = require('ndjson')
66
const getFilesStream = require('./get-files-stream')
77

8-
const isNode = !global.window
8+
const isNode = require('detect-node')
99

1010
// -- Internal
1111

test/api/add.spec.js

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

3-
const path = require('path')
4-
const File = require('vinyl')
53
const Readable = require('stream').Readable
64

7-
const isNode = !global.window
5+
const isNode = require('detect-node')
86

97
const testfilePath = __dirname + '/../testfile.txt'
108
let testfile
@@ -26,19 +24,17 @@ describe('.add', () => {
2624
return done()
2725
}
2826

29-
const file = new File({
30-
cwd: path.dirname(testfilePath),
31-
base: path.dirname(testfilePath),
32-
path: testfilePath,
33-
contents: new Buffer(testfile)
34-
})
27+
const file = {
28+
path: 'testfile.txt',
29+
content: new Buffer(testfile)
30+
}
3531

36-
apiClients['a'].add(file, (err, res) => {
32+
apiClients['a'].add([file], (err, res) => {
3733
expect(err).to.not.exist
3834

3935
const added = res[0] != null ? res[0] : res
4036
expect(added).to.have.property('Hash', 'Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
41-
expect(added).to.have.property('Name', path.basename(testfilePath))
37+
expect(added).to.have.property('Name', 'testfile.txt')
4238
done()
4339
})
4440
})
@@ -47,6 +43,7 @@ describe('.add', () => {
4743
let buf = new Buffer(testfile)
4844
apiClients['a'].add(buf, (err, res) => {
4945
expect(err).to.not.exist
46+
5047
expect(res).to.have.length(1)
5148
expect(res[0]).to.have.property('Hash', 'Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
5249
done()
@@ -60,6 +57,7 @@ describe('.add', () => {
6057

6158
apiClients['a'].add(testfileBig, (err, res) => {
6259
expect(err).to.not.exist
60+
6361
expect(res).to.have.length(1)
6462
expect(res[0]).to.have.a.property('Hash', 'Qme79tX2bViL26vNjPsF3DP1R9rMKMvnPYJiKTTKPrXJjq')
6563
done()
@@ -84,10 +82,9 @@ describe('.add', () => {
8482
apiClients['a'].add(__dirname + '/../test-folder', { recursive: true }, (err, res) => {
8583
if (isNode) {
8684
expect(err).to.not.exist
87-
console.log('Jeromy ->', res)
8885

8986
const added = res[res.length - 1]
90-
expect(added).to.have.property('Hash', 'QmSzLpCVbWnEm3XoTWnv6DT6Ju5BsVoLhzvxKXZeQ2cmdg')
87+
expect(added).to.have.property('Hash', 'QmTDH2RXGn8XyDAo9YyfbZAUXwL1FCr44YJCN9HBZmL9Gj')
9188
done()
9289
} else {
9390
expect(err.message).to.be.equal('Recursive uploads are not supported in the browser')
@@ -100,6 +97,7 @@ describe('.add', () => {
10097
const stream = new Readable()
10198
stream.push('Hello world')
10299
stream.push(null)
100+
103101
apiClients['a'].add(stream, (err, res) => {
104102
expect(err).to.not.exist
105103

test/api/files.spec.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,18 @@ describe('.files', function () {
6969
it('files.read', function (done) {
7070
this.timeout(20000)
7171

72+
if (!isNode) {
73+
return done()
74+
}
75+
7276
apiClients['a'].files.read('/test-folder/test-file', function (err, stream) {
7377
expect(err).to.not.exist
7478
let buf = ''
7579
stream
76-
.on('error', function (err) {
80+
.on('error', function (err) {
7781
expect(err).to.not.exist
7882
})
79-
.on('data', function (data) {
83+
.on('data', function (data) {
8084
buf += data
8185
})
8286
.on('end', function () {

test/setup.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const apiAddrs = require('./tmp-disposable-nodes-addrs.json')
55

66
global.expect = require('chai').expect
77
global.apiClients = {} // a, b, c
8-
global.isNode = !global.window
8+
global.isNode = require('detect-node')
99

1010
function connectNodes (done) {
1111
const addrs = {}

0 commit comments

Comments
 (0)